第四章 Docker网络原理实战

        Docker 虚拟化技术底层基于 LXC+Cgroups+AUFS ( Overlay)技术实现,而Cgroups 是Linux内核提供的一种可以限制、记录、隔离进程组(Process Groups)所使用的物理资源的机制。

        Docker虚拟化的产物是Docker 容器,基于Docker Engine启动容器时,默认会给容器指定和分配各种子系统,如CPU子系统、Memory子系统、I/O子系统、NET子系统等。

        启动一个容器,会为Network Namespace(子系统)提供一份独立的网络环境,包括网卡、路由、Iptables规则等,容器与其他容器的Network Namespace是相互隔离的。

        通过 Docker run命令创建 Docker容器时,可以使用--net选项指定 Docker容器的网络模式,Docker默认有4种网络模式。

(1)Host模式,使用--net=host指定。

(2)Container模式,使用--net=container:NAME_or_ID指定。

(3)None模式,使用--net=none指定。

(4)Bridge模式,使用--net=bridge指定,默认设置。

4.1 Host模式剖析

        通常来讲,启动新的 Docker容器,都会分配独立的Network Namespace隔离子系统;如果在运行时指定为Host模式,那么 Docker容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace子系统。

        新创建的 Docker容器不会创建自己的网卡,不会再虚拟出自己的IP、网关、路由等信息,而是和宿主机共享IP和端口等信息,其他软件、目录还是相互独立的。两个容器除了网络方面相同之外,其他如文件系统、进程列表等还是相互隔离的。

4.2 Container 模式剖析

        Container模式是指定新创建的 Docker 容器和已存在的某个 Docker 容器共享一个NetworkNamespace子系统,而不是和宿主机共享。

        新创建的 Docker 容器不会创建自己的网卡,不会再虚拟出自己的网卡、IP、网关、路由等信息,而是和指定的Docker容器共享P和端口等信息,其他软件、目录还是相互独立的。两个容器除了网络方面相同之外,其他如文件系统、进程列表等还是相互隔离的。如果依附的 Docker容器关闭,新的 Docker容器网络也会丢失。

4.3 None模式剖析

        None模式与其他模式都不同。如果 Docker 容器使用None模式,Docker 容器会拥有自己的Network Namespace子系统,但是 Docker引擎并不会为新启动的Docker容器配置任何的网络信息。

        即新创建的Docker 容器不会虚拟出自己的网卡、IP、网关、路由等信息,而是需要手动为Docker 容器添加这些信息。在企业实战环境中,通常会使用Pipework工具为Docker容器指定IP等信息。

4.4 Bridge模式剖析

        Docker 容器的Bridge模式也是 Docker默认的网络模式。该模式会为每个容器分配NetworkNamespace子系统,会自动给每个容器虚拟出自己的网卡、IP、网关、路由等信息,无须手动添加。

        默认创建的Docker 容器会统一通过一对veth 虚拟网卡连接到一个虚拟网桥交换机DockerO上,所有的容器的网络加入一个二层交换机网络,即同一宿主机的所有容器都是可以相互联通和访问的。

4.5 Bridge模式原理剖析

        默认 Docker引擎启动会在本地生成一个 Docker0虚拟网卡。Docker0是一个标准 Linux虚拟网桥设备。在 Docker 默认的桥接网络工作模式中,Docker0网桥起至关重要的作用。物理网桥是标准的二层网络设备,标准物理网桥只有两个网口,可以将两个物理网络连接在一起。

        但与物理层设备集线器等相比,网桥具备隔离冲突域的功能。网桥通过MAC地址学习和泛洪的方式实现二层相对高效的通信。随着技术的发展,标准网桥设备已经基本被淘汰了,替代网桥的是二层交换机。二层交换机也可以看成一个多口网桥。

        Docker容器采用Bridge模式结构,如图4-1所示。

图4-1 Docker容器Bridge模式结构

        Docker Bridge模式创建过程如下。

        (1)启动Docker 容器,指定模式为桥接模式时(默认模式),Docker 引擎会创建一对虚拟网卡 veth 设备,veth 设备总是成对出现,组成一个数据的通道,数据从一个设备进入,就会从另一个设备出来。veth 设备常用来连接两个网络设备,可以把 veth 接口对认为是虚拟网线的两端。

        (2) veth 设备的另外一端放在新创建的容器中,命名为eth0;然后将另外一块设备放在宿主机中、以类似 vethxxx的名称命名,并将这个网络设备加人Docker0网桥。

        (3)Docker 引擎会从 DockerO子网中动态分配一个新的P给容器使用,并设置Docker0的IP地址为容器的默认网关。

        (4)新创建的容器与宿主机能够通信,宿主机也可以访问容器中的IP地址。在Bridge模式下,连在同一网桥(交换机)上的容器之间可以相互通信,同时容器也可以访问外网(基于iptablesSNAT)。但是其他物理机不能访问Docker容器IP,需要通过NAT将容器IP的port 映射为宿主机的IP和 port。

4.6 Bridge模式实战一

        基于 Docker引擎启动Nginx Web容器,默认以 Bridge方式启动Docker容器,会动态地给Docker容器分配IP、网关等信息,操作指令如下:

#查看镜像列表

docker images

#运行新的Nginx容器

docker run -itd docker.io/nginx:latest

#查看启动的Nginx容器

docker ps

#查看Nginx容器的IP地址

docker inspect 510ea29c39f6|grep -i ipaddr

#访问Nginx容器80端口服务 curl -I http://172.17.0.2/

4.7 Bridge模式实战二

        基于Docker引擎启动Nginx Web容器,默认以Bridge方式启动Docker容器,此处使用pipework工具手动给容器指定桥接网卡,并手动配置IP地址。操作指令如下:

#查看镜像列表

docker images

#运行新的Nginx容器

docker run -itd --net=none docker.io/nginx:latest

#查看启动的Nginx容器

docker ps

#查看Nginx容器的IP地址(没有IP地址)

docker inspect 265a3745752e|grep -i ipaddr

#安装pipework IP配置脚本工具,方法如下

#安装pipework

git clone https://github.com/jpetazzo/pipework

cp ~/pipework/pipework /usr/local/bin/

#查看pipework工具是否配置正确

pipework -h

#pipework工具手动指定容器的IP,并设置容器为桥接方式上网,命令如下(docker0为网桥

#名称,172.17.0.18/16为容器IP和掩码,172.17.0.1为容器网关)

pipework docker0 265a3745752e 172.17.0.18/16@172.17.0.1

ping 172.17.0.18 -c 2

curl -I http://172.17.0.18/

4.8 Bridge模式实战三

        基于Docker引擎启动Nginx Web容器,默认以Bridge方式启动Docker容器;Docker0的网桥IP为172.17.0.0/16网段,可以通过指令修改Docker网桥的IP网段。例如,将网桥IP段修改为10.10.0.1/16段,操作指令如下:

#删除原有网络信息

service docker stop

ip link set dev docker0 down

brctl delbr docker0

iptables -t nat -F POSTROUTING

#添加新的Docker0网络信息

brctl addbr docker0

ip addr add 10.10.0.1/16 dev docker0

ip link set dev docker0 up

#配置Docker的文件

cat>/etc/docker/daemon.json<<EOF

{"registry-mirrors": ["http://docker-cn.docker.com"],

"bip": "10.10.0.1/16"

}

EOF

#启动新的Docker容器,查看容器桥接网络IP地址

docker run -itd docker.io/nginx:latest

docker inspect 72fec5ccdf73|grep -i ipaddr

4.9 Bridge模式实战四

        为了实现Docker容器与局域网通信,并实现局域网其他的物理机也可以访问容器的IP(不配置NAT映射),可以自定义桥接网络br0,将br0与物理网卡eth0或ens33桥接。操作方法如下:

#添加ens33网卡指定bridge桥接网卡名称br0

cd /etc/sysconfig/network-scripts/

#配置ifcfg-ens33网卡

cat>ifcfg-ens33<<EOF

TYPE="Ethernet"

DEVICE="ens33"

ONBOOT="yes"

BRIDGE="br0"

IPADDR=10.0.0.122

NETMASK=255.255.255.0

GATEWAY=192.168.0.1

EOF

#配置ifcfg-br0网卡

cat>ifcfg-br0<<EOF

DEVICE="br0"

BOOTPROTO=static

ONBOOT=yes

TYPE="Bridge"

IPADDR=10.0.0.122

NETMASK=255.255.255.0

GATEWAY=192.168.0.1

EOF

#重启network网络服务

service network restart

#修改Docker引擎,使用br0网桥

cat /etc/sysconfig/docker-network

DOCKER_NETWORK_OPTIONS="-b=br0"

#安装&部署pipework工具

yum install -y git

git clone https://github.com/jpetazzo/pipework

cp ~/pipework/pipework /usr/local/bin/

#启动Docker容器,设置为none模式,然后使用br0网桥,指令如下

#(br0为网桥名称,192.168.0.11/24为容器IP和掩码,10.0.0.122为容器网关)

docker run -itd --net=none --name=nginx-v1 docker.io/nginx pipework br0 nginx-v1 192.168.0.11/24@10.0.0.122

4.10 Docker持久化固定器IP

        基于Docker引擎创建Docker容器,在默认条件下创建容器是 Bridge模式。启动容器IP地址是 DHCP随机分配且为递增的,容器之间可以互相通信,网段也是固定的。

        Docker容器一旦关闭再次启动,就会导致容器的IP地址再次随机分配,而部分容器在部署的时候是不需要互相通信的,所以应使用固态 IP,保证想要通信的容器在同一网段,且容器重启之后P地址也不会随之改变。

        根据4.9节的 Pipework脚本可以给Docker容器配置固定IP地址,但是重启也会丢失IP地址,有没有方法实现重启容器IP也不丢失呢?持久化固定IP地址操作方法如下。

        (1)安装桥接工具和 Docker-py程序,操作指令如下:

#安装Docker-py程序

#pip install docker-py

yum install python-docker*

#安装桥接扩展包

yum install bridge-utils -y

        (2)从Github仓库下载Docker-static-ip固定IP的脚本,操作指令如下:

#下载docker-static-ip脚本

git clone https://github.com/lioncui/docker-static-ip

#部署docker-static-ip程序

mv docker-static-ip /usr/local/

#启动Docker引擎服务

systemctl start docker.service

#后台启动duration脚本

cd /usr/local/docker-static-ip/

python duration.py

#查看Python脚本进程

ps -ef|grep -aiE duraion

        (3)新增配置br0桥接网络。

        vi ifcfg-ens33内容修改如下:

cat>/etc/sysconfig/network-scripts/ifcfg-ens33 <<EOF

DEVICE=ens33

BOOTPROTO=static

ONBOOT=yes

TYPE=Ethernet

BRIDGE="br0"

IPADDR=192.168.1.151

NETMASK=255.255.255.0

GATEWAY=192.168.1.1

EOF

        vi ifcfg-br0内容如下:

cat>/etc/sysconfig/network-scripts/ifcfg-br0 <<EOF

DEVICE="br0"

BOOTPROTO=static

ONBOOT=yes

TYPE="Bridge"

IPADDR=192.168.1.151

NETMASK=255.255.255.0

GATEWAY=192.168.1.1

EOF

        启动Docker服务,命令操作如下:

service docker restart

        (4)基于本地CentOS 7镜像启动CentOS云主机,网络模式选择--net=none即可,操作指令如下:

docker run -itd --net=none --privileged --name=jfedu-vm01 centos7-ssh:v1

        (5)在/usr/local/docker-static-ip/目录下,将需要给CentOS容器配置的静态IP写入containers.cfg文件即可,内容如下:

jfedu-vm01,br0,192.168.1.101/24,192.168.1.2

        (6)查看Docker容器的IP地址,此时就是192.168.1.101,命令如下:

docker exec jfedu-vm01 ifconfig

        (7)重启Docker容器,再次查看容器的IP地址,还是192.168.1.101,IP固定成功。

docker restart jfedu-vm01

docker exec jfedu-vm01 ifconfig

        (8)通过CRT或者Xshell远程登录创建的CentOS云主机。

  • 27
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值