前言
本讲是从Docker系列讲解课程,单独抽离出来的一个小节,重点介绍容器网络模式, 属于了解范畴,充分了容器的网络模式,更有助于更好的理解Docker的容器之间的访问逻辑。
疑问:为什么要了解容器的网络模式?
首先,容器之间虽然不是物理隔离,但是它们彼此之间默认是不互联互通的,这也有助于保持每个容器的纯粹性,相互之间互不影响。
其次,既然使用了容器,通常情况下,容器需要与宿主机通信,或者A容器与B容器通信而B不需要知道A的存在,或者A/B两容器相互通信。
从而,就引出了本节内容,他们相互通信,就绕不开容器的网络模式!
概述
1.容器通信模式分类
模式名称 | 简介 | 备注 |
---|---|---|
bridge |
容器拥有独属于自己的虚拟网卡和和虚拟IP等网络资源,它们分别通过docker0虚拟网卡与宿主机的eth0网卡交互,进而和外界网络交互 | 默认模式 |
host | 容器没有自己的任何独立的网络资源(比如:容器的IP、网卡和端口),完全和宿主机共享网络空间 | 弊端:同一个端口只能同时被一个容器服务绑定 |
none | 该模式关闭了容器的网络功能,仅有独自的网络空间(一个空架子),并且该模式不会给容器分配任何网络资源,包括虚拟网卡、路由、防火墙、IP、网关、端口等 | 光秃秃的一个容器,没有任何的网络资源,就是自娱自乐的光杆司令(很少用) |
container | 它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源,除了网络资源,其他资源,容器彼此之间依然是相互隔离的 | 第一个以bridge方式启动的容器服务挂掉,后面依赖它的容器,都暂停服务 |
自定义 | 该模式也更为灵活,可以通过-d 指定自定义的网络模式的类型,可以是bridge或者overlay,其中overlay功能更为强大,可以指定多个subnet子网网段。 | 该模式,在容器之间可以使用别名相互通信,这一点很nice(重要) |
docker0虚拟网卡科普:
当docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,宿主机上以Bridge模式启动的容器会链接到这个虚拟网桥上。docker0默认地址172.17.0.0/16。虚拟网桥的工作方式和物理交换机类似,这样宿主机上的所有容器就通过docker0连在一个二层网络中,再通过docker0和物理网卡eth0交互(我本机的物理网卡名字是ens33)。
Docker 安装以后,会默认创建三种网络,可以通过 docker network ls 查看。
[root@centOS7 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
fad4a56fe429 bridge bridge local
2ec1ca3d2105 host host local
17d14a812fce none null local
预告:剩余的两种需要手动定义后,再通过docker network ls命令查看才会展现出来!
2.网络模式的使用方式
docker run 后面添加 --net参数即可。
示例:--net=bridge、 --net=host 、--net=container、--net=none
3.ip a 默认的网卡资源信息
查看目的:对以下两个网卡混个脸熟。
ens33是宿主机的物理网卡,大部分电脑是eth0。
docker0,它是docker的虚拟网卡,桥接模式下,内部容器都会把信息汇总给docker0网卡,由它再转发给eth0,来和外界交互。
ip addr #或者ip a 都可以查看所有的网络资源
下面一起深入探讨一下各模式的使用方式吧!
一、bridge桥接网络模式
docker run默认模式,最为常用。所以 --stat=bridge 可以省略不写。
特点:
1.默认为每个容器分配单独的网络空间,彼此相互隔离。
2.每个容器都单独的网卡、路由、IP等一些列基本的网络设施。
3.每个容器启动后,都会被分配一个独立的虚拟IP。
4.该模式会自动,将宿主机上的所有容器,都链接到 #ip a 看到的docker0的虚拟网卡上。
5.外界主机不能直接访问宿主机内的容器服务,需要宿主机通过-p做端口映射后访问宿主的映射端口。
1.准备工作,启动nginx前查看宿主机桥接模式网关、80端口占用情况
1)docker inspect bridge 总览桥接模式下的网关和子网网段
docker inspect bridge #查看桥接网络模式docker0虚拟网卡的详细信息(子网网段、网关等)
注意:下图中查看的网关信息,是bridge模式下的网关信息,可以看到桥接模式的网关和IP,docker0是桥接模式下,所有容器交互通信的交通枢纽。
稍后会查看host模式下的网关信息,里面都是空的。
2)开启nginx前,先查看宿主机80端口占用情况
查看目的,可以得知,在桥接模式下,容器自始至终使用的都是容器自身的虚拟网卡和虚拟IP,并不会占用宿主机的(80)端口和IP。
桥接模式实验结束后,会再次查看宿主机的80端口有没被占用(实际情况下,不会被占用的)
docker ps -a #实验前,查看是否有启动的容器,如果有暂时先停掉,特别是nginx容器
netstat -nalpt #实验前,先查看宿主机的(80)端口占用情况
2.通过启动nginx容器服务,深入了解bridge模式
1)以桥接模式启动nginx容器
docker images #查看镜像列表
docker run -d --name nginx_V1 nginx:alpine #默认就是桥接,不用--net单独指定bridge
docker ps #查看已启动的容器
2)查看桥接模式下,nginx容器的网络资源分配情况
ip a ,目的:可以看到系统给nginx容器服务单独分配了一个虚拟网卡veth****
注意:在桥接模式下,每个容器启动后,都会被分配一个独属于容器自己的虚拟网卡和虚拟IP。
ip a #发现多了一个虚拟网卡:vetha7cac49@if44
下面再通过:docker inspect nginx_v1 命令,查看桥接模式下,容器的网络配置详细信息
docker ps
docker inspect nginx_v1 #通过nginx容器别名查看容器的详细信息,可以看到容器的网关和IP 172.17.0.2
可以看到独立的IP、Port、GateWay、Mac等资源。
3)宿主机下,curl nginx容器IP,可以正常访问
curl 172.17.0.2 #桥接模式下,系统自动为nginx容器分配的虚拟IP
4)开启新窗口,进入同一宿主机的其他Tomcat容器内部curl nginx容器IP
可以发现,宿主机内的其他容器,依然可以访问nginx容器服务
docker run -it -p 8080:8080 tomcat:8.5.46-jdk8-openjdk /bin/bash # 进入其他容器内部
curl 172.17.0.2 #在Tomcat容器中,访问nginx容器
注:此时,先不退出tomcat容器时,在新窗口用ip a命令,可以看到两块虚拟网卡(分别对应nginx容器和tomcat容器的)。
ip a #暂不退出tomcat容器,开启新窗口运行此命令,可以看到两块虚拟网卡(分别是nginx和tomcat的)
5)再次在宿主机通过netstat -nalpt 查看宿主机的80端口是否开启
发现,宿主机的80端口,并没有被占用,为什么在宿主机还能通过curl 172.17.0.2访问nginx容器呢?实际情况该curl命令此时访问的是容器内部的80端口。桥接模式下,宿主机和容器之间、同一宿主机下容器和容器之间的网络是互联互通的。非宿主机的其他主机,即使和宿主机是同一网段的局域网,也不能直接访问宿主内的容器!
6)进入nginx容器内部,查看端口占用情况
docker ps #查看正在运行的容器列表
docker exec -it 3cae7605916d /bin/sh #进入nginx容器内部(注:这里使用/bin/bash会报错)
注意:此处,你可能会对上面命令尾部的/bin/sh有疑问,为什么不是/bin/bash,或者我为什么用/bin/bash无法进入容器内部?如果你有这样的疑问,点击这里。
7)Vmware其他虚拟主机curl nginx虚拟IP,是访问不通的
curl 172.17.0.2 #打开其他虚拟主机,访问虚拟主机nginx容器服务,发现不能访问
该结论在上面已经提及过,桥接模式下,非宿主机的其他主机,即使和宿主机是同一网段的局域网也无法直接访问容器内部, 但并不意味着没有办法间接访问。这里简单科普一下,同一网段的其他非宿主机,可以访问宿主机docker run -p 8000:8080,前面的映射端口,比如8000。
3.Bridge网络模式示意图
通过示意图,可以清晰的看到,docker容器在桥接模式下,会为每个容器分配单独的虚拟网卡、虚拟IP。然后再统一通过docker0虚拟网卡,统一和宿主机的eth0交互(本例中,我的宿主网卡是ens33)。
注:虚拟网卡、虚拟IP,在容器启动后,分别通过ip a 命令和 docker inspect 容器id,可以查看。
4.Bridge小结
- docker run 命令不带--net参数时,默认就是桥接模式。
- 桥接模式下,同一个宿主机内的容器,彼此的网络是互通的。
- 桥接模式下容器的虚拟IP,容器内部彼此之间可以访问,非宿主机的其他其他主机无法直接访问容器内部的服务。
- 注意:桥接模式下,虽然外界主机不能直接访问宿主机容器内部的服务,但是可以通过间接方式访问宿主机docker run -p时,对外暴露的映射端口。
比如:docker run -p 8000:8080,其他主机可访问宿主机IP:8000端口,而不能直接访问宿主机内容器的8080端口。
二、host网络模式(用的比较少)
docker run --net host 或者 --network host 来手动指定
特点:
1.host模式,它没有独立的网络空间。
2.host模式下的容器,完全和宿主机共用一个网络空间(端口、IP等),所以该模式下的容器不会虚拟出容器自身的虚拟网卡,也不会配置自己的虚拟IP。
3.host模式下的容器,除了网络和宿主机共享,其他的资源,如文件系统、进程列表等,容器之间依然是相互隔离的。
弊端
同一个端口,比如宿主机的80端口,只能被一个服务占用,如果被某个容器占用了,宿主机就不能用,后续的容器也不能用,直到优先抢到80端口的服务,停止提供服务(放弃80端口)。
1.准备工作,停掉无关服务
1)停掉并删除无关的容器
docker stop命令停掉所有正在运行的服务,docker rm 删除掉上一实验中的nginx容器,避免干扰本实验。
docker ps #查看所有正在运行的容器
docker stop 15 #停掉容器首字母是15的容器
docker rm 15 #删除nginx容器
2)查看宿主机端口占用情况
先用命令ss -lntup 或者 netstat -nalpt验证一下,是否有未知程序占用80,有的话kill it,依次确保下面实验的准确性(nginx占用的是80端口,稍后启动的nginx容器会霸占宿主机的80端口)。
注:进行下面实验前,确保80端口没有被任何程序占用!
3)ip -a 没有启动任何容器情况下,查看宿主机的网卡列表信息
查看目的:实验开始前,提供一个纯粹的实验环境(清除掉所有无关容器),然后在纯粹的环境下,通过ip a 查看网卡列表信息,以便验证稍后以Host模式启动nginx容器后,是否会产生新的虚拟网卡。
预告一下:实际情况Host模式下,各容器不产生新的虚拟网卡!
docker ps #查看容器列表,确保所有的容器都已被清除,确保本次实验的纯粹性(不受干扰)
ip a #查看宿主机的网卡列表信息,可以看到只有宿主机的ens33和docker0
2. 先后启动两个nginx服务
预告:第一个nginx容器被启动后,会霸占宿主机的80端口。
因为宿主机只有1个80端口,那么第二个nginx自然是因为没有80端口可用,而启动失败了。
1) docker run 以Host模式,启动第一个nginx容器 nginxV1
docker run -d --net=host --name nginxV1 nginx:alpine #以host模式启动nginxV1
netstat -nalpt #查看宿主机的端口占用情况(主要看80端口)
2)ip a 命令,查看host模式下并有没开启新的虚拟网卡(如果有,则以veth开头)
ip a #查看host网络模式下,容器是否会开启新的虚拟网卡
可以发现,Host模式下的容器启动后,不会创建新的网卡(桥接模式下的容器,会自动创建以veth开头的虚拟网卡)
3)docker inspect 查看Host模式下的网络详细信息
docker ps # 查看正在运行的容器
docker inspect d4 #根据容器id的首字母,查看容器详细信息
可以发现,Host模式开启的容器,容器自身是没有任何网络资源信息的,都是空的,它用的一切网络资源都是宿主机的,那么下面继续通过宿主机访问一下nginxV1吧。
4)curl 访问一下宿主机的80端口,看是否可以访问到内部容器nginx
ifconfig #查看宿主机(本机)IP
curl 192.168.31.220 #直接访问宿主机的IP,注:80默认可以不写
惊不惊喜,意不意外?
尽管host模式下的nginx容器没有任何网络资源,但是以该模式启动的容器,依然可以直接通过宿主机的IP(+端口,不同的服务,端口也不同)直接访问。
为什么呢?上面已经提及,Host模式运行的容器,用的一切网络资源,是霸占的宿主机的网络资源。
反思:既然宿主机的80端口被nginxV1霸占了,那么再开启nginxV2,是否可以启动呢?
预告:不能启动,宿主机的80端口就1个,已经被V1霸占了。
5)再次以host模式,在宿主机启动nginxV2
docker ps #查看正在运行的容器
docker run -d --net=host --name nginxV2 nginx:alpine #再次以host模式,开启nginxV2
docker ps -a #查看nginxV2是否启动成功(发现,没有启动成功)
发现,nginxV2状态是Exited,并没有真正启动(至此,如果你对容器状态感兴趣,点击这里)
6)docker logs命令,查看nginxV2的启动日志信息
docker ps -a #查看所有状态的容器(因为nginxV2没有成功启动,所以用-a参数,才可以看到)
docker logs ba #使用nginxV2容器ID首字母,查看日志信息
发现,nginxV2失败的原因是因为80端口已经被占用,至此就验证了,上面讲到的,Host网络模式下宿主机中容器的网络资源是霸占的宿主机的,特别是端口,先占先得,后来的望之兴叹,除非先得到的容器放弃了该端口的占用。
7)开启其他主机,在其他虚拟中curl host模式下的nginx
发现,其他同一网段的虚拟主机可以直接访问宿主机内部的容器。这一点很神奇,然而bridge模式下,同一网段的主机,是不能直接访问宿主机内部容器的。
之所以Host模式下,同一网段的主机可以直接访问宿主机内部容器,是因为容器霸占的是宿主机的资源。访问容器,相当于访问的就是宿主机,给人的感觉就是:“宿主机就是容器,容器就是宿主机”。然而除了网络资源,容器霸占的是宿主机的,容器之间的其他资源依然是相互隔离的,如文件系统、进程列表等。
3.Host模式示意图
4.Host模式小节
Host模式的优点和缺点,都十分明显,容器内的服务只要部署成功,可以被同一网段内的局域网的其他任一主机访问,给人的错觉就是“宿主机就是容器,容器就是宿主机”。缺点就是,一个端口只能被一个服务占用,且容器的网络也缺少隔离性,故该使用场景十分有限。
因为该模式,不是默认的网络模式,所以在docker run的时候,要添加参数--net=host 或者 --network=host 来手动指定。
三、container网络模式
该模式≈bridge+host的混合模式,指定一个容器以bridge方式启动,后面容器启动时指定网络模式为container,它们自动共享第一个容器的网络资源。
特点
1.新创建的容器,仅同前面已存在的容器,共享网络空间,不与宿主机共享网络。
2.新创建的容器,不会有自己的虚拟网卡和IP,后面新创建容器的网络资源用的是上一个容器的。
3.新创建的容器,仅仅是网络和第一个容器共享,其他资源彼此还都是相互隔离的。
弊端
第一个指定容器服务一旦停掉,后续的容器也没有办法继续运行
有了上两种模式做铺垫,本模式采用倒序方式进行。
1.container网络模式图解
2.清除所有容器,确保docker ps -a,看不到任何容器
1) 为了让实验免受干扰,分别通过,docker ps 、docker stop 、docker rm三个命令清掉所有容器
2) ip a 查看网卡信息列表,目的是为了和后面启动容器后网卡信息列表,作对比
此时,只有物理网卡ens33(你的电脑可能是eth0)和docker0虚拟网卡,别无其他网卡。
docker ps -a #清除所有容器,保证列表为空
ip a #查看网卡列表
3.container模式模拟
1)第一个nginx容器,以bridge网络模式启动,然后ip a 查看网卡信息
目的,便于对比,第二个容器以container网络模式启动后,网卡的变化。
预告,其实并没有变化,后面启动的容器,都会使用第一个指定的以桥接方式启动的容器。
docker images #查看镜像列表
docker run -d --name nginx_Num1 nginx:alpine #以bridge桥接模式启动第一个nginx
docker ps #查看已启动的容器
ip a #查看网卡列表
2)第二个tomcat容器,以container网络模式启动,然后再ip a 查看网卡信息
docker images #查看镜像列表,便于根据名称启动
docker ps -a #查看容器列表(主要是查看刚才的nginx_启动了没有)
docker run -d --name tomcat_Second --net=container:nginx_Num1 tomcat:8.5.46-jdk8-openjdk #以container模式启动第二个容器,注意,该模式不能只用-p
注意:container模式,docker run的时候,不能使用-p,因为-p是手动指定端口,而container模式的ip和端口是不受container模式的容器自身控制,它的IP和端口,相当于完全委托给第一个以桥接方式启动的容器了。
如果你不小心带了-p 8080:8080这个参数,你将看到这个错误:docker: Error response from daemon: conflicting options: port publishing and the container type network mode.
另外:--net=container后面直接跟冒号,冒号后面是它所依靠的以桥接方式启动的指定容器,即为:--net=container:nginx_Num1 ,其中nginx_Num1是上一步以bridge方式启动的第一个指定的容器。
ip a #再次查看网卡列表信息
3)docker inspect 分别查看两个容器的网络IP信息
docker ps #查看已启动容器列表(主要查看容器的ID)
docker inspect 43baa353505c #查看以桥接方式启动的第一个容器的网络信息,可以看到网络信息是全套的,ip 端口 网关,都有
发现,第一个以桥接方式启动的容器的网络信息是全套的,ip 端口 网关,都有。
docker ps b24dc87ccd1e #查的第二个以container模式启动容器的网络信息,发现毛都没有,都是空的
发现,第二个以container模式启动容器的网络信息,发现毛都没有,都是空的
4)在宿主机curl nginx容器的IP,尝试访问一下
curl 172.17.0.2 #这个地址就是第一个以bridger方式启动的nginx的Ip,它的默认端口是80
发现,是可以访问的
5)在非宿主机的其他局域网主机访问虚拟内部容器
发现,是无法访问的,这一点和桥接模式有点儿类似。
四、none网络模式(极少被使用)
特点:
光秃秃的一个容器,没有任何的网络资源,不能和容器和宿主机之间进行正常的访问互动。
1.none网络模式示意图
2.模拟--net=none
1)清除前面实验留下的容器
docker ps -a #列出所有容器列表
docker rm -f $(docker ps -qa) #强制移除所有容器
docker ps -a
2)以--net=none模式启动容器,并通过ip a 查看宿主机网卡列表
docker images
docker run -d --net=none nginx:alpine #以none的网络模式启动nginx
ip a #看到宿主机的网卡列表没有任何变化,仅ens33物理网卡和docker0虚拟网卡,两个网卡
3)docker ps 查看容器的端口启用情况
发现,容器虽然启动了,但是并没有被分配任何端口
4)docker inspect 查看none网络模式下,容器的网络信息
docker inspect d072b359e5cd #根据容器id,查看容器的网络信息
3.None网络模式小结
经过上述实验,该模式下的容器各个都是光杆司令,虽然可以启动,但是启动后,几乎什么服务都提供不了,因为它不会被宿主机分配任何网络资源。更没有IP和虚拟网卡,所以只能自娱自乐。
五、自定义网络模式
注:自定义网络模式,本身也是一个较大的知识点,本讲主要是站在容器五种网络类型层面解析一下,学习该模式前,先了解docker network几个常用的命令(如下命令,先混个脸熟)。
docker network ls | 查看已存在的网络模式列表 |
---|---|
docker network create -d [mode_type] **_name | 创建新的自定义网络 |
docker network rm [id | name] | 移除自定义网络模式 |
docker network connect [id | name] | 连接到特定网络 |
docker network disconnect net_name contain_id/name | 给指定容器,取消某个网络模式 |
docker network [birdge | none | host | 自定义] | 查看网络模式的详细网络信息 |
容器命令
docer exec -it container_[id | name] | 进入容器内部 |
docker inspect container_ [id | name] | 查看指定容器网络模式详细信息 |
1.创建bridge网络
docker network ls
docker network create -d bridge b-net #创建自定义网络
docker network create -d bridge c-net
docker network ls
docker network rm c-net #实验完毕移除自定义网络
docker network rm b-net
需要说明的是,docker network create 自定义网络时,不指定网络模式,默认就是bridge桥接模式
docker network create mybridgework #不用-d指定网络模式,默认就是bridge
docker network ls
docker network inspect mybridgework #查看自定义网络详细信息
docker network rm mybridgework #实验完毕移除自定义网络
2.创建一个overlay网络
docker network create -d overlay myOverLay #需要用-d 指定overlay
使用--subnet选项创建子网而言,bridge网络只能指定一个子网,而overlay网络支持多个子网。
在bridge和overlay网络驱动下创建的网络可以指定不同的参数。
注:通过命令docker inspect 命令,查找"Driver": "overlay2",可以看到驱动模式是overlay2。
下面继续探讨和自定义网络模式的使用(其实和上面差不多 --net=mynet就可以了)
3.自定义网络模式实战
预告:下面一起深入了解自定义网络模式,从创建到组合使用,以及---subnet的使用。
1)创建桥接模式的自定义网络,名字就叫mynet(网络模式为bridge)
docker network create -d bridge --subnet 172.25.0.0/16 mynet #自定义名字为mynet的网络,subnet指定子网网段(不能与其他网卡的网段重叠)
提示:这里有个细节需要注意一下,因为docker0网卡,已经把网段172.17.0.0/16占用了(用docker inspect bridge可以得知,上面自定义的mybridgework占用的是172.20.0.0/16 子网网段),本例的mynet就指定为172.25.0.0/16,各网卡之间的子网网段不能有重叠!
2)创建三个容器(分别指定不同的网络模式)
docker run -itd --name=container1 nginx:alpine #使用默认的docker0网卡
docker run -itd --name=container2 nginx:alpine #使用默认的docker0网卡;注:稍后下面会单独给container2添加自定义网络mynet,使其拥有两个网络模式
docker run -itd --name=container3 --net=mynet --ip=172.25.3.3 nginx:alpine #只使用自定义网络
注:以上三个容器都已经启动,默认都是使用docker0网卡,且都是桥接模式,
下面再额外给container2添加自定义的mynet网络模式
docker network connect mynet container2 #指定container2的网络模式为mynet
3) 查看这三个容器的网络情况
# 查看这三个容器的网络情况
docker inspect container1 # docker0
docker inspect container2 # docker0, mynet
docker inspect container3 # mynet
下面是contain1的网卡信息,可以看到网络模式就是默认的bridge,网卡使用的是docker0
下面是contain2的网卡信息,可以看到有两个网卡:IP分别是172.17.0.3、172.25.0.2
下面是contain3的网卡信息,它只有一个mynet网卡,可以看到IP是,172.25.3.3 (该IP的上面docker run 该容器时指定的)
4)ip a查看网卡信息
可以看到,在通过docker network create 命令创建新的网络模式,并指定--subnet子网网段时,会自动创建新的虚拟网卡。
4.默认网络与自定义bridge的区别
1)网络方面的差异
默认网络docker0:网络中所有主机间只能用IP相互访问。
自定义网络(bridge):网络中所有主机除ip访问外,还可以直接用容器名(container-name)作为hostname相互访问。
docker ps #查看已启动容器的列表
docker exec -it container2 /bin/sh #进入contain2容器内部,注,因为nginx镜像是alpine版本,默认不支持/bin/bash
ping w -3 172.17.0.2 #尝试在contain2内部ping通contain1的IP(可以ping通)
ping w -3 container1 #不可以ping通
ping w -3 container3 #可以ping通
为什么是下面的结果?
因为container1在docker run 启动时,什么就没有做,就是使用默认的bridge模式;
container2在docker run 启动后在默认bridge模式基础上,又单独多指定了自定义的mynet网络模式(此时它同时拥有2个网络模式);
container3在docker run 启动时,仅指令了网络模式为mynet自定义网络模式。
说明:bridge网络模式之间的容器,只能通过IP相互访问;自定义网络模式可以通过容器别名相互访问。
提示:首先通过decker exec 命令进入container2容器(它同时拥有默认的bridge网络模式+自定义网络模式),因为container1没有使用自定义网络模式,所以在container2中ping container1的别名ping不通,但是ping container1的ip可以ping通。
反之,此时的contain2和contain3都使用了自定义网络模式(名称为mynet),所以他们之间可以使用别名通信。
2)在容器连接的差别(非重点,了解范畴)
- 默认网络:--link是静态的,不允许链接容器重启,并且被链接容器必须提前创建好;
- 自定义网络:--link是动态的,支持链接容器重启(以及IP变化),且该模式下被链接的容器不必预先建好。
使用docker network connetct将容器连接到新网络中时,用参数--link链接相同的容器时,可以指定不同的别名,它们是针对不同网络的。
# 运行容器使用自定义网络,同时使用--link链接尚不存在的container5容器
docker run --net=mynet -itd --name=container4 --link container5:c5 nginx:alpine
# 创建容器container5
docker run --net=mynet -itd --name=container5 --link container4:c4 nginx:alpine
# 不同的网络环境连接中,使用不同的alias链接
docker network connect --link container5:foo local_alias container4
docker network connect --link container4:bar local_alias container5
引申:--link 附参
--link容器时指定alias: --link=<Container-Name>:<Alias>
--icc=false隔离性,实现容器间的安全连接
注意:docker run --link=[CONTAINER_NAME]:[ALIAS] [IMAGE]
[COMMAND]
以指定代号访问容器,可避免IP变化带来的影响,在容器中即可以用别名访问容器(修改了host和改变了env)。(官方不推荐,使用docker network --link),后续版本有可能会被废弃。所以不做学习重点!
由于--link不是本篇的重点,所以不做过多介绍,如果你想了解更多,点击这里。
5.给容器断开/移除自定义网络(收尾+验证)
1)用docker inspect 命令,先查看一下container3的ip
docker inspect container3 #查看container3的元数据,主要看IP
2)docker network disconnect 移除container2的自定义网络模式mynet
docker network disconnect mynet container2 #上面单独给container2添加了mynet自定义网络,在此予以移除(移除后,只剩下了默认的网络模式bridge桥接模式)
docker run -it container2 /bin/sh #再次进入container2容器内部 注:如果contain2处于run状态,可以通过docker exec -it container2 /bin/sh 命令进入容器内部
ping -w 3 container3 #此时就不能再通过容器别名ping通conatin3了,因为此时的container2和container1没有本质区别,都是只有一个网络模式,使用的是docker0网卡的bridge桥接模式
移除后,在container2容器内部,再尝试用container3的容器名称去ping,发现ping不通了,因为container2的自定义网络模式mynet被移除了,而container3的网络模式依然是mynet。
说明:
1)此时的container2的自定义网络模式被移除了,只剩下自定义的网络模式bridge桥接模式,此时的container2和container1处于同一个网络模式下,所以container2和container1虽然不能通过别名访问,但是可以通过IP相互访问(两者IP的网段,处于同一网段);
2)反之,container3使用了自定义网络模式mynet,且指定了IP为172.25.3.3,此时的container3与container1、container2不在同一个网段(container1和contain2在docker run时没有额外指明IP,所以默认是一个网段),所以,此时在container2容器内部可以用IP ping通contain1,不能ping同container3。
docker ps # 查看正在运行的容器
docker inspect container1 #查看容器1的ip,得知是 "IPAddress": "172.17.0.3",
docker exec -it container2 /bin/sh # 进入container2容器内部,ping container1的IP
小结论:只有使用了自定义网络模式,容器之才可以使用别名通信!
知识点:一个容器可以指定多个网段,不同网段之间,默认是不互通的,但是指定了相同自定义网络模式的容器,就相当于指定了相同的网段,此时就可以使用别名通信!
3)最后,docker network rm 移除自定义网络模式mynet
docker network ls #查看网络模式列表(此时还是有mynet)
docker network rm mynet #移除自定义网络mynet(因为container3依然使用的是mynet,所以会报错)
docker kill container3 #kill或stop 容器3
docker network rm mynet #移除自定义网络mynet
docker network ls #查看网络模式列表(此时mynet已归西)
6.自定义网络模式小结
至此,相信你对docker的自定义网络模式,已经有了深入了解,内容虽然不难,比较容易理解,要去理解记忆、动手实践一下哦,图文已经总结的很全面,希望对你有所帮助!
总结
以上详细介绍了docker的五种网络模式, bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式。
1.bridge是默认的网络模式,不用单独指定,该模式下的容器,会自动被分配虚拟的网卡和IP,使用该模式的容器,最终都会通过docker0虚拟网卡和宿主机的eth0(部分虚拟可能是ens33或其他名称)交互,该方式也最为常用。非宿主机的外部容器,不能直接访问容器内部服务。需通过方法宿主机-p对外暴露的端口间接访问容器服务。
2.host 模式,需要用-d手动指定,用的不太多,它会霸占宿主机的网络资源,从而出现“宿主机就是容器,容器就是宿主机”的假象,弊端非常明显,隔离性不好,而且同个端口只能被一个容器占有。
3.container模式,是前两种的合体,首先需要有一个指定容器需要以bridge的网络模式启动,后面启动的容器以--net=container:first_bridger_container_name的方式,启动。后面启动容器的网络,依赖于这个以bridge方式启动的容器。弊端也十分明显,后面容器押宝都压在了第一个指定以桥接方式启动的容器身上,一荣皆荣,一损皆损。
4.none模式,没啥好说的,就是自娱自乐,除了有独立的网络空间(仅仅是个空架子),没有其他任何的网络资源,ip、网卡、什么的统统都没有,在网络资源这块,它就是一个光杆司令。
5.自定义网络模式这块,相对比较灵活,特别是一个容器可以指定多个网络模式,同时创建自定义网络模式时,一般使用-d指定为桥接模式,同时用--subnet指定子网网段,很Nice!
docker network create -d bridge --subnet 172.25.0.0/16 mynet #自定义名字为mynet的网络,subnet指定子网网段(不能与其他网卡的网段重叠)
如果意犹未尽,希望了解更多是容器单双通信知识,点击这里
尾言
至此,耗费了大量的时间和精力,终于把docker的5种网络模式总结完毕了。然而我总结完毕了,这可能是你的开始。
希望你能跟着图文,自己手把手实验一下,做做笔记,最好把它在理解的基础上消化吸收为自己的知识,也不枉我耗费几天时间来总结。
本讲内容是从 Docker入门到进阶里面抽离出来的内容,目的是让原文更加有序、重点突出。本节是深入了解容器,必不可少的一个环节,在此汇总分享一下,希望对大家有所帮助。
如果你觉得比较不错,伸伸小手,可以点个赞,算是对我最大的支持,O(∩_∩)O哈哈~
内容比较长,文中难免会有手误,欢迎批评指正(#^.^#)
附注
你还可能对以下内容感兴趣,一起附注给爱学习的你
1、Linux环境下Docker的快速安装、Windows10+专业版环境下安装Docker
2、如何获取Docker的最新版本 | 如何获取Tomcat/JDK/Nginx指定版本镜像
3、配置阿里云镜像加速器,提高镜像下载速度
4、Dockerfile八大核心命令 | Dockerfile构建自己的镜像
5、Docker容器 | Dockerfile优化
6、Docker容器的生命周期 | kill和stop | pause 和 unpause文章来源:https://www.toymoban.com/news/detail-486009.html
7、Docker容器之间的单双向通信文章来源地址https://www.toymoban.com/news/detail-486009.html
到了这里,关于Docker学习:容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!