Dokcer学习笔记 —— 容器网络(跨主机容器网络互通)
Posted 爱敲代码的三毛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dokcer学习笔记 —— 容器网络(跨主机容器网络互通)相关的知识,希望对你有一定的参考价值。
文章目录
Docker容器网络
1. 本地网络
docker本地有4种类型的网络:
- bridge
这里的bridge和虚拟机里的桥接网络类型不太一样。可以把这个看作
与虚拟机里的NAT类型相似。宿主机能上公网,那么连接此网络的容器也可以上公网。
此为默认网络类型(也就是说运行容器时不指定网络,默认都属于这种
类型)。宿主机上的docker0网卡就是属于此网络.
- host
和宿主机共享网络,连接此网络的容器使用ifconfig查看的信息和宿主机一致,没有做NAT转换,类似跑在宿主机上一样。
- none
连接此网络的容器没有IP地址等信息,只有lo本地回环网卡。
无法连接公网网络。
- container
多个容器连接到此网络,那么容器间可以互相通讯,不和宿
主机共享
1) bridge
所有容器连接到桥,就可以使用外网,使用NAT让容器可以访问外网
[root@docker ~]# ip a
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:b1:7c:e1:ad brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
所有容器连接到此桥,IP地址都是172.17.0.0/16
1.创建一个名为bridge0的bridge类型的网络,指定网段为10.3.3.0/24(此网
段不能和宿主机已有的网段冲突),网关为10.3.3.1
[root@docker ~]# docker network create -d bridge --subnet "10.3.3.0/24" --gateway "10.3.3.1" bridge0
b6f4e5f4820b0e613d97d0726fdcbf5c48e735c9bf0c2dc7097fc9e529f96910
可以查看到bridge0这个网络,要删除的话使用docker network rm
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4b4c77e3837d bridge bridge local
b6f4e5f4820b bridge0 bridge local
d1809226464e host host local
bf038e1f5e1f none null local
2.运行容器,指定使用刚创建的网络
[root@docker ~]# docker run -it -d --name centos --network bridge0 centos:latest
d2e97d4f45aa0638ecbbf2fa0135abb709e2256fbd94988abd8cd2ddeb902a4c
3.验证并测试此容器的网络
[root@docker ~]# docker exec centos ip a | grep inet
inet 127.0.0.1/8 scope host lo
inet 10.3.3.2/24 brd 10.3.3.255 scope global eth0
可以ping通网关
[root@docker ~]# docker exec centos ping -c3 10.3.3.1
PING 10.3.3.1 (10.3.3.1) 56(84) bytes of data.
64 bytes from 10.3.3.1: icmp_seq=1 ttl=64 time=0.103 ms
64 bytes from 10.3.3.1: icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from 10.3.3.1: icmp_seq=3 ttl=64 time=0.108 ms
--- 10.3.3.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.101/0.104/0.108/0.003 ms
可以上网
[root@docker ~]# docker exec centos ping -c1 www.baidu.com
PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data.
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=127 time=26.2 ms
4.宿主机上会产生一个网卡名为br-xxxxx, IP地址为设置的网关10.3.3.1
[root@docker ~]# ip a
4: br-b6f4e5f4820b: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:25:76:10:57 brd ff:ff:ff:ff:ff:ff
inet 10.3.3.1/24 brd 10.3.3.255 scope global br-b6f4e5f4820b
valid_lft forever preferred_lft forever
inet6 fe80::42:25ff:fe76:1057/64 scope link
valid_lft forever preferred_lft forever
2) host
所有的容器与docker host在同一网络中,可以让容器访问,甚至可以让外网主机访问容器中的服务
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d1809226464e host host local
指定 host 网络运行容器
- 安装完成后,查看IP地址,发现其使用了docker host地址
- 好处在于方便访问
- 坏处在多容器同时运行一种服务,端口冲突
- 名字ip和宿主机一致,最好只在测试环境使用
[root@docker ~]# docker run -it --network host centos:latest /bin/bash
[root@docker /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 00:0c:29:c1:2b:2e brd ff:ff:ff:ff:ff:ff
inet 192.168.44.100/24 brd 192.168.44.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fec1:2b2e/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:b1:7c:e1:ad brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
3) none
不能与外网通讯,只有lo本地通迅
[root@docker ~]# docker run -it --network none centos:latest
[root@391a753f6ee9 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
ip都没有
4) container
基本不用
容器间共享同一个网络命名空间,实现容器间数据传输
docker run -itd --name c8 --
network=container:c1 centos:latest /bin/bash
c8容器与c1容器的网络一致(包括IP)
跨主机容器间网络
不同的宿主机上的容器通过映射端口,然后通过两台宿主机的IP和映射的端口来通迅。但这样做是利用了宿主机的网络,在某些场景并不方便。能不能建立跨宿主机之间的网络,让容器使用自己的IP就可以通迅呢? 答案是肯定的,而且方案也有很多种: 有docker原生的overlay、macvlan和第三方方案flannel。
1. flannel
flannel是kubernetes[kubə’netis]默认提供网络插件,由CoreOS团队设计
flannel实质上是一种“覆盖网络(overlay network)”, 也就是将TCP数据包装
在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、
AWS VPC和GCE路由等数据转发方式。
flannel可使用etcd存储,分配,维护子网信息,最终实现一个大网络内的不同
子网可以互通
- 是Overlay网络,即覆盖型网络
- 通过etcd保存子网信息及网络分配信息
- 给每台Docker Host分配置一个网段
- 通过UDP传输数据包
2. flannel 环境搭建
1) 环境准备
主机名 | ip | 安装软件 |
---|---|---|
node1 | 192.168.44.100 | etcd,flannel,docker |
node2 | 192.168.44.110 | flannel,docker |
-
配置静态ip
-
主机名绑定(/etc/hosts)
-
时间同步
-
关闭防火墙和SELinux
-
yum源(使用centos安装完系统后的默认yum源再加上下面的docker-ce源)
# yum install -y yum-utils device-mapper-persistent-data lvm2 # yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2) 搭建过程
第1步: 在node1上安装etcd,flannel,docker
[root@node1 ~]# yum install etcd flannel docker-ce -y
第2步: 在node1上配置etcd服务并启动
[root@node1 ~]# vim /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" 这里要监听
0.0.0.0,这样flanneld服务才能连接
[root@node1 ~]# systemctl start etcd
[root@node1 ~]# systemctl enable etcd
第3步: 在node1上配置flanneld服务,创建网络,并启动服务
[root@node1 ~]# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.44.100:2379" 注
意:这里IP改为etcd服务IP
创建一个虚拟网络(我这里创建172.18.0.0/16)
[root@node1 ~]# etcdctl mk //atomic.io/network/config '"Network":"172.18.0.0/16"'
"Network":"172.18.0.0/16"
[root@node1 ~]# systemctl start flanneld
[root@node1 ~]# systemctl enable flanneld
验证分配的网络(在172.18.0.0/16里随机的)
[root@node1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.26.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
第4步: 在node1上关联docker0网络与flannel0网络,启动docker服务,并验证网络
[root@node1 ~]# systemctl start docker
先启动docker才会产生/etc/docker/目录
[root@node1 ~]# vim /etc/docker/daemon.json
"bip": "172.18.26.1/24",
"mtu": 1472
说明:
- bip 边界IP,和 /run/flannel/subnet.env 配置文件里的对应
- mtu 网络最大传输单元,也和 /run/flannel/subnet.env 配置文件里
的对应
这里必须要重启docker服务;否则上面创建的flannel网络不能生效
[root@node1 ~]# systemctl restart docker
[root@node1 ~]# systemctl enable docker
[root@node1 ~]# ip a | grep -E 'docker0|flannel0'
3: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
inet 172.18.26.0/16 scope global flannel0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.18.86.1/24 brd 172.18.86.255 scope global docker0
第5步: 在node2安装flannel,docker
# yum install flannel docker-ce -y
第6步: 在node2上配置flanneld服务,并启动服务
[root@node2 ~]# vim /etc/sysconfig/flanneld
这里IP改为etcd服务IP
FLANNEL_ETCD_ENDPOINTS="http://192.168.44.100:2379"
[root@node2 ~]# systemctl start flanneld
[root@node2 ~]# systemctl enable flanneld
验证分配的网络
[root@node2 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.85.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
第7步: 在node2上启动docker服务,并验证网络
[root@node2 ~]# systemctl start docker
[root@node2 ~]# vim /etc/docker/daemon.json
"bip": "172.18.85.1/24"
"mtu": 1472
[root@node2 ~]# systemctl restart docker
[root@node2 ~]# systemctl enable docker
[root@node2 ~]# ip a | grep -E 'docker0|flannel0'
3: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
inet 172.18.85.0/16 scope global flannel0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.18.85.1/24 brd 172.18.85.255 scope global docker0
第8步: 在两台docker宿主机上分别运行容器
两台都下载busybox镜像(此镜像包含了ifconfig命令,镜像也小,下载快)
[root@node1 ~]# docker pull busybox
[root@node2 ~]# docker pull busybox
[root@node1 ~]# docker run -itd --name=test busybox /bin/sh
8614bb87f07d4666458aad7c5d036650e7f9332fb639f9c49a8afbaca4bcd12b
[root@node1 ~]# docker exec test ifconfig | head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:1A:02
inet addr:172.18.26.2 Bcast:172.18.26.255 Mask:255.255.255.0
[root@node2 ~]# docker run -itd --name=test busybox /bin/sh
a0803754ca1f29ec99a6671c60e7c70926f48af68b45cffcb26dedc9abf01cf0
[root@node2 ~]# docker exec test ifconfig | head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:55:02
inet addr:172.18.85.2 Bcast:172.18.85.255 Mask:255.255.255.0
第9步: 在两台宿主机上进行容器连通测试
node1上的test容器ping测试node2上的test容器,不通
[root@node1 ~]# docker exec test ping -c2 172.18.85.2
这里是被防火墙给限制了(启动docker服务,会产生iptables的规则),清除规
则(注意FORWARD链默认规则要改)
[root@node1 ~]# iptables -F
[root@node1 ~]# iptables -P FORWARD ACCEPT
[root@node2 ~]# iptables -F
[root@node2 ~]# iptables -P FORWARD ACCEPT
最后测试
[root@node1 ~]# docker exec test ping -c3 172.18.85.2
PING 172.18.85.2 (172.18.85.2): 56 data bytes
64 bytes from 172.18.85.2: seq=0 ttl=60 time=2.836 ms
64 bytes from 172.18.85.2: seq=1 ttl=60 time=3.299 ms
64 bytes from 172.18.85.2: seq=2 ttl=60 time=1.612 ms
--- 172.18.85.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.612/2.582/3.299 ms
[root@node2 ~]# docker exec test ping -c3 172.18.26.2
PING 172.18.26.2 (172.18.26.2): 56 data bytes
64 bytes from 172.18.26.2: seq=0 ttl=60 time=1.517 ms
64 bytes from 172.18.26.2: seq=1 ttl=60 time=1.361 ms
64 bytes from 172.18.26.2: seq=2 ttl=60 time=2.031 ms
--- 172.18.26.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.361/1.636/2.031 ms
以上是关于Dokcer学习笔记 —— 容器网络(跨主机容器网络互通)的主要内容,如果未能解决你的问题,请参考以下文章
docker的跨主机网络Overlay,MacVlan网络的实现