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

实验网络示意图
  • 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:~$
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容