Docker Swarm部署應用的總結

原文

大綱

本文只是一種實際部署方案的例子,涉及到的技術有(除Docker/Docker Swarm外):

  1. Docker overlay network
  2. Fluentd
  3. Prometheus stack
  4. vegasbrianc的Prometheus監控方案

步驟大綱:

  1. 部署Docker machine

    1. 基本配置
    2. 配置網絡
    3. 啓動Fluentd日誌服務
  2. 部署Docker swarm集羣

    1. 配置網絡
    2. 添加Node
  3. 部署Prometheus stack

    1. 給Node打Label
    2. 創建監控網絡
    3. 啓動service
  4. 部署應用

    1. 識別stateless與stateful
    2. 創建應用網絡
    3. 給Node打Label
    4. 啓動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_gwbridgeingress的子網是否與已有網絡衝突:

$ 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監控方案

整個監控方案包含一下幾個組件:

  1. Prometheus
  2. Node-exporter,運行在每個node上
  3. Alertmanager
  4. cAdvisor,運行在每個node上
  5. 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你自問以下三個問題:

  1. 這個service崩潰之後,是不是只需要重啓它就可以了,而不需要關心數據恢復?
  2. 這個service是否可以在node之間任意遷移,且不需要分佈式存儲?
  3. 這個service是否無需固定IP?

如果上述回答都是Yes,那麼這個service就是stateless的,只要有一個是No,則這個service是stateful的。

對於stateless service,你可以:

  1. docker stack deploy部署
  2. docker service create部署

對於stateful service,你可以:

  1. docker run部署
  2. docker-compose up部署
  3. 如果沒有固定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-netmonitor-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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章