Docker 小記—Compose&Swarm
前言
任何相對完整的應用服務都不可能是由單一的程序來完成支持,計劃使用 Docker 來部署的服務更是如此。大型服務需要進行拆分,形成微服務集群方能增強其穩定性和可維護性。本篇隨筆將對 Docker Compose 和 Docker Swarm 的原理和配置做整理歸納,並分享其使用經驗。
1. YAML 簡介
Docker Compose 的配置文件採用 YAML 格式,因此有必要在正文之前簡要說明下。YAML 是一門專門用來寫配置文件的語言,設計目標就是方便讀寫,其實質上是一種通用的數據串列化格式,基本語法規則如下:
大小寫敏感。
表示注釋。
使用縮進表示層級關係。
縮進時不允許使用 Tab 鍵,只允許使用空格。
縮進的空格數目不重要,只要相同層級的元素左側對齊即可。
YAML 支持的數據結構有三種:
對象: 。
數組:一組中劃線開頭的行,例如:
值類型和字元串。
2. Docker Compose
2.1 安裝與簡介
Docker 可以極為方便地部署單個服務,但這時候我們需要一個工具來整合 Docker 的功能,使之能夠更便捷地去管理整個微服務集群的部署和遷移,Docker Compose 正是應此而生。他是由 Python 編寫的程序,能夠根據指令結合配置文件轉換成對應的 Docker API 的操作,並直接體現到 Docker Daemon 中,這就代替我們完成了重複輸入複雜指令的過程,主要功能可分為以下兩點:
Service:代表的是運行同種應用程序的一個或多個相同容器的抽象定義,也是我們在Docker Compose 中配置的主要對象。在每個 Docker Compose 的配置文件中,我們可以定義多個服務,並定義服務的配置,以及服務於服務之間的以來關係。
Project:代表的是由多個服務所組成的一個相對完整的業務單元。
安裝命令:
2.2 配置參數
Docker Compose 的核心就是其配置文件,採用 YAML 格式,默認為 ,參數詳解可查閱「官方文檔」,以下只做一個常規摘要。
services
所有服務的根節點。
image
指定服務的鏡像名,若本地不存在,則 Compose 會去倉庫拉取這個鏡像:
ports
埠映射,例:
volumes
掛載主機目錄,其中 ro 表示只讀,例:
大多數情況下集群中部署的應該都是無狀態服務,服務可複製且不固定在某一台宿主機,所以掛載的數據卷最好應當與宿主機脫離關係,例:
當然,這種情況下最好是優先創建數據卷,後在配置文件中引用,例:
若必須掛載集群中一台宿主機的目錄作為數據卷,則要安裝一個 docker 插件:
networks
配置服務間的網路互通與隔離,例:
secrets
配置服務密碼訪問,例:
healthcheck
健康檢查,這個非常有必要,等服務準備好以後再上線,避免更新過程中出現短暫的無法訪問。
其實大多數情況下健康檢查的規則都會寫在 Dockerfile 中:
depends_on
依賴的服務,優先啟動,例:
environment & env_file
設置環境變數和指定環境變數的文件,例:
deploy
部署相關的配置都在這個節點下,例:
若非特殊服務,以上各節點的配置能夠滿足大部分部署場景了。
3. Swarm
Docker 默認包含了 Swarm,因此可以直接使用,初始化命令: ,此時將會默認當前節點為 Leader,以下命令為查看 token: ,其他節點可以用 manager 或者 worker 的身份加入到當前集群,例:
執行 脫離集群。
以下各節點常規操作命令,比較簡單,就不解釋了:
docker node demote [NODE]
docker node inspect [NODE]
docker node ls
docker node promote [NODE]
docker node ps [NODE]
docker node rm [NODE]
docker node update [OPTIONS] NODE
4. 應用案例
集群最擅長的就是解決多服務問題,只要在同一 network 之下,服務之間默認可以直接通過 service_name 互通有無。但為了避免混亂,各服務與外部的通信最好統一交給一個反向代理服務轉發。因對 nginx 比較熟悉,所以我最初選擇的代理是「jwilder/nginx-proxy」:
負載均衡使用的是阿里雲的 SLB,監聽 ,這樣一個服務就實現了節點檢查、代理和 https 重定向為一身。拖 nginx 的福,反正用起來就是爽,點擊「Nginx 原理解析和配置摘要」進一步了解。
正所謂樂極生悲,某一次我在擴展 Swarm 集群的時候提升了部分 work 節點為 manager, 並且擴展了代理的數量,這讓很多服務頻繁出現 503,找來找去我發現問題出在 nginx-proxy 代理上。當服務在各節點分布不均的時候,非 leader 節點上的那個代理無法找到服務,廢了老大的勁兒也沒找到合理的解決方案。
最後我決定選擇「Docker Flow Proxy」作為新的代理(好傢夥,這一看文檔嚇我一跳,我還是第一次看到私人的開源項目能把參考文檔寫得這麼詳細,作者的細膩程度「令人髮指」,小弟頂禮膜拜之),以下是我的案例:
更換代理的過程也並非一帆風順,我在 https 重定向這個問題浪費了好多時間,最後也沒在代理中解決。作者當然是考慮到了這個問題,經典的解決方案應如下:
但奈何哥哥「非經典」呀,我的 https 證書和負載均衡都委託給阿里雲的 SLB 了,SLB 代理的後端請求只能限定 http。我的想法還是監聽所有請求 443 埠的域名並返回 301,但以下方案並沒有成功:
當然重定向可以在各服務內部實現,但我不認為這是個好的解決方案。最後的最後,我想反正遲早都要上 CND,於是就在 CND 中加了 https 重定向(哎,就是帶寬的費用要 double 咯...):
除了代理,最好再加一個監控服務,比如 visualizer ,配合 proxy 示例:
docker-flow-proxy 還有一個默認的監控服務,顯示如下:
不過數據沒有統一收集,因此意義不大,看看就好。除此之外就是真正需要部署的應用了,只要伺服器性能足夠,隨便想來幾個來幾個。
5. 部署與維護
docker stack
部署命令: ,私有倉庫必須加 才能下載鏡像。除此之外常用的如下:
docker service
我使用 Compose 的場景一般都結合 Swarm,因此很少去記手動創建或者更改配置的命令了,意義也不大。除了查看移除等與上文相似以外,此處還應記兩個:
分別是查看日誌和服務異常後強制重啟。
結語
到此為止寫了蠻多了,其餘還有一些比較重要內容的後續有空再整理一篇。總結一下,開頭我放的那張圖其實很形象:Docker 可以看做集裝箱把雜亂的貨物一個個整理歸類, Compose 則是用於編排這些集裝箱,最後 Swarm 就是多提供幾條船,掛掉一兩條還能繼續走,提高穩定性。
不知為何此刻我會突然想到一句詩:「天蒼蒼野茫茫風吹草低見牛羊」,有關聯嗎?沒關聯,想到就寫了,晚安:)
TAG:有刻 |