乐趣区

Docker Swarm部署应用的总结

原文
大纲
本文只是一种实际部署方案的例子,涉及到的技术有(除 Docker/Docker Swarm 外):

Docker overlay network

Fluentd
Prometheus stack
vegasbrianc 的 Prometheus 监控方案

步骤大纲:

部署 Docker machine

基本配置
配置网络
启动 Fluentd 日志服务

部署 Docker swarm 集群

配置网络
添加 Node

部署 Prometheus stack

给 Node 打 Label
创建监控网络
启动 service

部署应用

识别 stateless 与 stateful
创建应用网络
给 Node 打 Label
启动 service

1 部署 Docker machine
1.1 基本配置
准备若干 Linux 服务器(本例使用 Ubuntu 16.04),参照 Docker CE 镜像源站提到的步骤安装 Docker CE。
参照 Docker Daemon 生产环境配置。
1.2 配置 bridge 网络
参照 Docker Daemon 生产环境配置中的 mtu 和子网章节。
1.3 启动 Fluentd 日志服务
参考使用 Fluentd 收集 Docker 容器日志。
2 部署 Docker swarm 集群
到一台机器上执行 docker swarm init,这个机器将作为 manager node。
执行 docker node ls 会看到类似下面的结果:
$ docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader
如果你计划不会把工作负载跑在 manager node 上,那么使用 docker drain:
docker node update –availability drain <node-id>
可参考 Docker Swarm 基本命令清单。
2.1 配置网络 MTU 和子网
参考 Docker Overlay 网络的 MTU。
特别注意
观察 docker_gwbridge 和 ingress 的子网是否与已有网络冲突:
$ docker network inspect -f ‘{{json .IPAM}}’ docker_gwbridge
{“Driver”:”default”,”Options”:null,”Config”:[{“Subnet”:”172.18.0.0/16″,”Gateway”:”172.18.0.1″}]}

$ docker network inspect -f ‘{{json .IPAM}}’ ingress
{“Driver”:”default”,”Options”:null,”Config”:[{“Subnet”:”10.255.0.0/16″,”Gateway”:”10.255.0.1″}]}
如果有冲突则参考 Docker Overlay 网络的 MTU 中的方法修改子网。
2.2 添加 Node
参考 Docker Swarm 基本命令清单。
3 部署 Prometheus stack
使用的是 vegasbrianc 的 Prometheus 监控方案。
整个监控方案包含一下几个组件:

Prometheus
Node-exporter,运行在每个 node 上
Alertmanager
cAdvisor,运行在每个 node 上
Grafana

3.1 给 Node 打 Label
挑选一台 Node 作为运行监控服务的机器。给这个 node 打上 label:
$ docker node update –label-add for-monitor-stack=1 <node-id>
3.2 创建监控网络
$ docker network create -d overlay –attachable monitor-net
参考参考 Docker Overlay 网络的 MTU 检查子网与 MTU 是否配置正确。
3.3 启动 service
clone vegasbrianc 的 Prometheus 监控方案 项目代码。
使用我修改过的 docker-stack.yml
启动 service:
$ docker stack deploy \
–with-registry-auth \
–prune \
-c docker-stack.yml \
p8s-monitor-stack
访问地址:

Prometheus:http://< 任意 swarm node ip>:9000

Node-exporter:http://< 任意 swarm node ip>:9010

Alertmanager:http://< 任意 swarm node ip>:9020

cAdvisor:http://< 任意 swarm node ip>:9030

Grafana:http://< 任意 swarm node ip>:9040,用户名 admin,密码 foobar

4 部署应用
4.1 识别 stateless 与 stateful
如果你的应用由多个组件(service)组成,那么在部署它们之前你得识别出哪些是 stateless service 哪些是 stateful service。
针对每个 service 你自问以下三个问题:

这个 service 崩溃之后,是不是只需要重启它就可以了,而不需要关心数据恢复?
这个 service 是否可以在 node 之间任意迁移,且不需要分布式存储?
这个 service 是否无需固定 IP?

如果上述回答都是 Yes,那么这个 service 就是 stateless 的,只要有一个是 No,则这个 service 是 stateful 的。
对于 stateless service,你可以:

用 docker stack deploy 部署
用 docker service create 部署

对于 stateful service,你可以:

用 docker run 部署
用 docker-compose up 部署
如果没有固定 IP 的要求,那么你也可以用 docker stack deploy/docker service create 部署,前提是你得保证这个 service 只会固定在一台机器上运行。

有时候你的应用既有 stateless service 又有 stateful service,这时需要把他们挂载到同一个 overlay 网络里,这样它们之间就能够互相通信了。
4.2 创建应用网络
创建 app-net(你也可以改成自己的名字)
$ docker network create -d overlay –attachable app-net
参考 Docker Overlay 网络的 MTU 检查子网与 MTU 是否配置正确。
4.3 给 Node 打 Label
如果你对于 Service 部署在哪个 Node 上有要求,那么你得给 Node 打上 Label:
$ docker node update –label-add <your-label>=1 <node-id>
然后在 docker-compose.yaml 里添加约束条件:
version: “3.7”
services:
busybox:
image: busybox
deploy:
placement:
constraints:
– node.labels.<your-label> == 1
4.4 启动 service
对于 stateless service,编写 docker-compose.yaml,里面写了同时挂载 app-net 和 monitor-net,比如:
version: “3.7”
services:
busybox:
image: busybox
networks:
app-net:
monitor-net:
aliases:
– busybox

networks:
app-net:
external: true
monitor-net:
external: true
注意上面设置了 busybox service 在 monitor-net 中的别名,这是因为如果你用 docker stack deploy 部署,那么 busybox 的名字默认是 <stack-name>_busybox,这样对于 prometheus 而言此名字不稳定,不便于配置详见 Prometehus 监控 Docker Swarm Overlay 网络中的容器。
然后用 docker stack deploy 部署:
$ docker stack deploy \
–with-registry-auth \
–prune \
-c docker-compose.yaml
<stack-name>
如果用 docker service create 则:
$ docker service create \
–network app-net \
–network monitor-net \
–name <name> \
… 其他参数
<image>
下面举例 docker run 启动 stateful service 的方法:
$ docker run -d \
–name <name> \
–network app-net \
… 其他参数 \
<image>

# 然后再挂载到 monitor-net 上
$ docker network connect monitor-net <name>

退出移动版