美文网首页docker知识库
Docker 网络-高级网络夸主机容器之间的通信 Etcd 实战

Docker 网络-高级网络夸主机容器之间的通信 Etcd 实战

作者: 运维开发_西瓜甜 | 来源:发表于2018-12-18 14:03 被阅读106次
    实验网络示意图
    • docker-node1docer-node2 是 Etcd 的成员,并且都安装了 Docker
    • redis-clientredis 分别是宿主机 docker-node1docer-node2 的容器实例
    • 每个 Docker 宿主机上,都创建了名为 overlay_netoverlay network

    宿主机操作系统: CentOS Linux release 7.6.1810 (Core)
    Docker CE:
    Version: 18.09.0
    API version: 1.39 (minimum version 1.12)

    下面就来一步一步的实现。

    1. 搭建Etcd Cluster

    这里仅仅是为了演示Doker 夸主机通信目的而搭建及其简单的 Etcd 集群,不可用于生产。

    简单介绍

    这将调出etcd侦听端口2379以进行客户端通信,并在端口2380上进行服务器到服务器通信。

    etcd是一个分布式可靠的键值存储,用于分布式系统的最关键数据,重点是:

    • 简单:面向用户定义明确的API(gRPC)
    • 安全:具有可选客户端证书身份验证的自动TLS
    • 快速:基准测试10,000次/秒
    • 可靠:使用Raft正确分布

    etcd是用Go编写的,使用Raft一致性算法来管理高度可用的复制日志。

    Etcd 的监听端口

    • 2380 用于集群成员之间的通信
    • 2379 用于监听客户端的请求

    下载

    官方提供了二进制包 https://github.com/etcd-io/etcd/releases/
    可以根据自己的系统进行有选择的下载。

    本测试环境下载的是适合 Linux 64位系统环境的包


    image.png

    Etcd 机器信息

    主机名 IP
    docker-node1 192.168.60.10
    docker-node2 192.168.60.20

    a. docker-node1 的操作

    下载解压

    [vagrant@docker-node1 ~]$ wget https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
    [vagrant@docker-node1 ~]$ tar -xf etcd-v3.3.10-linux-amd64.tar.gz
    [vagrant@docker-node1 ~]$ cd etcd-v3.3.10-linux-amd64/
    [vagrant@docker-node1 etcd-v3.3.10-linux-amd64]$
    

    后台启动运行

    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE1_IP=192.168.60.10
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE2_IP=192.168.60.20
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE1_NAME=docker-node1
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE2_NAME=docker-node2
    [vagrant@docker-node1 etcd-v3.3.10-linux-amd64]$ nohup ./etcd \
     --name ${NODE1_NAME} \
      --initial-advertise-peer-urls http://${NODE1_IP}:2380 \
      --listen-peer-urls http://${NODE1_IP}:2380 \
      --listen-client-urls http://${NODE1_IP}:2379,http://127.0.0.1:2379 \
      --advertise-client-urls http://${NODE1_IP}:2379 \
      --initial-cluster-token etcd-cluster-1 \
      --initial-cluster ${NODE1_NAME}=http://${NODE1_IP}:2380,${NODE2_NAME}=http://${NODE2_IP}:2380 \
      --initial-cluster-state new &
    
    • –name 节点名称
    • –initial-advertise-peer-urls 告知集群其他节点自己的URL,tcp2380端口用于集群通信
    • –listen-peer-urls 监听URL,用于与其他节点通讯
    • –advertise-client-urls 告知客户端的URL,tcp2379端口用于监听客户端请求
    • –initial-cluster-token 集群的ID
    • --initial-cluster-token # 集群 token,用于成员之间认证
    • –initial-cluster 集群中所有节点
    • –initial-cluster-state 集群状态,new为新创建集群,existing为已存在的集群

    b. docker-node2 的操作

    下载解压

    [vagrant@docker-node2 ~]$ wget https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
    [vagrant@docker-node2 ~]$ tar -xf etcd-v3.3.10-linux-amd64.tar.gz
    [vagrant@docker-node2 ~]$ cd etcd-v3.3.10-linux-amd64/
    

    后台启动运行

    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE1_IP=192.168.60.10
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE2_IP=192.168.60.20
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE1_NAME=docker-node1
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ export NODE2_NAME=docker-node2
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ nohup ./etcd \
    --name ${NODE2_NAME} \
    --initial-advertise-peer-urls http://${NODE2_IP}:2380 \
      --listen-peer-urls http://${NODE2_IP}:2380 \
      --listen-client-urls http://${NODE2_IP}:2379,http://127.0.0.1:2379 \
      --advertise-client-urls http://${NODE2_IP}:2379 \
      --initial-cluster-token etcd-cluster-1 \
      --initial-cluster ${NODE1_NAME}=http://${NODE1_IP}:2380,${NODE2_NAME}=http://${NODE2_IP}:2380 \
      --initial-cluster-state new &
    

    集群健康检查

    分别在每个成员中执行如下命令

    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ ./etcdctl cluster-health
    member d860400699ce61e is healthy: got healthy result from http://192.168.60.10:2379
    member f96c6ec64b2090e3 is healthy: got healthy result from http://192.168.60.20:2379
    cluster is healthy
    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$
    

    返回 cluster is healthy 说明正常。

    查看集群成员

    在任意节点上运行

    [vagrant@docker-node2 etcd-v3.3.10-linux-amd64]$ ./etcdctl  member  list
    d860400699ce61e: name=docker-node1 peerURLs=http://192.168.60.10:2380 clientURLs=http://192.168.60.10:2379 isLeader=true
    f96c6ec64b2090e3: name=docker-node2 peerURLs=http://192.168.60.20:2380 clientURLs=http://192.168.60.20:2379 isLeader=false
    

    集群正常后,接下来就可以对 Docker 进行配置了

    关于 Etcd 的更多配置参考官方文档

    2. 配置 Docker 使用 Etcd

    分别在两台宿主机上停止 dockerd 服务。
    这里一 systemd 为例

    sudo systemctl stop docker
    

    docker-node1 上执行

    sudo dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://${NODE1_IP}:2379 --cluster-advertise=${NODE1_IP}:2375 &
    

    docker-node2 上执行

    sudo dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://${NODE2_IP}:2379 --cluster-advertise=${NODE2_IP}:2375 &
    

    在其中的一个节点上创建 overlay network

    1. 这里我在 docker-node1 上创建名字为: overlay_net 的覆盖网络
    docker@docker-node1:~$ docker network create -d overlay  overlay_net
    833aa03d003739bf1f5802f8c1ebe0ae617e02e46b09000c03b348b66e1e27c5
    docker@docker-node1:~$ docker network inspect overlay_net
    [
        {
            "Name": "overlay_net",
            "Id": "833aa03d003739bf1f5802f8c1ebe0ae617e02e46b09000c03b348b66e1e27c5",
            "Created": "2018-12-16T01:52:28.046320149Z",
            "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": {}
        }
    ]
    
    1. 之后在 docker-node2 上查看网络信息
    docker@docker-node2:~$ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    31e870259bb0        bridge              bridge              local
    ee8cec8939af        host                host                local
    8d6c3e3ceb94        none                null                local
    833aa03d0037        overlay_net         overlay             global
    docker@docker-node2:~$
    

    可以看到在一个节点上创建的网络信息,可以同步到集群中的所有节点上。

    运行容器并将其连接到 overlay_net 网络中

    1. docker-node1 运行容器 redis-client
    docker@docker-node1:~$ sudo docker run -itd --rm --name=redis-client --network=overlay_net  python:3.6-alpine
    65bc05e3801242b2e917775d079a15272a926dab0e38b8039564f50547bef770
    ERRO[0000] enabling default vlan on bridge br0 failed open /sys/class/net/br0/bridge/default_pvid: permission denied
    ERRO[2018-12-16T01:59:00.903303768Z] reexec to set bridge default vlan failed exit status 1
    INFO[0839] shim containerd-shim started                  address="/containerd-shim/moby/65bc05e3801242b2e917775d079a15272a926dab0e38b8039564f50547bef770/shim.sock" debug=false pid=4668
    

    这里的错误信息暂时没解决

    1. docker-node2 运行容器 redis
    docker@docker-node2:~$ sudo docker run -itd --rm --name=redis --network=overlay_net redis:alpine
    58b6cf076675f005d0a0d944fd85762bfe0a6e0bf8a63f94fac3e65d9f74e955
    ERRO[0000] enabling default vlan on bridge br0 failed open /sys/class/net/br0/bridge/default_pvid: permission denied
    ERRO[2018-12-16T01:59:56.673683047Z] reexec to set bridge default vlan failed exit status 1
    INFO[0781] shim containerd-shim started                  address="/containerd-shim/moby/58b6cf076675f005d0a0d944fd85762bfe0a6e0bf8a63f94fac3e65d9f74e955/shim.sock" debug=false pid=4729
    
    1. docker-node2 进入容器 redis 测试连通性
    docker@docker-node2:~$ docker exec -it redis sh
    /data # ping redis-client
    PING redis-client (10.0.0.2): 56 data bytes
    64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.989 ms
    64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.702 ms
    ^C
    --- redis-client ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.702/0.845/0.989 ms
    
    1. docker-node1 进入容器 redis-client 测试连通性
    docker@docker-node1:~$ docker exec -it redis-client sh
    / # ping redis
    PING redis (10.0.0.3): 56 data bytes
    64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.998 ms
    64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.657 ms
    ^C
    --- redis ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.657/0.827/0.998 ms
    
    1. 最后在容器 redis-client 中安装 python3 用的 redis 模块,并且进行端口连通性测试
    / # pip3 install redis
    Collecting redis
      Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB)
        100% |████████████████████████████████| 71kB 115kB/s
    Installing collected packages: redis
    Successfully installed redis-3.0.1
    / # python3
    Python 3.6.7 (default, Nov 16 2018, 06:52:39)
    [GCC 6.4.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import redis
    >>> r = redis.Redis(host="redis", port=6379)
    >>> r.set("name", "shark")
    True
    >>> r.get("name")
    b'shark'
    >>> exit()
    / # exit
    docker@docker-node1:~$
    

    相关文章

      网友评论

        本文标题:Docker 网络-高级网络夸主机容器之间的通信 Etcd 实战

        本文链接:https://www.haomeiwen.com/subject/qsughqtx.html