【微服务实战之Docker容器】第九章-Docker网络
Docker网络基础与模式解析 Docker提供了多种网络模式来管理容器间通信。默认创建三大网络模式:bridge、host和none。通过docker network命令可创建、删除和查看网络配置。容器IP可能随重启变化,需注意服务名通信的优势。 主要网络模式: bridge模式:默认使用docker0网桥,通过veth配对实现容器间通信 host模式:容器直接使用宿主机网络栈,共享IP和端口
目录
1 Docker网络简介
ifconfig,查看发现docker启动时会有一个docker0虚拟网络
查看docker网络模式
docker network ls
docker默认创建3大网络模式
Docker网络常用基础命令
docker network --help
新建一个网络
docker network create aa_test
docker network ls
查看网络
docker network ls
删除一个网络
docker network rm aa_test
查看网络源数据
docker network inspect XXX网络名字
能干嘛:
容器间的互联和通信以及端口映射。
容器IP变动时候可以通过服务名直接网络通信而不受到影响。
Docker网络模式
总体介绍
bridge模式:使用–network bridge指定,默认使用docker0
host模式:使用–network host指定
none模式:使用–network none指定
container模式:使用–network container:NAME或者容器ID指定
容器实例内默认网络IP生产规则
1 先启动两个ubuntu容器实例
docker run -it --name u1 ubuntu bash
(ctrl+p+q)退出容器
docker run -it --name u2 ubuntu bash
(ctrl+p+q)退出容器
2 docker inspect 容器ID or 容器名字
docker inspect u1
docker inspect u2 | tail -n 20
3 关闭u2实例,新建u3,查看ip变化
删除u2
docker rm -f u2
新建u3
docker run -it --name u3 ubuntu bash
(ctrl+p+q)退出容器
查看u3的网络
docker inspect u3 | tail -n 20
震惊!和刚才u2的网络是一样的!
这说明当我们使用ip去访问时,当容器出现宕机时,ip有可能会发生改变。
docker容器内部的ip是有可能会发生改变的。
bridge模式
Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
查看 bridge 网络的详细信息,并通过 grep 获取名称项
docker network inspect bridge | grep name
-
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
-
docker run 的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址
-
网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
3.1 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);3.2 每个容器实例内部也有一块网卡,每个接口叫eth0;
3.3 docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。
启动两个tomcat容器
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
检查下宿主机的ip,发现多了两个veth
ip addr
接着,我们进81容器也看一下ip addr
docker exec -it tomcat81 /bin/bash
发现有一个eth0@if5,表示和宿主机的第五个网卡相通
接着,我们进82容器也看一下ip addr
docker exec -it tomcat82 /bin/bash
就像是插槽一样,两两配对,实现了内部的网络互通。
Host模式
直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换。
docker network inspect host
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
启动一个83tomcat
docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
提醒不让使用端口映射,用host模式时会以宿主机端口为主,出现重复时累计+1,直到不重复。
接下来删除掉83容器
docker rm -f tomcat83
重新不映射端口启动
docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
查看下83的网络配置,没有自己的网关和配置,和宿主机用的是一个
docker inspect tomcat83
进入容器看一下网络配置
docker exec -it tomcat83 /bin/bash
ip addr
再看下外面宿主机的网络配置
发现二者一样,证明host模式使用的是宿主机的ip
访问下docker的tomcat试一下,能够正常访问
http://192.168.248.128:8080/
None模式
在none模式下,并不为Docker容器进行任何网络配置。
也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo
需要我们自己为Docker容器添加网卡、配置IP等。
禁用网络功能,只有lo标识(就是127.0.0.1表示本地回环)
docker network inspect none
docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8
启动后同样上去看一下,只有一个local(127.0.0.1)的
container模式
container⽹络模式 新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
简单来说,两个容器通过同一个网络来访问各自的内容。
案例演示1:
启动两个容器
docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
指定容器二,和容器一以container模式,共用一个网络,container:tomcat85的意思是两个容器都用85的网络
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
86启动失败,显示8080端口已经被占用
这里我们就不再用tomcat进行演示,换一个镜像来做演示。
案例演示2:
Alpine操作系统是一个面向安全的轻型 Linux发行版
Alpine Linux 是一款独立的、非商业的通用 Linux 发行版,专为追求安全性、简单性和资源效率的用户而设计。
可能很多人没听说过这个 Linux 发行版本,但是经常用 Docker 的朋友可能都用过,因为他小,简单,安全而著称,所以作为基础镜像是非常好的一个选择,可谓是麻雀虽小但五脏俱全,镜像非常小巧,不到 6M的大小,所以特别适合容器打包。
docker run -it --name alpine1 alpine /bin/sh
接着,再启动一个alpine2和alpine1使用container模式共用同一个IP
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
成功允许,没有报错
接下来,我们验证下他们两个共用同一个网桥
使用以下命令分别查看两个容器内部的ip
ip addr
发现两个容器共用了同一个ip,我们知道这是container模式我们指定了alpine2使用的是alpine1的IP。
接下来我们测试一下,我们把alpine1的容器关掉,再看下alpine2IP情况。
docker stop alpine1
接下来再看下alpine2的IP情况
这时的alpine2就只剩下一个127.0.0.1的本地IP了,因此我们确定了container指定的是继承关系,当被继承的容器关闭时,继承的容器也会失去该IP。
自定义网络模式
通过自定义网络模式我们可以实现以下:
容器间的互联和通信以及端口映射。
容器IP变动时候可以通过服务名直接网络通信而不受到影响。
案例1-不使用自定义网络模式时:
我们启动两个tomcat容器
先把原来的两个tomca容器t删掉
docker rm -f tomcat81
docker rm -f tomcat82
再重新启动
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
接着进入容器实例内部,看是否能够互相ping通
进入81
docker exec -it tomcat81 bash
查看ip
ip addr
81的ip地址是172.17.0.2
接着进入82
docker exec -it tomcat82 bash
ping81的ip
ping 172.17.0.2
是能够ping通的
但是别忘了,我们之前测试过,这个ip在容器重启时是有可能会改变的,因此我们通过服务名去连接和调用是最为稳妥的。
我们在82容器中尝试去通过服务名ping我们的81容器
ping tomcat81
不通
案例2-使用自定义网络模式时:
先查看docker已有的网络模式
docker netowrk ls
我们创建一个自定义的网络模式
docker network create zzyy_network
删除原来的两个容器
docker rm -f tomcat81
docker rm -f tomcat82
新建容器加入上一步新建的自定义网络
docker run -d -p 8081:8080 --network zzyy_network --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network zzyy_network --name tomcat82 billygoo/tomcat8-jdk8
测试使用ip和容器名互ping,IP的不再演示。
docker exec -it tomcat81 bash
ping tocmat82
嘿嘿,能通了!66的
可以自行扩展使用方法哦~
更多推荐
所有评论(0)