深入淺出Docker 讀書筆記(七)

            第14章:使用Docker Stack部署應用

大規模場景下的多服務部署和管理是一件很難的事情。Docker Stack 通過提供期望狀態、滾動升級、簡單易用、擴縮容、健康檢查等特性簡化了應用的管理,這些功能都封裝在一個完美的聲明式模型當中。Stack 能夠在單個聲明文件中定義複雜的多服務應用。Stack 還提供了簡單的方式來部署應用並管理其完整的生命週期:初始化部署 -> 健康檢查 -> 擴容 -> 更新 -> 回滾,以及其他功能!步驟很簡單。在 Compose 文件中定義應用,然後通過 docker stack deploy 命令完成部署和管理。Compose 文件中包含了構成應用所需的完整服務棧。此外還包括了卷、網絡、安全以及應用所需的其他基礎架構。然後基於該文件使用 docker stack deploy 命令來部署應用。Stack 是基於 Docker Swarm 之上來完成應用的部署。因此諸如安全等高級特性,其實都是來自 Swarm。簡而言之,Docker 適用於開發和測試。Docker Stack 則適用於大規模場景和生產環境。從體系結構上來講,Stack 位於 Docker 應用層級的最頂端。Stack 基於服務進行構建,而服務又基於容器,如下圖所示。
 

AtSea商店架構圖

 

以以下應用爲例詳解stack。服務架構架構如下圖所示。
 

AtSea商店架構圖


如上該應用由 5 個服務、3 個網絡、4 個密鑰以及 3 組端口映射構成。具體細節將會結合 Stack 文件進行分析。這裏服務指的是 Docker 服務(由若干容器組成的集合,作爲一個整體進行統一管理,並且在 Docker API 中存在對應的服務對象)。獲取源碼命令$ git clone https://github.com/dockersamples/atsea-sample-shop-app.git Cloning 該應用的代碼由若干目錄和源碼文件組成。重點關注的文件是 docker-stack.yml。該文件通常被稱爲 Stack 文件,在該文件中定義了應用及其依賴。在該文件整體結構中,定義了 4 種頂級關鍵字。1)version:代表了Compose文件格式的版本號。爲了應用於Stack,需要3.0或者更高的版本。2——)services:中定義了組成當前應用的服務都有哪些。3)networks:列出了必需的網絡。4)secrets:定義了應用用到的密鑰。
如果展開頂級的關鍵字,可以看到類似上圖中的結構。Stack 文件由 5 個服務構成,“reverse_proxy” “database” “appserver” “visualizer” “payment_gateway”。Stack 文件中包含 3 個網絡,分別爲“front-tier”“back-tier”“payment”。最後,Stack 文件中有 4 個密鑰,分別爲“postgres_password”“staging_token”“revprox_key”“revprox_cert”。Stack 文件定義了應用的很多依賴要素,因此Stack 文件是應用的一個自描述文件,並且作爲一個很好的工具彌合了開發和運維之間的隔閡。

Stack文件詳解: stack文件就是 Docker Compose 文件。唯一的要求就是 version:一項需要是“3.0”或者更高的值。1)網絡:在Docker 根據某個Stack文件部署應用的時候,首先會檢查並創建networks:關鍵字對應的網絡。如果對應網絡不存在,Docker會進行創建。上例中定義了 3 個網絡:front-tier、back-tier 以及 payment。默認情況下,這些網絡都會採用 overlay 驅動,新建對應的覆蓋類型的網絡。但是 payment 網絡比較特殊,需要數據層加密。默認情況下,覆蓋網絡的所有控制層都是加密的。如果需要加密數據層,有兩種選擇。一種是在 docker network create 命令中指定 -o encrypted 參數。另一種是在 Stack 文件中的 driver_opts 之下指定 encrypted:'yes'。數據層加密會導致額外開銷,而影響額外開銷大小的因素有很多,比如流量的類型和流量的多少。但是,通常額外開銷會在 10% 的範圍之內。正如前面提到的,全部的 3 個網絡均會先於密鑰和服務被創建。2)密鑰:密鑰屬於頂級對象,在上例Stack 文件中定義4 個密鑰都被定義爲 external。這意味着在 Stack 部署之前,這些密鑰必須存在,當然在應用部署時按需創建密鑰也是可以的,只需要將 file: <filename> 替換爲 external: true。但該方式生效的前提是,需要在主機文件系統的對應路徑下有一個文本文件,其中包含密鑰所需的值,並且是未加密的。這種方式存在明顯的安全隱患。3)服務:部署中的主要操作都在服務這個環節。每個服務都是一個JSON集合(字典)其中包含了一系列關鍵字。如1) reverse_proxy 服務,此服務定義了鏡像、端口、密鑰以及網絡。

reverse_proxy:                           image是服務對象中唯一必填項,定義用於構建服務的鏡像。
image: reverse_proxy                除非指定其他值,否則鏡像會從 Docker Hub 拉取可以通過
ports:                                          也可在鏡像前添加對應第三方鏡像倉庫服務 API 的 DNS 名
- "80:80"                                     稱的方式,ports 關鍵字定義了兩個映射80:80 將 Swarm
- "443:443"                                 節點的80端口映射到每個服務副本的80端口。同理理解443
secrets:                                      secret 定義了兩個密鑰revprox_cert 以及revprox_key這兩
- source: revprox_cert               個密鑰必須在頂級關鍵字 secrets 下定義,並且必須在系統
target: revprox_cert                   上已經存在。密鑰以普通文件的形式被掛載到服務副本當中
- source: revprox_key                文件的名稱就是 stack 文件中定義的 target 屬性的值。
target: revprox_key                    networks確保服務所有副本都會連接到 front-tier 網絡。網
networks:                                   絡相關定義必須位於頂級關鍵字 networks 之下如果定義的
- front-tier                                  網絡不存在,Docker 會以 Overlay 網絡方式新建一個網絡
Docker Stack 和 Docker Compose 的一個區別是,Stack 不支持構建。這意味着在部署 Stack 之前,所有鏡像必須提前構建完成,關於端口映射默認情況下,所有端口映射都採用 Ingress 模式。這意味着 Swarm 集羣中每個節點的對應端口都會映射並且是可訪問的,即使是那些沒有運行副本的節點。另一種方式是 Host 模式,端口只映射到了運行副本的 Swarm 節點上。但是Host 模式需要使用完整格式的配置。

Docker Stack 部署練習:部署應用之前有幾個前置處理需要完成。1)Swarm 模式:應用將採用 Docker Stack 部署,而 Stack 依賴 Swarm 模式。2)標籤:某個 Swarm worker 節點需要自定義標籤。3)密鑰:應用所需的密鑰需要在部署前創建完成。實驗環境如下圖所示。
 

實例環境


接下來內容分爲 3 個步驟。1)創建新的三節點 Swarm 集羣。在任意 Swarm 管理節點的機器上,運行$ docker swarm init    2) 添加工作節點,複製前面輸出中出現的 docker swarm join 命令。將複製內容粘貼到工作節點上並運行。3) 確認當前 Swarm 由一個管理節點和兩個工作節點構成$ docker node ls,至此payment_gateway 服務配置了部署約束,限制該服務只能運行在有 pcidss=yes 標籤的工作節點之上。在實際操作中,添加該標籤之前必須將某個 Docker 節點按 PCI 規範進行標準化。但是這只是一個實驗環境,所以就暫且跳過這一過程,直接將標籤添加到 wrk-1 節點。在 Swarm 管理節點運行下面的命令。

1) 添加節點標籤到 wrk-1    $ docker node update --label-add pcidss=yes wrk-1Node 標籤只在 Swarm 集羣之內生效。2) 確認節點標籤$ docker node inspect wrk-1,工作節配置完成,該節點可以運行 payment_gateway 服務副本了。應用定義了 4 個密鑰,這些都需要在應用部署前創建。postgress_password。staging_token。revprox_cert。revprox_key。在管理節點運行下面的命令,來創建這些密鑰。1) 創建新的鍵值對:密鑰中有 3 個是需要加密 key 的。在本步驟中會創建加密 key,下一步會將加密 key 放到 Docker 密鑰文件當中。$ openssl req -newkey rsa:4096 -nodes -sha256 \     2) 創建 revprox_cert、revprox_key 以及 postgress_password 密鑰  $ docker secret create revprox_cert domain.crt     $ docker secret create revprox_key domain.key
$ docker secret create postgres_password domain.key   3) 創建 stage_token 密鑰$ echo staging | docker secret create staging_token -     4) 列出所有密鑰  $ docker secret ls。下面是部署應用,Stack 通過 docker stack deploy 命令完成部署。基礎格式下,該命令允許傳入兩個參數,Stack 文件的名稱和Stack 的名稱。Docker 將 Stack 名稱附加到由他創建的任何資源名稱前作爲前綴。另一個需要注意的點是出現了新的名爲 seastack_default 的網絡。該網絡並未在Stack文件中定義,但每個服務都需要連接到網絡,但是 visualizer 服務並沒有指定具體的網絡。因此Docker 創建了名爲seastack_default 的網絡,並將 visualizer 連接到該網絡。可以通過兩個命令來確認當前 Stack 的狀態。docker stack ls 列出了系統中全部 Stack,包括每個 Stack 下面包含多少服務。docker stack ps <stack-name> 針對某個指定 Stack 展示了更詳細的信息,例如期望狀態以及當前狀態。如果想查看具體某個服務的詳細信息,可以使用 docker service logs 命令。要將服務名稱 /ID 或者副本 ID 作爲參數傳入。如果傳入服務名稱或 ID,可以看到所有服務副本的日誌信息。如果傳入的是副本 ID,則只會看到對應副本的日誌信息。

Stack 是一組相關聯的服務和基礎設施,需要進行統一的部署和管理。雖然這句話裏充斥着術語,但仍提醒我們 Stack 是由普通的Docker資源構建而來:網絡、卷、密鑰、服務等。這意味着可以通過普通的 Docker 命令對其進行查看和重新配置,例如 docker network、docker volume、docker secret、docker service 等。在此前提之下,通過 docker service 命令來管理 Stack 中某個服務是可行的。一個簡單的例子是通過 docker service scale 命令來擴充 appserver 服務的副本數。但是,這並不是推薦的方式!推薦通過聲明式方式修改,即將 Stack 文件作爲配置的唯一聲明。這樣,所有 Stack 相關的改動都需要體現在 Stack 文件中,然後更新重新部署應用所需的 Stack 文件。下面對實際操作中經常用到的 Docker Stack 相關的命令做了一下總結,如下所示。1) docker stsack deploy  用於根據 Stack 文件(通常是 docker-stack.yml)部署和更新 Stack 服務的命令。 2) docker stack ls   會列出 Swarm 集羣中的全部 Stack,包括每個 Stack 擁有多少服務。3) docker stack ps   列出某個已經部署的 Stack 相關詳情。該命令支持 Stack 名稱作爲其主要參數,列舉了服務副本在節點的分佈情況,以及期望狀態和當前狀態。4) docker stack rm  命令用於從 Swarm 集羣中移除 Stack。移除操作執行前並不會進行二次確認。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章