一、Docker Swarm上的容器選擇
並非所有服務都應該部署在Swarm集群內。數據庫以及其他有狀態服務就不適合部署在Swarm集群內。
理論上,你可以通過使用labels將容器部署到特定節點上,但是這樣的話,Swarm集群外的節點就很難訪問它們了(Docker 1.12沒有很好的方法,但是1.13之后可以使用attachable network)。
如果你允許集群外的節點訪問數據庫,則所有節點都可以訪問它,這顯然不符合你的需求。
另外,Docker Swarm的跨節點數據卷(cross-host mounted volumes)並不可靠,一個簡單的文件上傳都可能引起問題。
無狀態的容器就非常適合部署在Swarm集群中,它們可以由環境變量進行配置(使用ENV指令)。建議為開源工具構建鏡像,例如,可以將Nginx的配置文件放到Docker鏡像中。
在Swarm集群中的服務:
- Django channels (網頁應用)
- Nginx(代理)
- Celery(周期性任務)
- Sensu(監控)
在Swarm集群之外的容器:
- Mysql(數據庫)
- Redis(緩存)
由於一個獲取真正IP的問題,我很可能會將Nginx運行在Swarm集群之外,或者采用host模式。
二、設置資源限制
就經驗而言,可以為所有服務設置CPU使用限制。當某一個容器應用占用掉所有主機資源時,此限制可以避免這種情況發生。
當想把所有容器均勻地發布在所有主機上或是想確保有足夠的資源來響應操作時,需使用Reserve-cpu這個參數。
例如:
# 限制服務占用的CPU資源
docker service update
--limit-cpu 0.25
--reserve-cpu 0.1 webapp
三、將半無狀態的服務變得完全無狀態
所謂半無狀態服務,就是容器需要依賴一些不太重要的外部文件。你可以使用數據卷(volume),但是更好的選擇是使用S3或者其他雲存儲服務。
記住,想要獲得擴展性,雲是最好的選擇。
例如,我不得不構建Nginx鏡像,將配置文件放到鏡像中。使用數據卷掛載Nginx配置文件不是很方便。
四、創建可附加的網絡
network是一個非常重要的特性。你最好使用它,否則docker run
創建的容器將無法接入Swarm集群的網絡,特別是跨宿主機通訊時。
這是Docker 1.13之后的版本才有的功能,也許你需要升級。
創建network的命令如下:
docker network create --driver=overlay --attachable core
五、增加環境變量
如果創建Docker鏡像的時候,遵循了最佳實踐原則(https://rock-it.pl/how-to-wri...),允許在運行的時候通過環境變量設置一切配置項,那么把應用遷到Swarm的過程完全沒有問題。
相關命令:
# 創建服務時指定環境變量
docker service create \ --env VAR=VALUE \ --env-file FILENAME \ ...
# 增加、刪除環境變量 docker service update \ --env-add VAR=NEW_VALUE \ --env-rm VAR \ ..
六、設置適當實例和批量更新
保持適當數量的實例,以應對高流量和實例或者節點不可用的情況。同時太多的實例數也會占用CPU和內存,並且導致爭搶CUP資源。
update-parallelism的默認值是1,默認只有一個實例在運行。但這個更新速度太慢了,建議是 replicas / 2。
相關命令:
# 將同時更新的容器數設為10 docker service update \ --update-parallelism 10 \ webapp # 同時增加多個服務的容器數 docker service scale redis=1 nginx=4 webapp=20 # 查看服務狀態 docker service ls # 查看服務的詳情(排除關閉的容器) docker service ps webapp | grep -v "Shutdown"
七、把Swarm配置保存為代碼
最好使用Docker Compose v3版本的語法(https://docs.docker.com/compo...)。
他允許使用代碼指定幾乎所有的服務選項。作者在開發的時候使用 Docker-compose.yml,在生產環境(swarm)配置使用 Docker-compose.prod.yml . 部署Docker-compose文件中所描述的服務,需要Docker stack deploy 命令(屬於新版本 Stack命令集合中的一部分[https://docs.docker.com/engin...)
Docker compose v3例子:
version: '3' services: webapp: image: registry.example.com/webapp networks: - ingress deploy: replicas: ${WEBAPP_REPLICAS} mode: replicated restart_policy: condition: on-failure proxy: image: registry.example.com/webapp-nginx-proxy networks: - ingress ports: - 80:80 - 443:443 deploy: replicas: ${NGINX_REPLICAS} mode: replicated restart_policy: condition: on-failure networks: ingress: external: true
部署的例子(創建或者更新服務):
export NGINX_REPLICAS=2 WEBAPP_REPLICAS=5 docker login registry.example.com docker stack deploy \ -c docker-compose.prod.yml\ --with-registry-auth \ frontend
提示:Docker-compose文件支持環境變量 (${VARIABLE}), 所以,可以動態調整配置作為測試等。
八、配置日志收集服務
使用分布式系統時,集中管理日志是非常必要的。我們有很多方案,包括開源工具或者SaaS服務,比如ELK,Grafana, Graylog…自己搭建完整的系統是非常復雜的,所以我建議搭建先使用SaaS服務(比如Loggly, Logentries ),當費用太高時,則自己搭建一個系統。ELK可以這樣配置:
docker service update \
--log-driver gelf \ --log-opt gelf-address=udp://monitoring.example.com:12201 \ --log-opt tag=example-tag \ example-service
參考:https://www.cnblogs.com/fundebug/p/6823897.html