Docker容器网络与通信原理
Docker容器默认网络模型
原理图
名词解释
- docker0
- 是一个二层网络设备,即网桥
- 通过网桥可以将Linux支持的不同的端口连接起来
- 实现类交换机多对多的通信
- veth pair
- 虚拟以太网(Ethernet)设备
- 成对出现,用于解决网络命名空间之间的隔离
- 一端连接Container network namespace,另一端连接host network namespace
Docker容器默认网络模型工作原理
容器访问外网
docker run -d --name web1 -p 28080:80 nginx:latest
iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 161 packets, 9660 bytes)
pkts bytes target prot opt in out source destination
246 15343 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
13 780 MASQUERADE all -- * !br-7537b3285555 172.19.0.0/16 0.0.0.0/0
53 3132 MASQUERADE all -- * !br-a633711c0a33 172.18.0.0/16 0.0.0.0/0
0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80
外网访问容器
iptables -t nat -vnL DOCKER
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
409 24540 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:28080 to:172.17.0.2:80
Docker容器四种网络模型
模式 | 使用方法 | 说明 |
---|---|---|
bridge [桥接式网络(Bridge container A)] | --network bridge | 桥接容器,除了有一块本地回环接口(Loopback interface)外,还有一块私有接口(Private interface)通过容器虚拟接口(Container virtual interface)连接到桥接虚拟接口(Docker bridge virtual interface),之后通过逻辑主机接口(Logical host interface)连接到主机物理网络(Physical network interface)。 桥接网卡默认会分配到172.17.0.0/16的IP地址段。 如果我们在创建容器时没有指定网络模型,默认就是(Nat)桥接网络,这也就是为什么我们在登录到一个容器后,发现IP地址段都在172.17.0.0/16网段的原因。 |
host [开放式容器(Open container)] | --network host | 比联盟式网络更开放,我们知道联盟式网络是多个容器共享网络(Net),而开放式容器(Open contaner)就直接共享了宿主机的名称空间。因此物理网卡有多少个,那么该容器就能看到多少网卡信息。我们可以说Open container是联盟式容器的衍生。 |
none [封闭式网络(Closed container)] | --network none | 封闭式容器,只有本地回环接口(Loopback interface,和咱们服务器看到的lo接口类似),无法与外界进行通信。 |
container [联盟式网络(Joined container A | Joined container B ] | --network container:c1(容器名称或容器ID) | 每个容器都各有一部分名称空间(Mount,PID,User),另外一部分名称空间是共享的(UTS,Net,IPC)。 由于它们的网络是共享的,因此各个容器可以通过本地回环接口(Loopback interface)进行通信。 除了共享同一组本地回环接口(Loopback interface)外,还有一块一块私有接口(Private interface)通过联合容器虚拟接口(Joined container virtual interface)连接到桥接虚拟接口(Docker bridge virtual interface),之后通过逻辑主机接口(Logical host interface)连接到主机物理网络(Physical network interface)。 |
Docker容器四种网络模型应用案例
查看已有的网络模型
# 查看已有的网络模型
docker network ls
NETWORK ID NAME DRIVER SCOPE
a0be1ed6360c bridge bridge local
2b3bac3d3d77 host host local
5708f555de67 none null local
# 查看已有网络模型详细信息
docker network inspect bridge
[
{
"Name": "bridge",
"Id": "a0be1ed6360c00a8e0a4988b5fb3506d76ffc98a95c7d2870eaebc5a75e2a365",
"Created": "2023-09-08T10:36:15.235953542+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"3539fbcf7d7cb12778196dd64d0bde1cdf5887614a558d76dff04d903b92ef76": {
"Name": "web1",
"EndpointID": "d70fe67944a539e4f4fa6420b54d9afac66d315c05932c634cec7311f0ae3f2b",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
# 查看docker支持的网络模型
docker info | grep Network
Network: bridge host ipvlan macvlan null overlay
创建指定类型的网络模型
bridge
# 查看创建网络模型的帮助方法
docker network create --help
# 创建一个名称为mybr0的网络
docker network create -d bridge --subnet "192.168.100.0/24" --gateway "192.168.100.1" -o com.docker.network.bridge.name=docker1 mybr0
# 查看已创建网络
docker network ls
NETWORK ID NAME DRIVER SCOPE
a0be1ed6360c bridge bridge local
2b3bac3d3d77 host host local
b7d84c6f3e6f mybr0 bridge local
5708f555de67 none null local
# 在docker host主机上可以看到多了一个网桥docker1
ifconfig
docker1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.100.1 netmask 255.255.255.0 broadcast 192.168.100.255
ether 02:42:2b:42:cc:c1 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 启动一个容器并连接到已创建mybr0网络,会进入容器
docker run -it --network mybr0 --rm busybox
# 下面在容器中执行
ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:64:02
inet addr:192.168.100.2 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:13 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1102 (1.0 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
host
# 查看host网络模型的详细信息
docker network inspect host
[
{
"Name": "host",
"Id": "2b3bac3d3d7761520c7115feecff4153b1653621b9235f41b3cbb30a7e1e4474",
"Created": "2023-09-06T10:58:39.605798371+08:00",
"Scope": "local",
"Driver": "host",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 创建容器使用host网络模型,并查看其网络信息,会进入容器
docker run -it --network host --rm busybox
# 下面在容器中执行,与在宿主机中执行返回相同的值
ifconfig
运行Nginx服务
# 创建用于运行nginx应用的容器,使用host网络模型
docker run -d --network host nginx:latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c5c0a7366943 nginx:latest "/docker-entrypoint.…" 13 seconds ago Up 13 seconds adoring_merkle
# 查看docker host 80端口状态
ss -anput | grep ":80"
tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=113034,fd=7),("nginx",pid=113033,fd=7),("nginx",pid=113032,fd=7),("nginx",pid=113031,fd=7),("nginx",pid=113030,fd=7),("nginx",pid=113029,fd=7),("nginx",pid=113028,fd=7),("nginx",pid=113027,fd=7),("nginx",pid=112990,fd=7))
tcp LISTEN 0 128 :::80 :::* users:(("nginx",pid=113034,fd=8),("nginx",pid=113033,fd=8),("nginx",pid=113032,fd=8),("nginx",pid=113031,fd=8),("nginx",pid=113030,fd=8),("nginx",pid=113029,fd=8),("nginx",pid=113028,fd=8),("nginx",pid=113027,fd=8),("nginx",pid=112990,fd=8))
# 也可以通过ip访问
curl http://127.0.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
none
# 查看none网络模型详细信息
docker network inspect none
[
{
"Name": "none",
"Id": "5708f555de6785a53ac200a8538cb8e3261b7b306248fdce58cff84ebc55fdeb",
"Created": "2023-09-06T10:58:39.596542279+08:00",
"Scope": "local",
"Driver": "null",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 创建容器使用none网络模型,并查看其网络状态,会进入容器
docker run -it --network none --rm busybox:latest
# 下面在容器中执行
ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
联盟网络
# 创建c1容器,使用默认网络模型,会进入容器
docker run -it --name c1 --rm busybox:latest
# 下面在容器中执行
ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:586 (586.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# 查看c1容器状态
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23af1a5b0889 busybox:latest "sh" About a minute ago Up About a minute c1
# Ctrl p q 不停止退出当前容器
# 创建c2容器,与c1容器共享网络命名空间,会进入容器
docker run -it --name c2 --network container:c1 --rm busybox:latest
# 下面在容器中执行
ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# 在c2容器中创建文件并开启httpd服务
echo "hello world" >> /tmp/index.html
httpd -h /tmp
# 验证80端口是否打开
netstat -npl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::80 :::* LISTEN 9/httpd
# 在c1容器中进行访问验证
docker exec c1 wget -O - -q 127.0.0.1
hello world
# 查看c1容器/tmp目录,发现没有在c2容器中创建的文件,说明c1与c2仅共享了网络命名空间,没有共享文件系统
docker exec c1 ls /tmp
跨Docker Host容器间通信实现
跨Docker Host容器间通信必要性
- 由于Docker容器运行的环境类似于在局域网中运行服务一样,无法直接被外界访问,如果采用在Docker Host利用端口映射方式会导致端口被严重消耗。
- 能够实现不同的Docker Host方便访问其它Docker Host之上的容器提供的服务
跨Docker Host容器间通信实现方案
Docker原生方案
- overlay,基于VXLAN封装实现Docker原生overlay网络
- macvlan,Docker主机网卡接口逻辑上分为多个子接口,每个子接口标识一个VLAN,容器接口直接连接Docker Host
- 网卡接口,通过路由策略转发到另一台Docker Host
第三方方案
隧道方案
- Flannel,支持UDP和VLAN封装传输方式
- Weave,支持UDP和VXLAN
- OpenvSwitch,支持VXLAN和GRE协议
路由方案
Calico
- 支持BGP协议和IPIP隧道
- 每台宿主机作为虚拟路由,通过BGP协议实现不同主机容器间通信。
Flannel
overlay network介绍
Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进行数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。
因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
Flannel介绍
Flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。 Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。 Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes
Flannel工作原理
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中,每个Node的Docker服务会分别负责所在节点容器的IP分配。Node内部的容器之间可以相互访问,但是跨主机(Node)网络相互间是不能通信。Flannel设计目的就是为集群中所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。 Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets
下面所有元素的变化信息,并且根据它来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。 如下原理图
- 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
- Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。
- 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。
ETCD
etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft
协议作为一致性算法,etcd基于Go语言实现。
etcd作为服务发现系统,特点:
- 简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单
- 安全:支持SSL证书验证
- 快速:根据官方提供的benchmark数据,单实例支持每秒2k+读操作
- 可靠:采用raft算法,实现分布式系统数据的可用性和一致性
ETCD部署
# 准备两台主机IP分别是:192.168.91.131、192.168.91.132
# 主机名称分别是docker1,docker2
# 主机名称配置
hostnamectl set-hostname docker1
# 两台主机hosts配置,用于主机名与IP地址解析
# 分别在每个节点的 /etc/hosts 文件中追加下面的内容
192.168.91.131 docker1
192.168.91.132 docker2
# 开启内核转发
# 分别在每个节点的 /etc/sysctl.conf 文件中追加下面的内容
net.ipv4.ip_forward=1
# 然后在每个节点上执行
sysctl -p
net.ipv4.ip_forward = 1
# etcd安装
# 在每个节点上执行
yum -y install etcd
# etcd配置修改 /etc/etcd/etcd.conf
# docker1节点修改或添加如下配置
ETCD_DATA_DIR="/var/lib/etcd/docker1.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="docker1"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://docker1:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://docker1:2379,http://docker1:4001"
ETCD_INITIAL_CLUSTER="docker1=http://docker1:2380,docker2=http://docker2:2380"
# docker2节点修改或添加如下配置
ETCD_DATA_DIR="/var/lib/etcd/docker2.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="docker2"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://docker2:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://docker2:2379,http://docker2:4001"
ETCD_INITIAL_CLUSTER="docker1=http://docker1:2380,docker2=http://docker2:2380"
# 在每个节点上执行下面的操作
# 开放etcd相关的端口
firewall-cmd --zone=public --add-port=2379/tcp --permanent
firewall-cmd --zone=public --add-port=2380/tcp --permanent
firewall-cmd --zone=public --add-port=4001/tcp --permanent
# 重启防火墙
firewall-cmd --reload
# 查看防火墙开放的所有端口
firewall-cmd --zone=public --list-ports
2379/tcp 2380/tcp 4001/tcp
# 设置etcd开机自启
systemctl enable etcd
# 启动etcd服务
systemctl start etcd
# 检查端口状态
netstat -tnlp | grep -E "4001|2380|2379"
tcp6 0 0 :::2379 :::* LISTEN 1914/etcd
tcp6 0 0 :::2380 :::* LISTEN 1914/etcd
tcp6 0 0 :::4001 :::* LISTEN 1914/etcd
# 检查etcd集群是否健康
etcdctl -C http://docker1:2379 cluster-health
member 1011570a22aac502 is healthy: got healthy result from http://docker1:2379
member e9ea1ddfa4d3ea28 is healthy: got healthy result from http://docker2:2379
cluster is healthy
etcdctl member list
1011570a22aac502: name=docker1 peerURLs=http://docker1:2380 clientURLs=http://docker1:2379,http://docker1:4001 isLeader=false
e9ea1ddfa4d3ea28: name=docker2 peerURLs=http://docker2:2380 clientURLs=http://docker2:2379,http://docker2:4001 isLeader=true
Flannel部署
# 在每个节点上执行下面的操作
# Flannel安装
yum -y install flannel
# Flannel配置修改 /etc/sysconfig/flanneld
# 节点修改或添加如下配置
FLANNEL_ETCD_ENDPOINTS="http://docker1:2379,http://docker2:2379"
FLANNEL_ETCD_PREFIX="/atomic.io/network"
FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/ --etcd-endpoints=http://docker1:2379,http://docker2:2379 --iface=ens33"
配置etcd中关于flannel的key
Flannel使用Etcd进行配置,来保证多个Flannel实例之间的配置一致性,所以需要在etcd上进行如下配置('/atomic.io/network/con…'这个key与上面的/etc/sysconfig/flannel中的配置项FLANNEL_ETCD_PREFIX是相对应的,错误的话启动就会出错)
# 在每个节点上执行下面的操作
etcdctl mk /atomic.io/network/config '{"Network":"172.21.0.0/16"}'
# 或者
etcdctl set /atomic.io/network/config '{"Network":"172.21.0.0/16"}'
# 查看
etcdctl get /atomic.io/network/config
{"Network":"172.21.0.0/16"}
该ip网段可以任意设定,随便设定一个网段都可以。容器的ip就是根据这个网段进行自动分配的,ip分配后,容器一般是可以对外联网的(网桥模式,只要Docker Host能上网即可。)
# 在每个节点上执行下面的操作
# 启动Flannel服务
systemctl enable flanneld
systemctl start flanneld
# 查看各节点中flannel产生的配置信息
ls /run/flannel/
docker subnet.env
# docker1节点
cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.21.0.0/16
FLANNEL_SUBNET=172.21.93.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:05:ba:66:ca 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
4: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 172.21.93.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::a505:cc8a:dd2c:1a43/64 scope link flags 800
valid_lft forever preferred_lft forever
# docker2节点
cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.21.0.0/16
FLANNEL_SUBNET=172.21.28.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:62:ae:d9:3b 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
4: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 172.21.28.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::acf5:2e32:1bfb:c220/64 scope link flags 800
valid_lft forever preferred_lft forever
Docker网络配置
# 修改docker服务配置 /usr/lib/systemd/system/docker.service
# docker1节点,修改ExecStart配置
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.21.93.1/24 --ip-masq=true --mtu=1472
# docker2节点,修改ExecStart配置
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.21.28.1/24 --ip-masq=true --mtu=1472
# 重启每个节点的docker
systemctl daemon-reload
systemctl restart docker
# docker1节点
ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:05:ba:66:ca brd ff:ff:ff:ff:ff:ff
inet 172.21.93.1/24 brd 172.21.93.255 scope global docker0
valid_lft forever preferred_lft forever
4: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 172.21.93.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::a505:cc8a:dd2c:1a43/64 scope link flags 800
valid_lft forever preferred_lft forever
# docker2节点
ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:62:ae:d9:3b brd ff:ff:ff:ff:ff:ff
inet 172.21.28.1/24 brd 172.21.28.255 scope global docker0
valid_lft forever preferred_lft forever
4: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 172.21.28.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::acf5:2e32:1bfb:c220/64 scope link flags 800
valid_lft forever preferred_lft forever
跨Docker Host容器间通信验证
# docker1节点
# 启动并进入容器
docker run -it --rm busybox:latest
# 下面在容器中执行
ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:15:5D:02
inet addr:172.21.93.2 Bcast:172.21.93.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1472 Metric:1
RX packets:13 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1102 (1.0 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# 等下面的docker2节点启动完成执行
ping 172.21.28.2
PING 172.21.28.2 (172.21.28.2): 56 data bytes
64 bytes from 172.21.28.2: seq=0 ttl=60 time=0.987 ms
64 bytes from 172.21.28.2: seq=1 ttl=60 time=1.276 ms
# docker2节点
# 启动并进入容器
docker run -it --rm busybox:latest
# 下面在容器中执行
ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:15:1C:02
inet addr:172.21.28.2 Bcast:172.21.28.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1472 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
ping 172.21.93.2
PING 172.21.93.2 (172.21.93.2): 56 data bytes
64 bytes from 172.21.93.2: seq=0 ttl=60 time=0.590 ms
64 bytes from 172.21.93.2: seq=1 ttl=60 time=4.295 ms