五、Docker网络配置

5.1 Docker网络工作原理

Docker服务启动时候会创建一个名为docker0的网桥,在启动容器的时候,会在宿主机和容器内各生成一个虚拟网卡。宿主机和容器内的虚拟网卡默认是连接到docker0这个网桥上的。所以容器可以和宿主机或其它容器网络通信。

Docker0的默认IP为172.17.0.1

docker 怎么设置网段 docker 网络配置_网络

 

启动一个容器再观察:

docker 怎么设置网段 docker 网络配置_网络_02

 

发现容器的ip是172.17.0.2

docker 怎么设置网段 docker 网络配置_网络_03

 

ping宿主机,发现是可以ping通的

在宿主机上查看桥接信息

brctl show

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_04

 

发现这个docker0上连接了一块虚拟网卡,这块虚拟网卡就是用来连接容器的。

我们再开一个容器

docker 怎么设置网段 docker 网络配置_docker_05

 

发现这个docker0上连接了两块虚拟网卡,分别用于连接两个容器

用ip link show 这个命令也能看到这两块网卡。

docker 怎么设置网段 docker 网络配置_docker_06

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_07

 

 

docker容器工作示意图。。

那么,docker又是如何可以连通宿主机以外的网络,外网又是如何可以访问到容器呢?

很简单,就是通过iptables的nat功能。

查看iptables的nat配置:

iptables  -t nat –L

docker 怎么设置网段 docker 网络配置_运维_08

 

第一个红框内是源地址转换,意思是容器访问外网的时候,源地址转换为宿主机外网网卡的地址。

第二个红框内是目的地址转换,意思是外网访问宿主机3306端口时,iptables外将目的地址转换为容器的IP地址。

我们之前学习过的3.5.1小节“将宿主机的端口映射到容器”这一章讲过的,在创建容器时加-v SPT:DPT这个参数,期实就是容器启动时在iptables中添加了一条目的地址转换的策略。

5.2 Docker网络的三种模式

bridge:桥接模式,容器网卡桥接到宿主机的桥上。(默认模式)

host:容器使用宿主机的网络配置。

none:容器不配置网卡

Docker启动后,会自动创建三个网络,分别对应以上三种模式。

docker network ls

docker 怎么设置网段 docker 网络配置_运维_09

 

host模式:

创建一个容器,并指定使用host网络

docker run -it --name centos1 --hostname centos1 --network host centos bash

--network bridge|host|none  #这里可以指定使用哪个网络,默认为bridge.

docker 怎么设置网段 docker 网络配置_centos_10

 

可以看到,容器内的网络参数和宿主机是一样的。

NONE模式:

docker run -it --name centos2 --hostname centos2 --network none centos bash

docker 怎么设置网段 docker 网络配置_运维_11

 

可以看到,容器内没有网卡。

5.3 新建docker网络

默认的网络:bridge,使用docker0做为网桥,默认使用172.17.0.1/16,且似乎无法修改,且容器的IP地址只能由宿主机自动分配,没办法指定固定的IP。

如果docker0的IP网段和我们宿主机的网段有冲突的话,那我们就没办法使用docker了。

因此我们需要新建一个docker网络。

docker network create mynet --subnet 192.168.100.0/24 --gateway 192.168.100.1

--subnet 192.168.100.0/24将mynet的网段设为192.168.100.0/24

--gateway 192.168.100.1将mynet的网关设为192.168.100.1(宿主机会取得这个地址)

docker 怎么设置网段 docker 网络配置_centos_12

 

这里会出现刚刚创建的那个网络。

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_13

docker 怎么设置网段 docker 网络配置_网络_14

 

 

宿主机上会多出一个网桥,并且IP地址是192.168.100.1

5.4自定义容器网络

现在新建一个容器,并将它连接到上一小节创建的网络mynet上。

docker run -it --name centos1 --network mynet centos bash

docker 怎么设置网段 docker 网络配置_运维_15

 

发现容器的IP是192.168.100.2

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_16

 

是可以ping通宿主机上,我们刚建的那个网桥的。

在宿主机上 brctl show,桥接已经建起来了。

docker 怎么设置网段 docker 网络配置_docker_17

 

我们也可以更改已创建完成的容器的网络

docker network connect bridge centos1

以上命令,将我们刚刚创建的容器(已连接到mynet,这个网络的),连接到默认的bridge上。

docker 怎么设置网段 docker 网络配置_网络_18

 

容器的IP地址,又变回到默认docker0的网段了。

我们也可指定容器使用固定IP地址

docker run -it --name centos3 --network mynet --ip 192.168.100.100 centos bash

--network mynet:指定连接到mynet这个网络

--ip 192.168.100.100:指定容器的IP地址为192.168.100.100.

注:当容器使用默认网络连接的时候,是不能指定容器的固定IP的;

指定的IP地址,必须和网桥在同一个网段。

docker 怎么设置网段 docker 网络配置_centos_19

 

5.5 使用openvswitch网桥

Docker默认使用的是Linux自带的网桥实现,可以替换为使用功能更强大的Openv-Switch虚拟交换机实现。

Step 1安装openvswitch

  1. 配置yum源

Openvswitch的yum源,在系统默认的yum源里是没有的,需要安装一个openstack yum源

yum -y install centos-release-openstack-queens

yum makecache

  1. 使用yum 安装openswitch

yum -y install openvswitch

  1. 启动openvswitch服务,并设置为开机自启动

systemctl start openvswitch

systemctl enable openvswitch

  1. 查看openvswitch状态

systemctl status openvswitch

docker 怎么设置网段 docker 网络配置_运维_20

 

Ifconfig

Step 2 创建一个名为ovsbr0的网桥

ovs-vsctl add-br ovsbr0

查看一下创建好的网桥

docker 怎么设置网段 docker 网络配置_运维_21

 

创建成功

Step 3 使用特权模式创建并运行一上无网络的容器

docker run -it --name centos1 --privileged=true --net=none centos bash

--privileged=true:使用特权模式,容器可以获得宿主机的root权限

--net=none :设备容器为无网络模式

此时容器内只有一个回环网卡

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_22

 

Step 4 下载OpenvSwitch项目提供的支持Docker容器的辅助脚本ovs-docker

wget https://github.com/openvswitch/ovs/raw/master/utilities/ovs-docker

给这个脚本加一下可执行权限

Chmod a+x ovs-docker

Step 5 给容器添加一块网卡eth0,并桥接到openvswitch创建的桥ovsrb0,并配置IP 地址

./ovs-docker add-port ovsbr0 eth0 centos1 --ipaddress=172.16.0.2/24

到容器内看一下网络配置

docker exec -it centos1 bash

ip address

docker 怎么设置网段 docker 网络配置_网络_23

 

这里可以看到,容器内已添加了一块网卡,并且有了IP地址

Step 6 在宿主机上配置一下ovsbr0的地址

ifconfig ovsbr0 172.16.0.1/24

docker 怎么设置网段 docker 网络配置_docker_24

 

测试一下容器网络:

docker 怎么设置网段 docker 网络配置_网络_25

 

网络是通的

5.5 自定义DOCKER_OPTS

可以使用DOCKER_OPTS对docker做更精细的管理。

Step1 :

修改docker.sevice文件

vim /usr/lib/systemd/system/docker.service

docker 怎么设置网段 docker 网络配置_docker 怎么设置网段_26

 

以上红框内是需要加入的内容。

Step 2 创建/etc/default/docker文件

docker 怎么设置网段 docker 网络配置_网络_27

 

这边加入一个OPTS “--bip 10.1.0.1/24”

实验1:修改docker0的默认IP

系统默认的docker0的IP地址是172.17.0.1/16,这里我们把这个默认IP改为10.1.0.1/24

1)按照step 2中的操作,增加一个OPTS “--bip 10.1.0.1/24”

2)重载服务配置文件,重启docker服务

systemctl daemon-reload

systemctl restart docker

3)查看docker0的IP地址

ifconfig docker0

docker 怎么设置网段 docker 网络配置_docker_28

 

发现docker0的IP地址已经变了。

  1. 创建一个名为centos3的容器

docker run -it --name centos3 centos bash

docker 怎么设置网段 docker 网络配置_运维_29

 

发现容器的IP地址变成10.1.0.0这个网段了

实验2:让容器之间不能互通

默认情况下,容器之间是可以通过网络互相访问的,但有些情况下,为了安全起见,需要限制容器间的访问。

docker 怎么设置网段 docker 网络配置_网络_30

 

在配置前,我们先开两个容器,centos1 (IP:10.1.0.2),centos2(IP:10.1.0.3)

进入容器centos2,去ping centos1的IP

docker 怎么设置网段 docker 网络配置_centos_31

 

发现是可以通的。

然后我们在/etc/default/docker这个文件里加入一个OPTS “--icc=false”

清空iptables

iptables -F

重载服务配置文件,重启docker服务

systemctl daemon-reload

systemctl restart docker

再次开启容器centos1和centos2,并进入centos2 ping centos1 ,看效果:

docker 怎么设置网段 docker 网络配置_运维_32

 

发现已经ping不通了。

这个之所以ping不通了,是因为加了这个OPTS后,会在iptables中生成一条规则。

我们查看下iptables规则:

iptables -nF

docker 怎么设置网段 docker 网络配置_运维_33