背景
之前寫過<<docker-compose真香>> 和《docker-compose、docker stack前世今生》兩篇博客, 回顧一下思路:
① docker-compose是docker引擎頂層的容器編排工具(Python實現),需要單獨安裝; docker stack 是docker引擎原生支持的容器編排技術(Go實現)
② 兩者都支持最新docker-compose.yml 版本3容器編排文件,部分指令有差異。
③ docker-compose 能現場Build鏡像,更適用於開發、測試時候單機迭代部署;docker stack須預先准備鏡像,具備生產環境諸多特性。
昨天docker-compose編排的單機多容器突然崩潰,為提高項目服務可用性評價值(SLA), 決心切換到docker stack生產部署。
Docker Swarm優勢
Docker Swarm is native clustering for Docker. It turns a pool of Docker hosts into a single, virtual Docker host.
Docker Swarm是Docker平台原生內置的集群編排技術,它將Docker主機池變成了 單個虛擬主機。
有很多理由促使你采用容器集群解決方案。隨着應用程序的增長,將面臨新的強制要求:例如可伸縮性,可管理性和高可用性。
Docker Swarm 直接優勢:
-
Native Clustering
-
Production Grade
-
Work out of the box
-
Easy to setup and use
-
Active Community
高可用支撐生產業務
Stack、Service、Container 金字塔模型定義了一個完整的生產應用架構:
- task是Docker Swarm中最小部署單位,task與容器Container是一對一的關系
-
service是一個或一組容器在生產環境的預期狀態(也可說是一組task的集合),在Worker節點上執行;有兩種模式(對應下面docker-stack.yml-deploy-mode配置節)
- (默認)replicated: 指定容器數量
- global: 每個節點一個容器(容器數量由可用節點決定)
-
stack 是一組服務,協作支撐整個業務
部署策略
還支持 副本集、滾動更新、更新和回滾策略,以上配置都可以在docker-compose.yml 版本3官方文檔找到對應的配置字段:
deploy: endpoint_mode: 服務發現的方式: vip,dnsrr labels: 為服務指定的標簽 mode:replicated (指定數量的容器) global(每個節點一個容器) replicas: 實例數量 resources: 配置資源 restart_policy: 重啟策略 update_config: 服務更新策略 parallelism: 同時更新容器數量 delay: 容器組更新的間隔時間 failure_action: 更新失敗的操作:continue、rollbak,pause(默認) monitor: 監視更新失敗的等待時間 max_failure_ratio: 更新的失敗容錯率 order:操作策略:stop-first(先停止某容器,再創建新容器)、start-first (先創建新容器,所以會與即將消滅的容器有時間重疊) rollback_config: 回滾策略 ...同上...
集群多節點部署
Docker Swarm在以多主機模型支撐業務,對於開發者/部署者來說, 一個節點或多節點部署的配置流程是類似的。
有兩種形式節點: managers,workers
managers節點
- 維護集群狀態
使用Raft協議保持集群內部一致性;
測試目的,可以使用單個manager運行swarm;(單manager fail, 服務繼續運行)
- 調度服務
- 支撐swarm mode HTTP endpoints
workers節點
workers節點的唯一目的是執行容器,workers節點不參與Raft distributed state, make scheduling decisions, or serve the swarm mode HTTP API.
可以創建只有一個manager的群集,但是如果沒有一個manager節點,則不可能有一個工作節點。
默認情況下,所有manager也是worker。在單個manager節點集群中,您可以運行諸如docker service create之類的命令,而調度程序會將所有任務放在本地引擎上。
Load Balancing
+ https://docs.docker.com/engine/swarm/key-concepts/#services-and-tasks
ingress load balancing
作用在外部要訪問的服務上,一般服務會對外暴露一個port,(如果你沒有指定的話,swarm manager會自動給這個服務分配一個PublishedPort )
外部Clients能在集群任一節點的PublishedPort 上訪問服務(不論這個節點當前是否有這個服務的running task)。
服務發現(這里自然說的是Docker Stack中某個對外暴露的服務),有兩種模式(對應docker-stack.yml: deploy---->endpoint_mode)
- vip: Docker Swarm為服務分配1個虛擬ip,服務后有多少節點、服務請求到哪個節點容器對於客戶端是透明的。 默認
- dnsrr: Docker Swarm 為服務建立DNS記錄,返回可用容器的ip列表, 客戶端直接請求其中一個ip, 這種方式一般用於自建負載均衡器
internal load balancing:
作用在每個服務上,swarm內部有一個DNS組件(自動為每個服務分配dns條目),swarm manager使用依據DNS名稱分發請求。
Docker Swarm網絡模型
① overlay network:覆蓋物網絡,顧名思義是附着在主機底層網絡之上的網絡, 這個網絡保證了不同主機之間容器通信
② ingress network:進入網絡,顧名思義是外部客戶端訪問服務時,服務節點間負載均衡(節點在開放端口上收到請求,上交給IPVS,選擇容器),是一種特殊的overlay網絡。
③ docker-gwbridge: 將overlay網絡連接到docker宿主機的網絡,默認: 服務正在運行的每個容器都連接到其本地Docker守護程序主機的docker_gwbridge網絡
在初始化或剛加入Swarm集群時,會創建一個Ingress和 docker-gwbridge網絡
單機走向集群部署
本次將<<docker-compose真香>> 3容器改造目標:
-
三個服務---->nginx----> receiver------>app,服務容器通過名為webnet 的overlay網絡通信;
-
nginx開放外部訪問端口80和8080,關注ingress網絡
-
receiver, app服務需要訪問宿主機上搭建的Redis, 關注docker-gwbridge網絡
一般兩個步驟: ① 搭建集群 ② 發布服務
搭建Docker Swarm集群
單節點/多節點的初始化方式,可參考 docker swarm -- help指令; 集群節點的管理可參考 docker node --help指令
$ docker swarm --help Usage: docker swarm COMMAND Manage Swarm Commands: ca Display and rotate the root CA init Initialize a swarm join Join a swarm as a node and/or manager join-token Manage join tokens, 如果忘記Token,可以執行這個參數 leave Leave the swarm unlock Unlock swarm unlock-key Manage the unlock key update Update the swarm
發布服務
可使用docker service create方式創建服務,我比較喜歡使用docker stack deploy搭配docker-stack.yml文件
下面是生產部署中追加的production.yml,創建了一個名為eqidstack_webnet的overlay網絡
version: "3.7" services: proxy: networks: - webnet receiver: deploy: replicas: 1 restart_policy: condition: on-failure networks: - webnet volumes: - type: bind source: /home/eqidmanager/receiver.secrets.json target: /app/appsettings.secrets.json app: deploy: replicas: 2 restart_policy: condition: on-failure update_config: parallelism: 1 delay: 5s order: stop-first networks: - webnet volumes: - type: bind source: /home/eqidmanager/appsettings.secrets.json target: /app/appsettings.secrets.json networks: webnet:
# docker stack不加載同目錄下的.env環境變量文件,原有適用於docker-compose工具的yml文件可采用變通方法
docker stack deploy -c <(docker-compose -f docker-stack.yml -f production.yml config) eqidstack
服務部署效果:
#docker stack ls: NAME SERVICES ORCHESTRATOR eqidstack 3 Swarm #docker service ls:
ID NAME MODE REPLICAS IMAGE PORTS (服務對外暴露的端口)
jml6ecfa330r eqidstack_app replicated 2/2 12205599/eqidmanager:master
3381stpkirgj eqidstack_proxy replicated 1/1 nginx:latest *:80->80/tcp, *:8080->8080/tcp
vhz4ef8p4ffp eqidstack_receiver replicated 1/1 12205599/eqidreceiver:master
可通過
docker network inspect ingress 驗證容器eqidstack_proxy.1 連接到ingress網絡;
docker network inspect eqidstack_webnet 驗證有4個容器連接到 overlay網絡
不停服更新/不停服擴容
手動更新服務配置:docker service update [opton] {some_service_name}
我們來為以上名為{eqidstack_proxy}的服務添加 [重啟策略]
手動擴容:docker service scale [option] {service=replicas}
為名為{eqidstack_proxy}的服務擴容為2容器
可通過docker service inspect eqidstack_proxy驗證操作結果
總結
docker service 定義某個(副本集)容器在生產環境下的狀態,一般業務含義上的服務相關;
docker stack 定義一組服務,服務間協作、調用,支撐整個業務架構;
docker swarm 管理一組服務在集群節點上的的部署
本文以 重難點解讀+實戰演練的方式記錄Docker Swarm生產部署的過程,希望能和大家查缺補漏,共同探討。
+ https://docs.docker.com/compose/compose-file/
+ https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/#manager-nodes
+ https://docs.docker.com/engine/swarm/key-concepts/#services-and-tasks
+ https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/