Docker服务启动时候会创建一个名为docker0的网桥,在启动容器的时候,会在宿主机和容器内各生成一个虚拟网卡。宿主机和容器内的虚拟网卡默认是连接到docker0这个网桥上的。所以容器可以和宿主机或其它容器网络通信。
Docker0的默认IP为172.17.0.1
启动一个容器再观察:
发现容器的ip是172.17.0.2
ping宿主机,发现是可以ping通的
在宿主机上查看桥接信息
brctl show
发现这个docker0上连接了一块虚拟网卡,这块虚拟网卡就是用来连接容器的。
我们再开一个容器
发现这个docker0上连接了两块虚拟网卡,分别用于连接两个容器
用ip link show 这个命令也能看到这两块网卡。
docker容器工作示意图。。
那么,docker又是如何可以连通宿主机以外的网络,外网又是如何可以访问到容器呢?
很简单,就是通过iptables的nat功能。
查看iptables的nat配置:
iptables -t nat –L
第一个红框内是源地址转换,意思是容器访问外网的时候,源地址转换为宿主机外网网卡的地址。
第二个红框内是目的地址转换,意思是外网访问宿主机3306端口时,iptables外将目的地址转换为容器的IP地址。
我们之前学习过的3.5.1小节“将宿主机的端口映射到容器”这一章讲过的,在创建容器时加-v SPT:DPT这个参数,期实就是容器启动时在iptables中添加了一条目的地址转换的策略。
bridge:桥接模式,容器网卡桥接到宿主机的桥上。(默认模式)
host:容器使用宿主机的网络配置。
none:容器不配置网卡
Docker启动后,会自动创建三个网络,分别对应以上三种模式。
docker network ls
host模式:
创建一个容器,并指定使用host网络
docker run -it --name centos1 --hostname centos1 --network host centos bash
--network bridge|host|none #这里可以指定使用哪个网络,默认为bridge.
可以看到,容器内的网络参数和宿主机是一样的。
NONE模式:
docker run -it --name centos2 --hostname centos2 --network none centos bash
可以看到,容器内没有网卡。
默认的网络: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(宿主机会取得这个地址)
这里会出现刚刚创建的那个网络。
宿主机上会多出一个网桥,并且IP地址是192.168.100.1
现在新建一个容器,并将它连接到上一小节创建的网络mynet上。
docker run -it --name centos1 --network mynet centos bash
发现容器的IP是192.168.100.2
是可以ping通宿主机上,我们刚建的那个网桥的。
在宿主机上 brctl show,桥接已经建起来了。
我们也可以更改已创建完成的容器的网络
docker network connect bridge centos1
以上命令,将我们刚刚创建的容器(已连接到mynet,这个网络的),连接到默认的bridge上。
容器的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默认使用的是Linux自带的网桥实现,可以替换为使用功能更强大的Openv-Switch虚拟交换机实现。
Step 1安装openvswitch
Openvswitch的yum源,在系统默认的yum源里是没有的,需要安装一个openstack yum源
yum -y install centos-release-openstack-queens
yum makecache
yum -y install openvswitch
systemctl start openvswitch
systemctl enable openvswitch
systemctl status openvswitch
Ifconfig
Step 2 创建一个名为ovsbr0的网桥
ovs-vsctl add-br ovsbr0
查看一下创建好的网桥
创建成功
Step 3 使用特权模式创建并运行一上无网络的容器
docker run -it --name centos1 --privileged=true --net=none centos bash
--privileged=true:使用特权模式,容器可以获得宿主机的root权限
--net=none :设备容器为无网络模式
此时容器内只有一个回环网卡
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
这里可以看到,容器内已添加了一块网卡,并且有了IP地址
Step 6 在宿主机上配置一下ovsbr0的地址
ifconfig ovsbr0 172.16.0.1/24
测试一下容器网络:
网络是通的
可以使用DOCKER_OPTS对docker做更精细的管理。
Step1 :
修改docker.sevice文件
vim /usr/lib/systemd/system/docker.service
以上红框内是需要加入的内容。
Step 2 创建/etc/default/docker文件
这边加入一个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
发现docker0的IP地址已经变了。
docker run -it --name centos3 centos bash
发现容器的IP地址变成10.1.0.0这个网段了
实验2:让容器之间不能互通
默认情况下,容器之间是可以通过网络互相访问的,但有些情况下,为了安全起见,需要限制容器间的访问。
在配置前,我们先开两个容器,centos1 (IP:10.1.0.2),centos2(IP:10.1.0.3)
进入容器centos2,去ping centos1的IP
发现是可以通的。
然后我们在/etc/default/docker这个文件里加入一个OPTS “--icc=false”
清空iptables
iptables -F
重载服务配置文件,重启docker服务
systemctl daemon-reload
systemctl restart docker
再次开启容器centos1和centos2,并进入centos2 ping centos1 ,看效果:
发现已经ping不通了。
这个之所以ping不通了,是因为加了这个OPTS后,会在iptables中生成一条规则。
我们查看下iptables规则:
iptables -nF