Docker学习笔记(三)
Docker网络
定义:Docker网络是Docker提供的一种用于在容器和容器之间、容器和外部网络之间提供网络功能的方式。Docker网络提供了容器间的安全、私有通信。
功能:容器间的互联和通信以及端口映射,容器IP变动时候可以通过服务名直接网络通信而不受到影响。
基本命令
1 | Commands: |
上述的部分命令包含子命令。可以通过–help查看
网络模式
通过使用docker network ls可以看到docker自动创建的三个网络分别是一下:
1 | bridge模式:使用--network bridge指定,默认使用docker0 |
bridge模式:为每个容器分配和设置IP等,并将容器链接到docker0的虚拟网桥上。
host模式:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
none模式:容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP 等。几乎不使用这个。
container模式:新建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP,端口范围等。
用的最多的就是bridge和host两种网络模式,在创建docker网络时默认模式是bridge模式。
docker容器内部的IP有可能是会发生变动的。
案例说明
本章案例均使用typecho镜像来说明网络的各个模式,也可以使用别的镜像,只是恰巧在本地有一个typecho的镜像。
bridge模式
概述
Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
1 | [root@localhost ~]# docker network inspect ed17f204c15f | grep bridge |
1、Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
2、docker run 的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址
3、网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
- 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
- 每个容器实例内部也有一块网卡,每个接口叫eth0;
- docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。
案例
启动一个typecho的容器实例名为typecho-network-bridege.
在宿主机上ip addr来查看网络信息,可以看到如下信息,这是因为启动了一个typecho的docker容器示例,他的网络模式就是bridge模式。
进入到typecho容器示例内部查看网络情况如下。
可以看出docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
host模式
概述
直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换。
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
案例
重新启动一个typecho的容器实例名为typecho-network-host.
1 | docker run -d \ |
当执行完毕使会出现以下waring
WARNING: Published ports are discarded when using host network mode
这是因为在host模式下,使用的是宿主机的网络配置信息,不需要在指定端口映射。
通过inspect来查看容器的网络信息如下:
1 | [root@localhost ~]# docker inspect typecho-network-host | tail -n 20 |
进入容器内部查看网络信息,可以发现,容器的网络信息和本地的信息一致。
此处由于网络信息较长,省略。
http://宿主机IP:80/
在CentOS里面用默认的火狐浏览器访问容器内的typecho服务看到访问成功,因为此时容器的IP借用主机的,所以容器共享宿主机网络IP,这样的好处是外部主机与容器可以直接通信。
none模式
该模式使用的很少。
概述
在none模式下,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo需要我们自己为Docker容器添加网卡、配置IP等。
禁用网络功能,只有lo标识(就是127.0.0.1表示本地回环)
案例
以none模式启动一个typecho容器实例,实例名称为typecho-network-none.
1 | docker run -d \ |
在容器外部查看容器的网络信息如下
1 | [root@localhost ~]# docker inspect typecho-network-none | tail -n 20 |
进入容器实例内部查看网络信息,可以看到容器的网络就只有一个lo。
1 | [root@localhost ~]# docker exec -it typecho-network-none /bin/sh |
container模式
概述
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
案例
本案例使用ubuntu的镜像演示,由于typecho镜像在启动两个容器实例的时候会导致端口冲突。
以bridge模式启动一个ubuntu容器实例,实例名称为ubuntu-o。执行以下命令会打开一个连接ubuntu-o容器的伪终端。不要关闭。
1 | docker run -it --name=ubuntu-o ubuntu:latest /bin/bash |
A:查看ubuntu-o容器的网络信息,在连接ubuntu-o的伪终端中,输入ip addr命令发现无法找到命令。执行以下命令
1
2 apt-get update
apt-get install -y iproute2
在伪终端中输入ip addr内容如下。
以下内容会根据你的系统变化。
1 | root@d184d4bdf3d1:/# ip addr |
再启动一个ubuntu容器实例,实例名字为ubuntu-w,使用container网络模式,ubuntu-o和实例共享网络信息。执行以下命令会打开一个连接ubuntu-w容器的伪终端。不要关闭。
1 | docker run -it --name=ubuntu-w --network container:ubuntu-o ubuntu:latest /bin/bash |
查看容器是否成功启动
1 | [root@localhost ~]# docker ps |
在ubuntu-w伪终端界面查看网络信息,若出现上无法找到命令的话就执行A处的步骤。ubuntu-w容器的网络信息如下
1 | root@d184d4bdf3d1:/# ip addr |
会发现ubuntu-w的网络信息和ubuntu-o的一样,是因为,ubuntu-w共享了ubuntu-o的网络。
若ubuntu-o容器实例停止运行,ubuntu-w的网络将丢失共享的网络配置剩下本地网络的回环地址配置信息。
自定义网络
概述
允许自定义容器之间的网络通信规则。自定义网络可以帮助你更好地控制容器的网络环境,例如隔离网络、创建私有网络等。
由于bridge模式在容器重启时可能会导致容器的网络配置IP信息发生变化,所以自定义网络可以使网络内的容器直接使用服务名通信。就解决了容器重启发生IP变化的问题。
案例
本案例只演示使用自定义网络后,网络内的容器可以直接调用的情况,由于不使用自定义网络只能通过IP通信这里不演示。
本案例同样使用ubuntu的镜像。
创建一个自定义的docker网络,网络名字为docker-study-network-custom,命令如下
1 | [root@localhost ~]# docker network create docker-study-network-custom |
创建两个ubuntu的实例,实例名分别为ubuntu-1,ubuntu-2。
1 | docker run -it --name=ubuntu-1 --network docker-study-network-custom ubuntu:latest /bin/bash |
在ubuntu-2内ping ubuntu-1。
若提示ping命令不存在,在ubuntu-2的容器内执行以下命令
apt-get update
apt-get install iputils-ping
1 | root@1631df68cf4d:/# ping ubuntu-1 |
同样也可以直接ping ip地址。但是容器重启IP可能会发生变化,所以自定义网络解决了容器重启发生IP变化容器连通的问题。