前言

本讲是从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

7、Docker容器之间的单双向通信

Docker学习:容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解相关推荐

  1. [Python图像识别] 五十.Keras构建AlexNet和CNN实现自定义数据集分类详解

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  2. Hadoop入门(二)——VMware虚拟网络设置+Windows10的IP地址配置+CentOS7静态IP设置(图文详解步骤2021)

    Hadoop入门(二)--VMware虚拟网络设置+Windows10的IP地址配置+CentOS7静态IP设置(图文详解步骤2021) 之前在上一篇文章中讲述了 CentOS7下载+VM上安装(手动 ...

  3. Docker学习(五):Docker网络

    Docker网络 1. docker network命令 #查看docker网络 docker network ls #帮助命令 docker network --help #创建网络 docker ...

  4. docker学习笔记(五)docker实战

    目录 一.搭建MySQL高可用集群(pxc+HA-Proxy) 二.Nginx+Spring Boot+MySQL 一.搭建MySQL高可用集群(pxc+HA-Proxy) 参考链接:https:// ...

  5. FATE学习:五种不同的API提交FATE任务

    综述 当前支持如下五种API来提交FATE任务,分别为: CLI API:通过python 启动python 脚本 fate_flow_client.py,提交FATE任务. REST API:Res ...

  6. Dockerfile精编细作(六)四种网络模式bridge、host、container、none

    查看网卡信息 查看ip信息:centos7:ip add或ip addr lo:localhost网卡 ens33:对外网卡以太网,本机ip docker0:docker容器和宿主机通信的网卡,Doc ...

  7. 区块链用哪种语言 Java_区块链开发用什么语言呢?区块链与编程语言的关系详解...

    原标题:区块链开发用什么语言呢?区块链与编程语言的关系详解 区块链的概念就随着比特币的大热开始逐渐进入公众视野,比特币的拥有者为了使其创造更高的财富,开始疯狂炒作,因而引发购买比特币大浪潮.然而等到比 ...

  8. IP地址、子网掩码、网络号、主机号、网络地址、主机地址以及ip段详解

    背景知识 IP地址 IP地址被用来给Internet上的电脑一个编号.大家日常见到的情况是每台联网的PC上都需要有IP地址,才能正常通信.我们可以把"个人电脑"比作"一台 ...

  9. css三种定位都脱离文档流了吗,CSS布局之脱离文档流详解——浮动、绝对定位脱离文档流的区别...

    1.代码 (1)示例代码1 CSS布局之脱离文档流详解--浮动.绝对定位脱离文档流的区别 .left { width: 300px; height: 500px; background: red; f ...

最新文章

  1. android菜单(menu)资源
  2. 「GNN,简直太烂了」,一位Reddit网友的深度分析火了
  3. Android配置build.gradle解锁更高逼格玩法(多版本共存、分服务器打包等)
  4. 160个CrackMe002
  5. POPUP_TO_DECIDE
  6. mybatis-plus 查询,删除
  7. Tomcat启动项目没问题,网页一片空白
  8. 【网站开发必备】——12款响应式 Lightbox(灯箱)效果插件
  9. 1.1.2 Greedy Gift Givers 贪婪的送礼者
  10. 浅谈java实现桌面小程序
  11. 数值计算方法matlab课后答案,《现代的数值计算方法matlab版》习题解答.pdf
  12. html中响应ocx事件,JS实现OCX控件的事件响应示例
  13. navicat编程界面_主界面初识 Navicat Premium使用技巧(一)
  14. Pandas:写了一个简易的销量异常检测器
  15. 【HTML】人生苦短, 快卷快卷 第二课 HTML 基础
  16. 关于世博会的一些遐想!
  17. 外卖返利系统电影吃喝玩乐团购返利系统外卖探探外卖券儿外卖cps系统saas源码
  18. 从 0 到 1 学习 elasticsearch ,这一篇就够了!(建议收藏)
  19. Cast-Designer Weld人工智能参与的多道焊工艺参数设计
  20. 影视剪辑副业真的可以月入过万吗?

热门文章

  1. 电脑总是自动弹出outlook Express 窗口
  2. 中海达ihand30手簿详细教程_中海达ihand20手簿使用简易说明书
  3. 埃森哲最新研究认为,全球企业高管尚未看清5G应用潜力
  4. 计算机系统结构WINDLX实验——实验一
  5. 怎么调解计算机休眠不断网,win7怎么设置不待机?win7设置不待机的方法
  6. docker安装部署jdk1.8
  7. 阿里巴巴离职DBA在35岁总结的职业生涯
  8. Android刘海屏、水滴屏全面屏适配。
  9. java微服务打包命令
  10. JavaScript获得页面卷起的高度