前言

docker容器化网络的痛点

容器化网络和日志的选型和落地,主要解决的是网络选型(k8s和mesos)以下痛点:

  1. 可否跨机器访问? 跨域访问?
  2. flannel可以跨容器通信
  3. 跨主机的容器互联
  4. 容器与外部互联
  5. 是否支持静态ip
  6. 固定ip的话,那么就需要每次部署,或者更新或重启的时候,ip保持不变
  7. overlay network, Docker 1.6 可以实现跨主机通信
  8. 是否支持dns?
  9. 是否支持4层/7层访问?
  10. 支持容器扩容后的网络?
  11. ip端口,最好不要自行手动规划。
  12. 网络策略:防御 ,隔离 ?
  13. 容器集群不同应用之间的网络隔离和流量限制?

对应的方案类别:

  1. 隧道方案, 通过隧道,或者说Overlay Networking的方式;
  2. Weave,UDP广播,本机建立新的BR,通过PCAP互通;
  3. Open vSwitch(OVS),基于VxLAN和GRE协议,但是性能方面损失比较严重;
  4. Flannel,UDP广播,VxLan。

路由方案:

Calico,基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。
Macvlan,从逻辑和Kernel层来看,隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。
性能好,没有NAT,效率比较高,但是受限于路由表,另外每个容器都有一个ip,那么业务ip可能会被用光。

Flannel 使用etcd存储配置数据和子网分配信息

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分片做了代理。 在Flannel的GitHub页面有如下的一张原理图:

pod容器里没有hostname 命令_使用openvswitch

对上图的简单说明 (Flannel的工作原理可以解释如下):
1、数据从源容器中发出后,经由所在主机的docker0虚拟网卡,转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
2、Flannel通过Etcd服务,维护了一张节点间的路由表,该张表里,保存了各个节点主机的子网网段信息。
3、源主机的flanneld服务,将原本的数据内容,UDP封装后,根据自己的路由表,投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样,由docker0路由到达目标容器。

除了UDP,Flannel还支持很多其他的Backend:
1、udp:使用用户态udp封装,默认使用8285端口。由于是在用户态封装和解包,性能上有较大的损失
2、vxlan:vxlan封装,需要配置VNI,Port(默认8472)和GBP
3、host-gw:直接路由的方式,将容器网络的路由信息,直接更新到主机的路由表中,仅适用于二层直接可达的网络
4、aws-vpc:使用 Amazon VPC route table 创建路由,适用于AWS上运行的容器
5、gce:使用Google Compute Engine Network创建路由,所有instance需要开启IP forwarding,适用于GCE上运行的容器
6、ali-vpc:使用阿里云VPC route table 创建路由,适用于阿里云上运行的容器

官方文档
https://github.com/coreos/flannel

1、准备工作

两台服务器:
192.168.160.65 node1
192.168.160.70 node2
开启内核ipv4转发功能

echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
sysctl -p

# 重启服务器后失效,需要重新执行开启转发
清除iptables底层默认规则,并开启允许转发功能

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -L -n

关闭防火墙,如果开启防火墙,则最好打开2379和4001端口

[root@node-1 ~]  systemctl disable firewalld.service
[root@node-1 ~]  systemctl stop firewalld.service

2、安装etcd服务
yum安装 (两台服务都安装)

yum install etcd -y

2、修改etcd配置文件

192.168.160.65 node1 配置

# 备份配置文件
cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf_bak
# 编辑
vim /etc/etcd/etcd.conf

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/node1.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="node1"
#
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.160.65:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.160.65:2379,http://182.168.160.65:4001"
ETCD_INITIAL_CLUSTER="node1=http://192.168.160.65:2380,node2=http://192.168.160.70:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

192.168.160.70 node2 配置 

# 备份配置文件
cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf_bak

# 编辑
vim /etc/etcd/etcd.conf

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/node2.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="node2"
#
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.160.70:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.160.70:2379,http://192.168.160.70:4001"
ETCD_INITIAL_CLUSTER="node1=http://192.168.160.65:2380,node2=http://192.168.160.70:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

启动服务》启动

systemctl start etcd
# 设置为开机启动
systemctl enable etcd
# 查看启动状态
systemctl status etcd

查看进程服务

netstat -tnlp | grep -E  "4001|2380"
ps -ef | grep etcd

验证

etcdctl --help
 etcdctl -C http://192.168.160.65:2379 cluster-health
 etcdctl -C http://192.168.160.65:4001 cluster-health
 etcdctl -C http://192.168.160.70:2379 cluster-health
 etcdctl -C http://192.168.160.70:4001 cluster-health
 # 查看下etcd集群的状态
 etcdctl member list

3、安装Flannel服务

yum安装flannel

yum install flannel -y
#配置flannel文件
# 备份配置文件
cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld_bak
# 编辑配置文件
vim /etc/sysconfig/flanneld

# Flanneld configuration options  
# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://192.168.160.65:2379,http://192.168.160.70:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"

# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/ --etcd-endpoints=http://192.168.160.65:2379,http://192.168.160.70:2379 --iface=ens33"

配置etcd中关于flannel的key(只能在etcd节点上操作
Flannel使用Etcd进行配置,来保证多个Flannel实例之间的配置一致性,所以需要在etcd上进行如下配置

('/atomic.io/network/config'这个key,与上面的/etc/sysconfig/flannel中的配置项FLANNEL_ETCD_PREFIX是相对应的,错误的话启动就会出错)

etcdctl mk /atomic.io/network/config '{"Network":"18.10.0.0/16"}'
etcdctl set /atomic.io/network/config '{"Network":"18.10.0.0/16"}'
etcdctl get /atomic.io/network/config

备注:该ip网段可以任意设定,随便设定一个网段都可以。

容器的ip,就是根据这个网段进行自动分配的,ip分配后,容器一般是可以对外联网的(网桥模式,只要宿主机能上网就可以)
启动服务

# 启动服务
systemctl start flanneld.service
# 设置开机启动
systemctl enable flanneld.service

专有网络配置
在两台云ECS主机安装与配置flannel,在专有网络下两台主机只能通过公网ip连通,所以flannel还需要额外一些配置才能连通。

# 查看当前网络集群
etcdctl ls /atomic.io/network/subnets

/atomic.io/network/subnets/18.10.88.0-24
/atomic.io/network/subnets/18.10.14.0-24
# 返回结果是两台安装flannel保存在etcd的子网信息
# 查看其中一个键值,PublicIP的值原来是内网ip
[root@ecs-c0be-0003 package]# etcdctl get /atomic.io/network/subnets/18.10.88.0-24
{"PublicIP":"192.168.0.100"}

# 两个不同帐号ECS内网ip是不连通的,所以要将两台主机键值改为公网ip
etcdctl set /atomic.io/network/subnets/18.10.88.0-24 '{"PublicIP":"139.9.248.53"}'
etcdctl set /atomic.io/network/subnets/18.10.14.0-24 '{"PublicIP":"114.116.112.159"}'

4、配置docker

# systemctl show docker 将会发现 在安装flannel后自动生成配置
DropInPaths=/usr/lib/systemd/system/docker.service.d/flannel.conf

# 查看Flannel 配置
cat /run/flannel/subnet.env 

FLANNEL_NETWORK=18.10.0.0/16
FLANNEL_SUBNET=18.10.90.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false

编辑docker配置文件

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

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=18.10.90.1/24 --ip-masq=true --mtu=1472
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3


StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

就是把--bip=18.10.90.1/24 --ip-masq=true --mtu=1472放到启动命令后面.
删除docker默认配置文件

mv /etc/docker/daemon.json /etc/docker/daemon.json.bak

重新启动docker

# 重新加载docker启动配置
systemctl daemon-reload

# 重新启动docker 服务
systemctl restart docker
#查看验证
ifconfig 

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1472
        inet 18.10.90.1  netmask 255.255.255.0  broadcast 18.10.90.255
        inet6 fe80::42:34ff:fe7e:d18b  prefixlen 64  scopeid 0x20<link>
        ether 02:42:34:7e:d1:8b  txqueuelen 0  (Ethernet)
        RX packets 15738  bytes 1270136 (1.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13868  bytes 1307080 (1.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.160.65  netmask 255.255.255.0  broadcast 192.168.160.255
        inet6 fe80::c823:3eff:61f5:8349  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:87:da:81  txqueuelen 1000  (Ethernet)
        RX packets 2453041  bytes 245567676 (234.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2221747  bytes 219463640 (209.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

flannel0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1472
        inet 18.10.90.0  netmask 255.255.0.0  destination 18.10.90.0
        inet6 fe80::7223:9944:632d:e607  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 14113  bytes 1185492 (1.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14837  bytes 1246200 (1.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

由上确定下docker的网络是否被flannel接管?我们查看下docker的进程要确认下

[root@master docker]# ps -ef | grep docker 
root     35701  1708  0 14:13 pts/0    00:00:00 grep --color=auto docker
root     49800     1  0 10:01 ?        00:00:24 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=18.10.90.1/24 --ip-masq=true --mtu=1472
root     51198 49800  0 10:02 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 18001 -container-ip 18.10.90.2 -container-port 18001
root     51206  1080  0 10:02 ?        00:00:17 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/be82fbc0cb1f945b1001b3e855158bb0dc61946b74d6821a4b59b8dcc332207f -address /run/containerd/containerd.sock -containerd-binary 
/usr/bin/containerd -runtime-root /var/run/docker/runtime-runc

Node2 服务器重复 4 操作修改docker配置,并重新启动

5、验证

在两个服务器上分别启动一个容器,并进入容器查看容器内的ip地址

sh ../shell/dockerstart.sh app-register-0.0.1 /opt/webber/package 18001

# Node1 服务器
[root@master docker]# docker exec -it app-register-0.0.1 /bin/bash
bash-4.4# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:12:0A:5A:02  
          inet addr:18.10.90.2  Bcast:18.10.90.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1472  Metric:1
          RX packets:14269 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16139 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1345034 (1.2 MiB)  TX bytes:1528422 (1.4 MiB)

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)

# Node2 服务器
[root@localhost docker]# docker exec -it app-register-0.0.1 /bin/bash 
bash-4.4# ifconfig 
eth0      Link encap:Ethernet  HWaddr 02:42:12:0A:54:02  
          inet addr:18.10.84.2  Bcast:18.10.84.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1472  Metric:1
          RX packets:14095 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14140 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1341758 (1.2 MiB)  TX bytes:1346296 (1.2 MiB)

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)

分别在两个容器类连接验证

# Node1 服务器
bash-4.4# ping 18.10.84.2
PING 18.10.84.2 (18.10.84.2): 56 data bytes
64 bytes from 18.10.84.2: seq=0 ttl=60 time=1.980 ms
64 bytes from 18.10.84.2: seq=1 ttl=60 time=0.528 ms
64 bytes from 18.10.84.2: seq=2 ttl=60 time=2.140 ms
64 bytes from 18.10.84.2: seq=3 ttl=60 time=0.580 ms
64 bytes from 18.10.84.2: seq=4 ttl=60 time=0.821 ms
^C

# Node2 服务器
bash-4.4# ping 18.10.90.2
PING 18.10.90.2 (18.10.90.2): 56 data bytes
64 bytes from 18.10.90.2: seq=0 ttl=60 time=1.224 ms
64 bytes from 18.10.90.2: seq=1 ttl=60 time=0.478 ms
64 bytes from 18.10.90.2: seq=2 ttl=60 time=1.121 ms
64 bytes from 18.10.90.2: seq=3 ttl=60 time=0.543 ms
64 bytes from 18.10.90.2: seq=4 ttl=60 time=0.552 ms
^C

由此,一可以看出,在两个不同服务器上,不同主机下,两个容器间实现可跨主机访问通信
注意事项:
1,向etcd集群写入子网信息时候,务必要注意建立的子网文件夹,要和flannel的配置文件内一致。
2,flannel的配置,etcd集群地址写正确,子网文件夹信息,要和etcd写入一致
3,系统iptables默认规则一定要清除,并开启允许转发
4,确定下docker的网络是否被flannel接管?我们查看下docker的进程要确认下
5,操作系统建议为Centos 7
附件:
docker容器中安装vim 、telnet、ifconfig命令

# 进入到docker容器内

# 更新
apt-get update

# 安装telnet
apt-get install  telnet
# 安装ifconfig命令  
apt-get install net-tools
# 安装ping命令  
apt install iputils-ping

使用openvswitch 搭建 xvlan协议隧道

open vSwitch是一个开源的虚拟交换软件,有点像Linux中的bridge,但是功能要复杂得多。Open vSwitch的网桥,可以直接建立多种通信通道(隧道),例如Open vSwitch with GRE/VxLAN。这些通道的建立,可以很容易地通过OVS的配置命令实现。在k8s、Docker场景下,我们主要是建立L3到L3的隧道,例如下面样子的网络架构。

pod容器里没有hostname 命令_容器化网络和日志的选型和落地_02


 

  1. 首先,为了避免Docker创建的docker0地址产生冲突,我们需要手动配置,和指定下各个Node节点上docker0网桥的地址段分布。
  2. 其次,建立Open vSwitch的网桥ovs,然后使用ovs-vsctl命令,给ovs网桥增加gre端口,添加gre端口时,要将目标连接的NodeIP地址,设置为对端的IP地址。对每一个对端IP地址都需要这么操作(对于大型网络,需要做自动化脚本来完成)。
  3. 最后,将ovs的网桥作为网络接口,加入Docker的网桥上。重启ovs网桥和Docker的网桥,并添加一个Docker的地址段,到Docker网桥的路由规则项,就可以将两个容器的网络连接起来了。

另一个容器的地址时,数据包会通过容器内的默认路由,发送给docker0网桥。ovs的网桥是作为docker0网桥的端口存在的,安会将数据发送给ovs网桥。ovs网络已经通过配置,建立了和其他ovs网桥的GRE/VxLAN隧道,自然能将数据送达对端的Node,并送往docker0及Pod。
通过新增的路由项,使用得Node节点本身的应用的数据,也路由到docker0网桥上,和刚才的通信过程一样,自然也可以访问其他Node上的Pod。

将多个物理机的容器,组到一个物理网络,这需要在每台机器上,创建自己的网桥br0,然后将docker默认网桥绑定到br0。
使用docker的swarm集群,或者使用docker的overlay网络。

准备环境(Ubuntu 18.04.2 LTS)

物理机server-1------192.168.0.10------运行docker容器地址:10.10.0.2/16
物理机server-2------192.168.0.20------运行docker容器地址:10.10.1.2/16
物理机server-3------192.168.0.30------运行docker容器地址:10.10.2.2/16

安装及配置

1、安装并配置consul

server-1、server-2、server-3 三台物理机全部安装consul:

wget https://releases.hashicorp.com/consul/1.4.2/consul_1.4.2_linux_amd64.zip
unzip consul_1.4.2_linux_amd64.zip
chmod +x consul
mv consul /usr/bin/

这里将server-1作为键值存储服务器,其他两个作为客户端:

server-1 / 192.168.0.10:
root@server-1:~# nohup consul agent -server -bootstrap -data-dir /var/lib/consul -bind=192.168.0.10 &> /var/log/consul.log &

server-2 / 192.168.0.20:
root@server-2:~# nohup consul agent -data-dir /var/lib/consul -bind=192.168.0.20 &> /var/log/consul.log &
root@server-2:~# consul join 192.168.0.10      # 加入到consul群集

server-3 / 192.168.0.30:
root@server-3:~# nohup consul agent -data-dir /var/lib/consul -bind=192.168.0.30 &> /var/log/consul.log &
root@server-3:~# consul join 192.168.0.10

查看群集内成员:

root@server-1:~# consul members list
 Node      Address            Status  Type    Build  Protocol  DC   Segment
 server-1  192.168.0.10:8301  alive   server  1.4.2  2         dc1  
 server-2  192.168.0.20:8301  alive   client  1.4.2  2         dc1  
 server-3  192.168.0.30:8301  alive   client  1.4.2  2         dc1

2、配置docker启动参数

为了重启的时候能找到consul的服务端,在三台机器上操作:

vim /lib/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=consul://localhost:8500 --cluster-advertise=ens33:2375

其中cluster-store的主机指定为localhost即可,cluster-advertise的ip可以指定为本机的网卡名,修改好之后需要重启docker服务:

systemctl daemon-reload && systemctl restart docker

3、创建overlay网络

在server-1上执行:

docker network create -d overlay --gateway=10.10.0.1 --subnet=10.10.0.0/16 --attachable=true dknet

创建一个类型为 overlay 的网络 dknet,创建好之后,其他两个节点,会自动同步网络信息。

root@server-1:~# docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
83e7e5433a4b        bridge              bridge              local
0200c8c4e84f        dknet               overlay             global
b986c512c5ce        host                host                local
ee7d6b44478d        none                null                local

4、创建容器并测试

分别在三台物理机上执行:

server-1:
docker run -it --net=dknet --ip=10.10.0.2 --name=web ubuntu:latest bash
server-2:
docker run -it --net=dknet --ip=10.10.1.2 --name=db ubuntu:latest  bash
server-3:
docker run -it --net=dknet --ip=10.10.2.2 --name=app ubuntu:latest  bash

进入容器后先安装命令工具:

root@3539858a25e2:/# apt update && apt install -y net-tools iputils-ping

server-1 上查看ip,并且ping其他两台机器上的容器IP地址:其他两台机器,测试方法相同,至此配置完毕!

root@3539858a25e2:/# ifconfig 
 eth0: flags=4163  mtu 1450
         inet 10.10.0.2  netmask 255.255.0.0  broadcast 10.10.255.255
         ether 02:42:0a:0a:00:02  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
 eth1: flags=4163  mtu 1500
         inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255
         ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
         RX packets 5442  bytes 16213018 (16.2 MB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 5441  bytes 505135 (505.1 KB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 lo: flags=73  mtu 65536
         inet 127.0.0.1  netmask 255.0.0.0
         loop  txqueuelen 1000  (Local Loopback)
         RX packets 8  bytes 890 (890.0 B)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 8  bytes 890 (890.0 B)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


root@3539858a25e2:/# ping 10.10.1.2 -c 3 
 PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
 64 bytes from 10.10.1.2: icmp_seq=1 ttl=64 time=1.10 ms
 64 bytes from 10.10.1.2: icmp_seq=2 ttl=64 time=0.367 ms
 64 bytes from 10.10.1.2: icmp_seq=3 ttl=64 time=0.401 ms
 --- 10.10.1.2 ping statistics ---
 3 packets transmitted, 3 received, 0% packet loss, time 2004ms
 rtt min/avg/max/mdev = 0.367/0.623/1.103/0.340 ms

root@3539858a25e2:/# ping 10.10.2.2 -c 3 
 PING 10.10.2.2 (10.10.2.2) 56(84) bytes of data.
 64 bytes from 10.10.2.2: icmp_seq=1 ttl=64 time=0.451 ms
 64 bytes from 10.10.2.2: icmp_seq=2 ttl=64 time=0.409 ms
 64 bytes from 10.10.2.2: icmp_seq=3 ttl=64 time=0.921 ms

查看创建的overlay网络dknet:

root@server-1:~# docker network inspect dknet
 [
     {
         "Name": "dknet",
         "Id": "0200c8c4e84ff9a2912552b019e8c90122ffca5066c7b118df8ec5350cb6378c",
         "Created": "2019-02-17T07:45:31.429607539Z",
         "Scope": "global",
         "Driver": "overlay",
         "EnableIPv6": false,
         "IPAM": {
             "Driver": "default",
             "Options": {},
             "Config": [
                 {
                     "Subnet": "10.10.0.0/16",
                     "Gateway": "10.10.0.1"
                 }
             ]
         },
         "Internal": false,
         "Attachable": true,
         "Ingress": false,
         "ConfigFrom": {
             "Network": ""
         },
         "ConfigOnly": false,
         "Containers": {
             "3539858a25e22837fa6649facf4ff1b2ff9581b4dbcdd21541037976a09660da": {
                 "Name": "web",
                 "EndpointID": "cde41697a54feb968024e0ffb057e370eff18bdfc7723633d7babb30e342fd93",
                 "MacAddress": "02:42:0a:0a:00:02",
                 "IPv4Address": "10.10.0.2/16",
                 "IPv6Address": ""
             },
             "ep-9e1670750656ae673948019e7ab08223a1f10d5d1cd8b0c9c4f678d636cae607": {
                 "Name": "app",
                 "EndpointID": "9e1670750656ae673948019e7ab08223a1f10d5d1cd8b0c9c4f678d636cae607",
                 "MacAddress": "02:42:0a:0a:02:02",
                 "IPv4Address": "10.10.2.2/16",
                 "IPv6Address": ""
             },
             "ep-f8a0a2d27b81fc292e75fb15cd8c0d920f81c2178e7eb4bdfa3ad40df3310d78": {
                 "Name": "db",
                 "EndpointID": "f8a0a2d27b81fc292e75fb15cd8c0d920f81c2178e7eb4bdfa3ad40df3310d78",
                 "MacAddress": "02:42:0a:0a:01:02",
                 "IPv4Address": "10.10.1.2/16",
                 "IPv6Address": ""
             }
         },
         "Options": {},
         "Labels": {}
     }
 ]