之前使用 rancher 做为我个人的 docker 容器管理引擎, rancher 在大部分时候都工作的很好. 但是 Rancher 1 将会在最早于明年夏天 (Rancher Forums) 结束支持, 因为 k8s 的占用过于庞大, 我因此不是很想转换到 rancher 2 上 (而且也不能平滑升级) 这时候就尝试试一下 swarm

swarm 真香

节点的部署

在 manager 机器上使用 docker swarm init 你将会得到用与加入 swarm 集群的命令 将这个命令在 worker 机器上执行就可以将机器加入集群了

注意事项

在 1:1 NAT 的机器上网络通信的问题

在某些 1:1 NAT 的机器上 (例如 Google Cloud / AWS) 上你可能会遇到这个问题, 问题具体表现为你加入集群之后是没问题的 但是节点之间 overlay 的 network 并不能跨机通信

答案: 在 docker swarm join 的时候加上 --advertise-addr 外网IP 这个 参数

创建服务

traefik

Traefik 是一个用使用 golang 编写的负载均衡 / 反向代理服务端, 可以通过 service 的 label 来配置外网的访问

首先创建文件夹

1mkdir -p /data/traefik
2touch acme.json  traefik.toml

然后编辑 /data/traefik/traefik.toml 这一个配置文件 以下为我的配置文件

 1debug = true
 2defaultEntryPoints = ["http", "https"]
 3
 4[web]
 5address = ":8080"
 6ReadOnly = true
 7  [web.auth.basic]
 8  users = ["Indexyz:$apr1$h7AhHWe1$I7OTEhwmTR5GUg1mPv6yS/"]
 9
10[entryPoints]
11  [entryPoints.http]
12  address = ":80"
13    [entryPoints.http.redirect]
14    entryPoint = "https"
15  [entryPoints.https]
16  address = ":443"
17  compress = true
18    [entryPoints.https.tls]
19
20[retry]
21
22[acme]
23email = "acme@indexyz.me"
24storage = "acme.json"
25entryPoint = "https"
26onHostRule = true
27[acme.httpChallenge]
28  entryPoint = "http"

使用以下命令来创建 traefik 服务

 1docker network create --driver overlay \
 2    --attachable \
 3    traefik
 4
 5docker service create --name traefik \
 6    --name traefik \
 7    --constraint=node.role==manager \
 8    --publish 80:80 \
 9    --publish 443:443 \
10    --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
11    --mount type=bind,source=/data/traefik/traefik.toml,target=/traefik.toml \
12    --mount type=bind,source=/data/traefik/acme.json,target=/acme.json \
13    --network traefik \
14    --label traefik.port=8080 \
15    --label traefik.frontend.rule=Host:traefik.indexyz.me \
16    --label traefik.docker.network=traefik \
17    --label 'traefik.frontend.auth.basic=Indexyz:$PASSWORD$' \
18    traefik \
19    --docker \
20    --docker.swarmmode \
21    --docker.domain=indexyz.me \
22    --docker.watch \
23    --web

将其中的 $PASSWORD$ 替换为 apr1 加密过的密码 (使用 openssl passwd --apr1)

docker-proxy

一些事件只能在 master 的 docker.sock 上监听到 因此很多应用都有部署到 manage 上的要求 我们可以使用 rancher/socat-docker 来将 master 的 docker.sock 在 tcp 上监听

利用以下命令来运行 docker-proxy

 1docker network create --driver overlay \
 2    --attachable \
 3    docker-proxy
 4
 5docker service create \
 6    --name docker-proxy \
 7    --mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
 8    --constraint 'node.role==manager' \
 9    --network docker-proxy \
10    rancher/socat-docker

Portainer

Portainer 是一个 可视化的 docker 管理器, 支持 swarm 集群的管理, 毕竟我们一直用命令行进行创建 service 比较麻烦

使用以下命令来创建 Portainer 服务

 1docker service create \
 2    --name portainer \
 3    --replicas=1 \
 4    --constraint 'node.role == manager' \
 5    --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
 6    --mount type=bind,src=/data/portainer,dst=/data \
 7    --label traefik.port=9000 \
 8    --label traefik.frontend.rule=Host:portainer.indexyz.me \
 9    --label traefik.docker.network=traefik \
10    --network traefik \
11    portainer/portainer \
12    -H unix:///var/run/docker.sock