docker 跨主机的容器间通信(macvlan)

 作用:

虚拟多个mac地址,虚拟出多个网卡给容器用。

 

#创建macvlan网络
docker network create --driver macvlan(要创建的网络类型) --subnet  子网IP段  --gateway 本机网关 -o parent=本机网卡  创建的macvlan网络名称
[root@k8s129 ~]# docker network create --driver macvlan --subnet 192.168.6.0/24 --gateway 192.168.6.254 -o parent=eth0  macvlan_xj
7e4729ca45692d2f2a5e4a2129a39027ac1b3f97331129a5dc07093e12edc9f7
[root@k8s129 ~]# docker network ls  #查看创建好的网络
NETWORK ID          NAME                DRIVER              SCOPE
391cca4ceb1e        bridge              bridge              local
ebb5492e53f3        host                host                local
7e4729ca4569        macvlan_xj          macvlan             local
b087e09b1e13        none                null                local
 
#在另外一台机器,也创建相同的网络
[root@k8s130 yum.repos.d]# docker network create --driver macvlan --subnet 192.168.6.0/24 --gateway 192.168.6.254 -o parent=eth0  macvlan_xj
34d43e62d44f26cee3124124a87187f89a81d8ef65cb7cd2f313f8c856bef7f3
[root@k8s130 yum.repos.d]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
922766952baf        bridge              bridge              local
45355ea7ab2b        host                host                local
34d43e62d44f        macvlan_xj          macvlan             local
1de35a0fe6bd        none                null                local
[root@k8s130 yum.repos.d]#
 
#创建使用macvlan 网络的 容器
[root@k8s129 ~]# ping 192.168.6.3  #找到一个没有被使用的IP
PING 192.168.6.3 (192.168.6.3) 56(84) bytes of data.
From 192.168.6.129 icmp_seq=1 Destination Host Unreachable
 
#128机器上面起一个容器,IP地址是:192.168.6.3
[root@k8s129 ~]# docker run -it --network macvlan_xj --ip=192.168.6.3 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
7: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:c0:a8:06:03 brd ff:ff:ff:ff:ff:ff
    inet 192.168.6.3/24 brd 192.168.6.255 scope global eth0
       valid_lft forever preferred_lft forever
#ping 一下另外一台宿主机IP,发现是可以ping通的
#并且这时候可以直接使用xshell,登录这台容器,就和宿主机一样的效果
/ # ping 192.168.6.130
PING 192.168.6.130 (192.168.6.130): 56 data bytes
64 bytes from 192.168.6.130: seq=0 ttl=64 time=1.104 ms
^C
--- 192.168.6.130 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.505/0.804/1.104 ms
/ #
#130机器上面也起一个容器,ip地址是:192.168.6.4 
[root@k8s130 yum.repos.d]# docker run -it --network macvlan_xj --ip=192.168.6.4 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
5: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:c0:a8:06:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.6.4/24 brd 192.168.6.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 192.168.6.3  # ping 192.168.6.3容器,发现是可以互相ping的,实现了容器互联
PING 192.168.6.3 (192.168.6.3): 56 data bytes
64 bytes from 192.168.6.3: seq=0 ttl=64 time=1.059 ms
^C
--- 192.168.6.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.059/1.059/1.059 ms
/ #

 缺点:

每次需要手动指定IP地址,分配IP地址(还要去手动的查看这个IP地址有没有被使用)

优点:

性能好,和局域网其它服务器处于同一个网段

-------------------------------

docker跨主机通信之 overlay(重叠网络,vxlan)

 

为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。

VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。

Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息(这样就可以知道哪些IP目前是被使用的)

包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。

Consul 类似于redis的功能。

 

#安装Consul  (直接起一个Consul 的容器就可以了)
[root@k8s129 ~]# docker run -d -p 8500:8500 -h consul --name consul  --restart=always progrium/consul -server -bootstrap

容器启动后,可以通过 http://192.168.6.129:8500 访问 Consul。

 

#在原有的基础上面增加如下三行:
  "hosts": ["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],#起2376端口,和sock
  "cluster-store": "consul://192.168.6.129:8500",           #consul网络地址
  "cluster-advertise": "192.168.6.129:2376"                
[root@k8s129 ~]# cat /etc/docker/daemon.json    
{
  "registry-mirrors": ["https://aeckruos.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.6.129:5000"],
  "hosts": ["tcp://0.0.0.0:2376","unix://var/run/docker.sock"],
  "cluster-store": "consul://192.168.6.129:8500",
   "cluster-advertise": "192.168.6.130:2376"
}
[root@k8s129 ~]# vim /usr/lib/systemd/system/docker.service
# for containers run by docker
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd  #上面的这句改成当前的这句
 
#重启 docker daemon。
[root@k8s129 ~]# systemctl daemon-reload  
[root@k8s129 ~]# systemctl restart docker.service
[root@k8s129 ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      6120/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      6209/master         
tcp6       0      0 :::5000                 :::*                    LISTEN      9063/docker-proxy   
tcp6       0      0 :::2376                 :::*                    LISTEN      8921/dockerd        
tcp6       0      0 :::22                   :::*                    LISTEN      6120/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      6209/master         
[root@k8s129 ~]#
#在把刚才的容器起一下
[root@k8s129 ~]# docker rm `docker ps  -a  -q`
[root@k8s129 ~]# docker run -d -p 8500:8500 -h consul --name consul  --restart=always progrium/consul -server -bootstrap

这个时候网页点击:key.value 在点击docker然后 nodes多点击几次,就会出现我们129 的节点了

 

容器mac会变吗 容器 mac地址_IP

 

 

之后再130机器修改如下:

[root@k8s130 yum.repos.d]# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["https://aeckruos.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.6.129:5000"],
  "hosts": ["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
  "cluster-store": "consul://192.168.6.129:8500",
  "cluster-advertise": "192.168.6.130:2376"  #只需要把这个IP改成我们的本机130IP就可以
}
[root@k8s130 yum.repos.d]# vim /usr/lib/systemd/system/docker.service
# for containers run by docker
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd  #上面的这句改成当前的这句
[root@k8s130 yum.repos.d]# systemctl daemon-reload  
[root@k8s130 yum.repos.d]# systemctl restart docker.service

 

之后网页:

就会出现两个节点了

 

容器mac会变吗 容器 mac地址_容器mac会变吗_02

 

 

 

到此我们的环境就准备好了,下面overlay(重叠网络,vxlan)的用法:

 ==

创建overlay网络 

#129或者130创建都可以,在任何一个节点创建网络,会自动同步到另外一台
[root@k8s139 / 130 ~]# docker network ls  
NETWORK ID          NAME                DRIVER              SCOPE
aaa40ad04d54        bridge              bridge              local
45355ea7ab2b        host                host                local
34d43e62d44f        macvlan_xj          macvlan             local
1de35a0fe6bd        none                null                local
[root@k8s130 ~]# docker network rm 34d43e62d44f   #删掉之前创建的macvlan_xj 网络,因为我们要使用192的网段,如果你有两块网卡,比如172网段,就不需要删除,执行下面的指定成172网段的就行s
[root@k8s130 ~]# docker network create -d overlay --subnet 192.168.6.0/24 --gateway 192.168.6.254 oll
[root@k8s130 ~]# docker network ls  
NETWORK ID          NAME                DRIVER              SCOPE
aaa40ad04d54        bridge              bridge              local
45355ea7ab2b        host                host                local
1de35a0fe6bd        none                null                local
be79115dff0b        oll                 overlay             global
[root@k8s130 ~]#
 
#启动容器测试,跨主机ping, ping百度都可以上外网
[root@k8s129 ~]# docker run -it --network oll --name xujin01 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
    link/ether 02:42:c0:a8:06:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.6.1/24 brd 192.168.6.255 scope global eth0
       valid_lft forever preferred_lft forever
19: eth1@if20: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # ping 192.168.6.2
PING 192.168.6.2 (192.168.6.2): 56 data bytes
64 bytes from 192.168.6.2: seq=0 ttl=64 time=0.996 ms
64 bytes from 192.168.6.2: seq=1 ttl=64 time=1.023 ms
^C
--- 192.168.6.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.996/1.009/1.023 ms
/ #
 
[root@k8s130 ~]# docker run -it --network oll --name xujin02 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
    link/ether 02:42:c0:a8:06:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.6.2/24 brd 192.168.6.255 scope global eth0
       valid_lft forever preferred_lft forever
9: eth1@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # ping 192.168.6.1
PING 192.168.6.1 (192.168.6.1): 56 data bytes
64 bytes from 192.168.6.1: seq=0 ttl=64 time=1.245 ms
^C
--- 192.168.6.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.245/1.245/1.245 ms
/ # ping baidu.com
PING baidu.com (220.181.38.148): 56 data bytes
64 bytes from 220.181.38.148: seq=0 ttl=127 time=35.268 ms
^C
--- baidu.com ping statistics ---
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 35.268/35.268/35.268 ms
/ #

 原理图:(来源互联网强哥)

 

容器mac会变吗 容器 mac地址_docker_03

 扩展:

#查看网络命名空间namespace
容器的网络环境隔离,就是靠网络命名空间隔离的
[root@k8s130 ~]# cd /var/run/docker/netns/
[root@k8s130 netns]# ls
256cde1c8c4e  2-be79115dff
[root@k8s130 netns]# ln -s /var/run/docker/netns/  /var/run/netns   # 默认是看不到网络命名空间,需要做一个软连接
[root@k8s130 netns]# ip netns
256cde1c8c4e (id: 0)
2-be79115dff (id: 1)
[root@k8s130 netns]# ip netns exec 2-be79115dff /bin/bash  #进入网络命名空间
[root@k8s130 netns]# ifconfig   # 此时会发现有个vxlan0,还有一个bro的网络,结合上图就好理解了
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 192.168.6.254  netmask 255.255.255.0  broadcast 192.168.6.255
        ether 0e:15:bd:9d:12:a5  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
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        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
 
veth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        ether 0e:15:bd:9d:12:a5  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
 
vxlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        ether ba:c0:e6:bc:58:7d  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
 
#在129上面也进入命令空间。也会发现vxlan0,就是这个实现了两个宿主机的容器间的互联

 

运维