容器是相对独立的环境,相当于一个小型的 Linux 系统,外界无法直接访问,那他是怎么做的呢,这里我们先了解下 Linux veth pair
veth虚拟网络设备的特点就是它会成对出现,pair英文就是成对的意思,也就是说你创建veth的时候,他会创建一个对veth设备,veth设备一段连着linux网络协议栈,另一端连接的另外的veth设备,成对的veth发送数据后会直接到另一个veth设备上去。
veth pair将两个网络eth0和eth1连通
三个网络
1. lo 127.0.0.1 #本地回环地址
2. eth0 172.21.221.194 # 阿里云的私有IP
3. docker0 172.17.0.1 # docker网桥
lo和eth0在我们创建虚拟机的时候就会创建,但是docker0在我们安装了docker的时候就会创建,docker0用来和虚拟机之间通信
2.2启动一个容器,查看网络
[root@docker ~]# docker run -d -p 8080:8080 --name tomcat01 tomcat
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba0a3198a482 tomcat "catalina.sh run" 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp tomcat01
发现启动容器之后,多了一组网卡,而且是成对的。
# 进入容器,查看容器内的ip
[root@docker ~]# docker exec -it tomcat01 /bin/bash
root@ba0a3198a482:/usr/local/tomcat# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 ba0a3198a482 # 容器内的ip地址
结论:我们每启动一个容器,就会多出一对网卡,同时他们被连接到docker0上,而docker0又和虚拟机之间连通
# 通过network ls查看列表
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b8a696ab513c bridge bridge local # docker0
e789f4efb1cd host host local
014233f751ef none null local
通过inspect查看网络情况
把docker0当作一个路由器的功能,任何一个容器启动都是docker0网络
docker默认会给容器分配一个可用ip,并把它同docker项链,使用的就是veth-pair技术
网络模式 | 配置 | 说明 |
---|---|---|
bridge模式 | –net=bridge | 默认值,在docker0上为容器创建新的网络栈 |
host模式 | –net=host | 容器和宿主机共享network namespace |
none模式 | –net=none | 不配置网络,用户进入容器,自行配置 |
container模式 | –net=container:name/id | 容器和另一个容器共享network namespace |
用户自定义 | –net=自定义模式 | 用户自己使用network相关命令定义网络,创建容器的时候可以指定自己定义的网络 |
原理:docker服务默认创建一个docker0网桥,该桥接的网络名称为docker0,它在内核层联通了其他的物理或虚拟网卡,这就将所容器和本地主机都放在了一个物理网络,docker默认指定了docker0
原理:直接使用宿主机得到的ip和端口于外界进行通信,不再需要额外进行nat转换。
容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的ip和端口
通过配置文件我们也可以看出,容器内没有进行网络配置
运行并验证
注意:由于容器使用宿主机的ip和端口,在使用-p映射端口时,会报错
docker启动时指定–network=host或-net=host,如果还指定了-p映射端口,那这个时候就会有此警告,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。
查看容器的网络配置
docker inspect tomcat01
原理:在none模式下,没有对docker容器进行任何网络配置。等于这个docker容器没有网卡,ip,路由信息,只有一个lo,这个时候需要我们自己为docker容器添加网卡,配置ip等。
查看none模式的网络配置信息
运行并验证
没有ip等信息
原理:新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,培植自己的ip,而是和一个指定的容器共享ip,端口范围等。同样,两个容器除了网络方面,其他的如文件系统,进程列表等还是隔离的。
在新建一个容器centos02,网络模式采用container模式,查看网络信息
两个容器网络信息一样,如果centos01关机后,centos02网络是否发生变化?
网络只剩下一个回环地址
# 创建两个容器
[root@docker ~]#docker run -it --name centos02 --network=container:centos01 centos # ctrl+Q+P 不停止退出容器
[root@docker ~]#docker run -it --name centos02 --network=container:centos01 centos # ctrl+Q+P 不停止退出容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
590ef03a6ece centos "/bin/bash" 11 seconds ago Up 10 seconds centos02
7a681b1b7a87 centos "/bin/bash" 41 seconds ago Up 41 seconds centos01
docker network create --help
[root@docker ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
7c45f7a7563bb8f14ac11e4f7563b88913135d7f5b14aebfe051f8b170ec3ec6
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b8a696ab513c bridge bridge local
e789f4efb1cd host host local
7c45f7a7563b mynet bridge local
014233f751ef none null local
创建容器centos03和centos04放在同一个网络下mynet
ping服务名和ip进行测试
已知centos01,centos02在一个网段,centos03,centos04在一个网段,他们能互相ping通?
不同网段无法互通
不同Docker网络之间的容器想要连接的话,需要把该容器注册到另一个容器所在的网络上,使用docker connect命令
docker network connect mynet centos01