用Docker Swarm實現容器服務高可用

2022-07-01 12:45:17 字數 4148 閱讀 4048

如何用容器快速部署這三個應用?

如何提高效能?

如何保障後端可用性?

在我以往的實踐中,容器的編排使用了docker-compose實現,問題一就已經解決。但docker-compose也只是用於編排,可以各啟動三個服務的乙個容器,效能與高可用性就可能不能滿足要求。

對於效能與高可用,如果是大型專案,目前不二的選擇就是kubernetes(k8s),但是我的專案不足以稱之為「大型專案」,因此我考慮的是,如何在單宿主機上提高效能與高可用。

docker swarm是官方整合至 docker cli 中的集群服務(雖然被k8s後來居上,但是其設計理念與功能也是十分成熟完善,架構上與k8s有很多共通點)。swarm可以連線多個宿主機作為集群節點,當然也是支援單機容器集群的部署。swarm的集群部署需要建立services,secret等,也是較為繁瑣,因此有stack工具能夠解析compose檔案,讓建立各種服務的過程描述於yaml指令碼中,更方便管理。

當然,stack解析的compose檔案語法與docker-compose所支援的略微有不同,但大多是通用的,具體後面提到。

綜上可以總結一下幾個工具的關係與區別:

優勢/劣勢僅針對我的後端架構而言

工具/服務

優勢劣勢

是否滿足

docker-compose

容器編排

不支援高可用

否kubernetes

容器編排,高可用,適合大型專案無是

swarm

容器編排,高可用

成熟度略差於k8s

是stack

屬於swarm的命令,用於應用compose檔案

n/an/a

**中特意加上了stack,因為最開始我把stackswarm視為同一級了。swarm更多是提供集群環境,協調各種服務元件,而stack更像是乙個命令列工具,呼叫swarm的各種命令啟動不同服務等。

每個服務由任務(task)的複製集組成,乙個任務就是乙個容器(container)。例如乙個後端服務,我們可以通過啟動 3 個複製任務來提高效能。服務是程式的出入口,雖然啟動了 3 個任務,我們訪問這個服務時候還是用服務名即可,請求會在幾個任務之間按 rr(輪詢) 機制被處理。

介紹了 docker swarm 的幾個概念之後,我們來實際實現標題「用 docker swarm 實現容器服務高可用」吧!

因為我在單機上部署我的應用,擴充套件 swarm 節點的操作就不贅述了。

首先初始乙個swarm集群:

docker swarm init

複製**

集群初始化成功後,docker network ls會看到新建立了兩個網路:

異常解決

在除錯 swarm 部署應用時,我在 3 臺機器執行了一樣的操作,奇怪的是其中一台伺服器在初始化 swarm 集群後,只建立了ingress,導致應用部署後任務無法啟動。

通過執行:

docker service ps --no-trunc 

複製**

檢視到部分報錯資訊如下:

複製**

發現是 docker 網路出了問題,通過對比幾台伺服器的網路找到是docker_gwbridge的缺失。

手動建立該網橋解決問題:

docker network create \

--subnet 172.20.0.0/20 \

--gateway 172.20.0.1 \

-o com.docker.network.bridge.enable_icc=false \

-o com.docker.network.bridge.name=docker_gwbridge \

docker_gwbridge

複製**

應用可以通過手動乙個個建立服務的方式部署,通過引用同乙個 docker 網路來保證服務間的通訊可達。

但是 docker 提供了更方便的方式來部署、擴充套件乙個應用————docker-compose.yml配置檔案

compose 檔案

先按我的服務架構,寫乙份docker-compose.yml檔案:

version: '3'

services:

rabbit:

image: rabbitmq:3

ports:

- "5672:5672"

networks:

- webnet

web:

image: myweb:latest

command: python manage.py runserver 0.0.0.0:8000

environment:

- django_settings_module=bd_annotation_proj.settings.staging

deploy:

replicas: 3

depends_on:

- rabbit

- worker

ports:

- "8000:8000"

networks:

- webnet

celery-worker:

image: myweb:latest

command: celery -a bd_annotation_proj worker -l info

environment:

- django_settings_module=bd_annotation_proj.settings.staging

deploy:

replicas: 2

depends_on:

- rabbit

networks:

- webnet

networks:

webnet:

複製**

重要字段含義如下:

建立應用與服務

複製**

服務檢視

# 檢視所有服務

docker service ls

複製**

服務中執行的任務可以直接通過docker ps檢視容器 id 等資訊。

修改docker-compose.yml中的replicas配置來擴充套件複製集:

...

delopy:

replicas: 5

複製**

修改後應用新配置:

複製**

如果映象發生了更新,此時需要針對性地更新服務:

複製**

會有進度條顯示當前服務中任務的更新進度。

通過執行:

複製**

結束應用的生命週期,應用相關的任務、服務與網路都會被刪除。

通過 docker swarm 部署完成我的應用後,我通過刪除容器檢視重啟情況實際測試了一下高可用性,完全符合我的預期。swarm 中的ingress類似 nginx,已經替我們完成了負載均衡,我們只要享受這種便利就好。

效能上,由於啟動了 3 個容器,相比之前在乙個容器中使用uwsgi的方式執行服務,部分請求響應時間提公升 10 倍,相當滿意。

容器是開發者的福音,無論是前後端還是測試運維都有必要學習與應用它。雖然容器編排的戰役可以說是 k8s 拿下,但是 swarm 在很多場景也是能夠勝任。還是那句話:技術沒有對錯,只有合適不合適!

DNS實現粗粒度容災

這裡介紹如果通過dns來實現容災,餓了麼有非常多的應用,應用的使用者量非常大,遍布各地。這些應用都是需要網域名稱的,所以為了提神服務質量,構建自己的dns體系,為餓了麼的應用提供網域名稱解析服務。dns提供了根據網域名稱查ip位址的服務,和常見的http協議一樣,dns也是乙個工作在7層的應用成協議...

iOS容聯離線訊息接收實現

1.需要在控制台裡面上傳生產證書 2.把應用上蘋果推送開關確認是開啟狀態 3.應用啟動 告訴ios底層請求token ios8 註冊apns uiusernotificationtype notificationtypes uiusernotificationtypebadge uiusernoti...

通過rsync實現遠端容災備份

一 rsync簡介 rsync是linux系統下的資料映象備份工具,通過rsync可以將本地系統資料通過網路備份到任何遠端主機上,rsync有如下特性 可以映象儲存整個目錄樹和檔案系統 可以增量同步資料,檔案傳輸效率高,因而同步時間很短。可以保持原有檔案的許可權 時間等屬性。加密傳輸資料,保證了資料...