Docker跨主机网络-overlay

13 篇文章 1 订阅
13 篇文章 0 订阅

一、前言Docker网络

 

1、单 Docker Host 容器通信网络方案

none、host、bridge 和 joined 容器

2、跨主机容器间通信网络方案

A、Docker 原生 Network 的 overlay 和 macvlan

B、第三方方案常用的有 flannel、weave 和 calico

N方案如何与 Docker 集成

利用: libnetwork 以及 CNM

2.1、libnetwork & CNM

libnetwork 是 Docker 容器网络库

Container Network Model (CNM)是libnetwork的核心,对容器网络抽象化,由以下三类组件组成:

Sandbox

Sandbox 是容器的网络栈,包含容器的 interface、路由表和 DNS 设置

Linux Network Namespace 是 Sandbox 的标准实现

Sandbox 可以包含来自不同 Network 的 Endpoint

Endpoint

Endpoint 作用是将 Sandbox 接入 Network

Endpoint 典型实现是 veth pair

1个 Endpoint 只能属于一个网络,且只能属于一个 Sandbox

Network

Network 包含一组 Endpoint

同1个 Network 的 Endpoint 可直接通信

Network 的实现可以是 Linux Bridge、VLAN 等

CNM 示例:

如上图所示:

2个容器,1个容器1个 Sandbox,每个 Sandbox 都有1个 Endpoint 连接到 Network 1,第2个 Sandbox 还有1个 Endpoint 是接入到了 Network 2

libnetwork CNM 定义了 Docker Container的网络模型,按照该模型开发出的 driver 能与 docker daemon 协同工作,实现Container Network

Docker 原生的 driver 包括 none、bridge、overlay 和 macvlan

第三方 driver 包括 flannel、weave、calico 等

 

二、Docker Overlay Network 环境

Docker 提供了 overlay driver,可创建基于 VxLAN 的 overlay 网络

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

什么是overlay网络

overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密,当我们初始化一个swarm或是加入到一个swarm中时,在docker主机上会出现两种网络:

第一种、称为ingress的overlay网络

用于传递集群服务的控制或是数据消息,若在创建swarm服务时没有指定连接用户自定义的overlay网络,将会加入到默认的ingress网络

第二种、名为docker_gwbridge桥接网络

docker_gwbridge桥接网络会连接swarm中所有独立的docker系统进程

可以使用docker network create创建自定义的overlay网络,容器以及服务可以加入多个网络,只有同一网络中的容器可以相互交换信息,可以将单一容器或是swarm服务连接到overlay网络中,但是两者在overlay网络中的行为会有所不同,接下来会描述两者在overlay网络中的共同行为以及不同行为

注意事项:

如果想要连接到overlay网络,请确保连接前下列端口没有服务,并且服务器防火墙要允许下列端口通过:

TCP端口2377,用于集群管理信息的交流

TCP、UDP端口7946用于集群中节点的交流

UDP端口4789用于overlay网络中数据报的发送与接收

1、搭配key-value 数据库

Docerk overlay 网络需要1个 key-value 数据库保存网络状态信息,包括 Network、Endpoint、IP 等

Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,此处使用 Consul

2、环境描述

使用docker-machine 创建的实验环境

  1. 跨主机的2台Docker 主机

Docker 主机 host02(192.168.233.144)和 host03(192.168.233.145)上实践各种跨主机网络方案

B、部署组件

主机 docker-centos (192.168.233.143) 上部署支持的组件,如: Consul

简单方式--容器方式运行 Consul

Consul可以用来实现分布式系统的服务发现与配置,它是HashiCorp公司推出的一款实用开源工具,支持Linux等平台。Consul是分布式的、高可用的、可横向扩展的。

Consul具备的特性

服务发现: Consul提供了通过DNS或者HTTP接口的方式来注册服务和发现服务。一些外部的服务通过Consul很容易的找到它所依赖的服务。

健康检测: Consul的Client提供了健康检查的机制,可以通过用来避免流量被转发到有故障的服务上。

Key/Value存储: 应用程序可以根据自己的需要使用Consul提供的Key/Value存储。Consul提供了简单易用的HTTP接口,结合其他工具可以实现动态配置、功能标记、领袖选举等等功能。

多数据中心: Consul支持开箱即用的多数据中心. 这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。

执行指令:

docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap

docker run -d \

--restart="always" \

-p="8500:8500" \

-hostname="consul" \

--name="consul" \

progrium/consul  -server  -bootstrap

访问 Consul

http://192.168.233.143:8500

C、修改 docker daemon 配置文件

host02 和 host03 配置文件

cat /etc/systemd/system/docker.service.d/10-machine.conf

实际内容:Docker version 19.03.11

vi  /etc/systemd/system/docker.service.d/10-machine.conf

追加

--cluster-store=consul://192.168.233.143:8500   --cluster-advertise=ens33:2376

 

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --storage-driver overlay2 --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic  --cluster-store=consul://192.168.233.143:8500   --cluster-advertise=ens33:2376

配置解析:

--cluster-store 指定 consul 的地址

--cluster-advertise 告知 consul 自己的连接地址

 

D、重启 docker daemon

systemctl status docker.service

systemctl daemon-reload  

systemctl restart docker.service

systemctl status docker.service

 

 

E、观察结果

host02 和 host03 将自动注册到 Consul 数据库中

 

三、创建 overlay 网络

1、在 host02 服务器上创建 overlay 网络 overlay_net01

docker  network  create  -d  overlay  overlay_net01

-d  overlay  指定 driver 为 overlay

2、host03上查看当前网络

docker  network  ls  

原理解释:

host03 上也能看到 overlay_net01,因为创建 overlay_net01 时 host02 将 overlay 网络信息存入了 consul,host03 从 consul 读取到了新网络的数据。之后 overlay_net01 的任何变化都会同步到 host02 和 host3

3、查看 overlay_net01 的详细信息

docker  network  inspect  overlay_net01

docker  network  inspect  overlay_net01

[

    {

        "Name": "overlay_net01",

        "Id": "9ebb22fd5d745f1c8715032c4e76053603c31045accbddf1308d2444b89c259a",

        "Created": "2020-06-16T16:53:00.071749316+08:00",

        "Scope": "global",

        "Driver": "overlay",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": {},

            "Config": [

                {

                    "Subnet": "10.0.0.0/24",

                    "Gateway": "10.0.0.1"

                }

            ]

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {},

        "Options": {},

        "Labels": {}

    }

]

IPAM 是指 IP Address Management,docker 自动为 overlay_net01 分配的 IP 空间为 10.0.0.0/24

 

四、在 overlay 中运行容器

1、在host02上,运行1个 busybox 容器并连接到 overlay_net01

docker  run  -itd  --name  busybox-01  --network  overlay_net01  busybox

2、查看容器网络配置

docker  exec  busybox-01  ip  r

busybox-01 有两个网络接口 eth0 和 eth1

eth0 IP 为 10.0.0.2,连接的是 overlay 网络 overlay_net01

eth1 IP 172.17.0.2,容器的默认路由是走 eth1,eth1 是哪儿来的呢?

其实,docker 会创建一个 bridge 网络 “docker_gwbridge”,为所有连接到 overlay 网络的容器提供访问外网的能力

3、查看 docker_gwbridge 详情信息

docker  network  inspect  docker_gwbridge

docker  network  inspect  docker_gwbridge

[

    {

        "Name": "docker_gwbridge",

        "Id": "192f1d193f83f81c836842b0a339e5097e04aaf3341c2f7909d913335ac194dc",

        "Created": "2020-06-16T17:23:20.698017508+08:00",

        "Scope": "local",

        "Driver": "bridge",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": [

                {

                    "Subnet": "172.18.0.0/16",

                    "Gateway": "172.18.0.1"

                }

            ]

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {

            "42fbbcdeacd351701163986bc920f5e70af72f8d72d9d4d36817d8120c3a90f5": {

                "Name": "gateway_297bdad64327",

                "EndpointID": "adf1f97c040f78792e0ea94db272ddfccc276e5ec77e6f891a1d639a423d8997",

                "MacAddress": "02:42:ac:12:00:02",

                "IPv4Address": "172.18.0.2/16",

                "IPv6Address": ""

            }

        },

        "Options": {

            "com.docker.network.bridge.enable_icc": "false",

            "com.docker.network.bridge.enable_ip_masquerade": "true",

            "com.docker.network.bridge.name": "docker_gwbridge"

        },

        "Labels": {}

    }

]

IP 地址范围是 172.18.0.0/16,当前连接的容器就是 busybox-01  (172.18.0.2)

172.18.0.0/16网络的网关就是网桥 docker_gwbridge 的 IP 172.18.0.1

ifconfig   docker_gwbridge

4、验证与外网的连通性

A、访问外网

容器 busybox-01 就可通过 docker_gwbridge 访问外网

docker  exec  busybox-01  ping  -c  3  www.baidu.com

B、外网访问容器

如果外网要访问容器,可通过主机端口映射,比如:

docker  run  -p  80:80  -d  --net overlay_net01  --name web1  httpd

五、overlay 实现跨主机通信--连通性

1、在 host03 中运行容器 busybox-02

docker  run  -itd  --name  busybox-02  --network  overlay_net01  busybox

docker  exec  busybox-02  ip  r

【问题记录】创建容器时,报:docker: Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on 144.144.144.144:53: read udp 192.168.233.149:41512->144.144.144.144:53: i/o timeout.

【解决方法】vi /etc/docker/daemon.json

{

"registry-mirrors":["https://49c47s26.mirror.aliyuncs.com"]

}

systemctl restart docker

2、host03上的busybox-02与host02上的busybox-01网络

busybox-02 IP 为 10.0.0.4,可以直接 ping busybox-01

docker  exec  busybox-02  ping  -c 3 busybox-01

docker  exec  busybox-02  ping  -c 3 10.0.0.2

overlay 网络中的容器可以直接通信,同时 docker 也实现了 DNS 服务

3、overlay 网络的具体实现

docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 Linux bridge br0,endpoint 还是由 veth pair 实现,一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上

br0 除了连接所有的 endpoint,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的

4、查看 overlay 网络的 namespace

在 host02 和 host03 上执行 ip netns(请确保在此之前执行过 ln -s /var/run/docker/netns /var/run/netns),可以看到两个 host 上有一个相同的 namespace “1-9ebb22fd5d

ln -s /var/run/docker/netns /var/run/netns

ip netns

[root@host02 ~]# ip netns

ae08955cc1c2 (id: 1)

1-9ebb22fd5d (id: 0)

[root@host03 ~]# ip netns

e5d25e449779 (id: 1)

1-9ebb22fd5d (id: 0)

5、查看 namespace 中的 br0 上的设备

这就是 overlay_net01 的 namespace

ip  netns  exec  1-9ebb22fd5d  brctl  show

可见 namespace 中的 br0 上的设备vxlan0

【问题记录】[root@host02 ~]# ip  netns  exec  1-9ebb22fd5d  brctl  show

exec of "brctl" failed: No such file or directory

【解决方法】先安装

yum install -y bridge-utils

6、查看 vxlan0 设备的具体配置信息

ip  netns  exec 1-9ebb22fd5d  ip  -d  l  show  vxlan0

可见 overlay 使用的 VNI(VxLAN ID)为 256

vxlan0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UNKNOWN mode DEFAULT group default

    link/ether 66:48:73:e2:77:52 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 1

    vxlan id 256 srcport 0 0 dstport 4789 proxy l2miss l3miss ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx

bridge_slave state forwarding priority 32 cost 100 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8001 port_no 0x1 designated_port 32769 designated_cost 0 designated_bridge 8000.66:48:73:e2:77:52 designated_root 8000.66:48:73:e2:77:52 hold_timer    0.00 message_age_timer    0.00 forward_delay_timer    0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

 

六、overlay 的网络隔离特性

不同的 overlay 网络是相互隔离的

1、创建第二个 overlay 网络 overlay_net02 并运行容器 busybox-03

docker  network  create  -d  overlay  overlay_net02

docker  run  -itd  --name  busybox-03  --network  overlay_net02  busybox

docker  exec  -it  busybox-03  ip  r

busybox-03 分配到的 IP 是 10.0.1.2,尝试 ping busybox-01(10.0.0.2)

docker  exec  -it  busybox-03  ping  -c  3  10.0.0.2

可见:overlay_net02 中的 busybox-03 ping overlay_net01 中的 busybox-01 失败,可见不同 overlay 网络之间是隔离的。即便是通过 docker_gwbridge 也不能通信

2、实现 busybox-03 与 busybox-01 通信

将 busybox-03 也连接到 overlay_net01

docker  network  connect  overlay_net01  busybox-03

尝试再次 ping busybox-03

docker  exec  -it  busybox-03  ping  -c  3  busybox-01

3、指定overlay 网络 IP 空间

overlay IPAM

docker 默认为 overlay 网络分配 24 位掩码的子网(10.0.X.0/24),所有主机共享这个 subnet,容器启动时会顺序从此空间分配 IP

--subnet 指定 IP 空间

docker  network  ls

docker network create -d overlay --subnet 10.10.1.0/24 overlay_net03

4、查看 overlay_net03 详情

docker network inspect overlay_net03

[root@host02 ~]# docker network inspect overlay_net03

[

    {

        "Name": "overlay_net03",

        "Id": "beb14c4386f9f947754531c5ee53c054cbcc9a6b8f63a6d954f27db824ebf7c1",

        "Created": "2020-06-21T02:31:05.632006303+08:00",

        "Scope": "global",

        "Driver": "overlay",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": {},

            "Config": [

                {

                    "Subnet": "10.10.1.0/24"

                }

            ]

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {},

        "Options": {},

        "Labels": {}

    }

]

详情请见,微信公众号

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值