Docker Swarm 集羣環境搭建及彈性服務部署

  上一篇文章《Docker Swarm 集羣管理利器核心概念掃盲》中咱們把 Swarm 重要的概念性知識給你們講解了一波,理論完事就該實戰了,這篇文章帶你們從零開始,搭建 Docker Swarm 集羣環境,並經過 Swarm 實現服務的彈性部署,滾動更新服務及回滾服務等功能。node

  

集羣搭建

  

環境準備

  

  • 五臺安裝了 Docker 的 CentOS 機器,版本爲:CentOS 7.8.2003
  • Docker Engine 1.12+(最低要求 1.12,本文使用 19.03.12)
  • 防火牆開啓如下端口或者關閉防火牆:
    • TCP 端口 2377,用於集羣管理通訊;
    • TCP 和 UDP 端口 7946,用於節點之間通訊;
    • UDP 端口 4789,用於覆蓋網絡。

  

機器分佈

  

角色 IP HOSTNAME Docker 版本
Manager 192.168.10.101 manager1 19.03.12
Manager 192.168.10.102 manager2 19.03.12
Manager 192.168.10.103 manager3 19.03.12
Worker 192.168.10.10 worker1 19.03.12
Worker 192.168.10.11 worker2 19.03.12
  • 能夠經過 hostname 主機名 修改機器的主機名(當即生效,重啓後失效);
  • 或者 hostnamectl set-hostname 主機名 修改機器的主機名(當即生效,重啓也生效);
  • 或者 vi /etc/hosts 編輯 hosts 文件,以下所示, 給 127.0.0.1 添加主機名(重啓生效)。
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 manager1
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

  

建立集羣

  

  在任意節點下經過 docker swarm init 命令建立一個新的 Swarm 集羣並加入,且該節點會默認成爲 Manager 節點。根據咱們預先定義的角色,在 101 ~ 103 的任意一臺機器上運行該命令便可。linux

  一般,第一個加入集羣的管理節點將成爲 Leader,後來加入的管理節點都是 Reachable。當前的 Leader 若是掛掉,全部的 Reachable 將從新選舉一個新的 Leader。nginx

[root@localhost ~]# docker swarm init --advertise-addr 192.168.10.101
Swarm initialized: current node (clumstpieg0qzzxt1caeazg8g) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5ob7jlej85qsygxubqypjuftiwruvew8e2cr4u3iuo4thxyrhg-3hbf2u3i1iagurdprl3n3yra1 192.168.10.101:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

  

加入集羣

  

  Docker 中內置的集羣模式自帶了公鑰基礎設施(PKI)系統,使得安所有署容器變得簡單。集羣中的節點使用傳輸層安全協議(TLS)對集羣中其餘節點的通訊進行身份驗證、受權和加密。redis

  默認狀況下,經過 docker swarm init 命令建立一個新的 Swarm 集羣時,Manager 節點會生成新的根證書頒發機構(CA)和密鑰對,用於保護與加入羣集的其餘節點之間的通訊安全。docker

  Manager 節點會生成兩個令牌,供其餘節點加入集羣時使用:一個 Worker 令牌,一個 Manager 令牌。每一個令牌都包括根 CA 證書的摘要和隨機生成的密鑰。當節點加入羣集時,加入的節點使用摘要來驗證來自遠程管理節點的根 CA 證書。遠程管理節點使用密鑰來確保加入的節點是批准的節點。shell

  

  

Manager

  

  若要向該集羣添加 Manager 節點,管理節點先運行 docker swarm join-token manager 命令查看管理節點的令牌信息。安全

docker swarm join-token manager

  

  而後在其餘節點上運行 docker swarm join 並攜帶令牌參數加入 Swarm 集羣,該節點角色爲 Manager。網絡

  

Worker

  

  經過建立集羣時返回的結果能夠得知,要向這個集羣添加一個 Worker 節點,運行下圖中的命令便可。或者管理節點先運行 docker swarm join-token worker 命令查看工做節點的令牌信息。dom

  

  而後在其餘節點上運行 docker swarm join 並攜帶令牌參數加入 Swarm 集羣,該節點角色爲 Worker。tcp

  

查看集羣信息

  

  在任意 Manager 節點中運行 docker info 能夠查看當前集羣的信息。

  

查看集羣節點

  

  在任意 Manager 節點中運行 docker node ls 能夠查看當前集羣節點信息。

docker node ls

* 表明當前節點,如今的環境爲 3 個管理節點構成 1 主 2 從,以及 2 個工做節點。

  

  節點 MANAGER STATUS 說明:表示節點是屬於 Manager 仍是 Worker,沒有值則屬於 Worker 節點。

  • Leader:該節點是管理節點中的主節點,負責該集羣的集羣管理和編排決策;
  • Reachable:該節點是管理節點中的從節點,若是 Leader 節點不可用,該節點有資格被選爲新的 Leader;
  • Unavailable:該管理節點已不能與其餘管理節點通訊。若是管理節點不可用,應該將新的管理節點加入羣集,或者將工做節點升級爲管理節點。

  

  節點 AVAILABILITY 說明:表示調度程序是否能夠將任務分配給該節點。

  • Active:調度程序能夠將任務分配給該節點;
  • Pause:調度程序不會將新任務分配給該節點,但現有任務仍能夠運行;
  • Drain:調度程序不會將新任務分配給該節點,而且會關閉該節點全部現有任務,並將它們調度在可用的節點上。

  

刪除節點

  

Manager

  

  刪除節點以前須要先將該節點的 AVAILABILITY 改成 Drain。其目的是爲了將該節點的服務遷移到其餘可用節點上,確保服務正常。最好檢查一下容器遷移狀況,確保這一步已經處理完成再繼續往下。

docker node update --availability drain 節點名稱|節點ID

  

  而後,將該 Manager 節點進行降級處理,降級爲 Worker 節點。

docker node demote 節點名稱|節點ID

  

  而後,在已經降級爲 Worker 的節點中運行如下命令,離開集羣。

docker swarm leave

  

  最後,在管理節點中對剛纔離開的節點進行刪除。

docker node rm 節點名稱|節點ID

  

Worker

  

  刪除節點以前須要先將該節點的 AVAILABILITY 改成 Drain。其目的是爲了將該節點的服務遷移到其餘可用節點上,確保服務正常。最好檢查一下容器遷移狀況,確保這一步已經處理完成再繼續往下。

docker node update --availability drain 節點名稱|節點ID

  

  而後,在準備刪除的 Worker 節點中運行如下命令,離開集羣。

docker swarm leave

  

  最後,在管理節點中對剛纔離開的節點進行刪除。

docker node rm 節點名稱|節點ID

  

服務部署

  

注意:跟集羣管理有關的任何操做,都是在 Manager 節點上操做的。

  

建立服務

  

  下面這個案例,使用 nginx 鏡像建立了一個名爲 mynginx 的服務,該服務會被隨機指派給一個工做節點運行。

docker service create --replicas 1 --name mynginx -p 80:80 nginx

  • docker service create:建立服務;
  • --replicas:指定一個服務有幾個實例運行;
  • --name:服務名稱。

  

查看服務

  

  能夠經過 docker service ls 查看運行的服務。

[root@manager1 ~]# docker service ls
ID                NAME           MODE              REPLICAS        IMAGE              PORTS
hepx06k5ik5n      mynginx        replicated        1/1             nginx:latest       *:80->80/tcp

  

  能夠經過 docker service inspect 服務名稱|服務ID 查看服務的詳細信息。

[root@manager1 ~]# docker service inspect mynginx
[
    {
        "ID": "k0dbjg1zzy3l3g71kdwa56ect",
        "Version": {
            "Index": 127
        },
        "CreatedAt": "2020-09-16T10:05:55.627974095Z",
        "UpdatedAt": "2020-09-16T10:05:55.629507771Z",
        "Spec": {
            "Name": "mynginx",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "nginx:latest@sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0",
                    "Init": false,
                    "StopGracePeriod": 10000000000,
                    "DNSConfig": {},
                    "Isolation": "default"
                },
                "Resources": {
                    "Limits": {},
                    "Reservations": {}
                },
                "RestartPolicy": {
                    "Condition": "any",
                    "Delay": 5000000000,
                    "MaxAttempts": 0
                },
                "Placement": {
                    "Platforms": [
                        {
                            "Architecture": "amd64",
                            "OS": "linux"
                        },
                        {
                            "OS": "linux"
                        },
                        {
                            "OS": "linux"
                        },
                        {
                            "Architecture": "arm64",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "386",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "mips64le",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "ppc64le",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "s390x",
                            "OS": "linux"
                        }
                    ]
                },
                "ForceUpdate": 0,
                "Runtime": "container"
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "UpdateConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "RollbackConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "EndpointSpec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80,
                        "PublishedPort": 80,
                        "PublishMode": "ingress"
                    }
                ]
            }
        },
        "Endpoint": {
            "Spec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80,
                        "PublishedPort": 80,
                        "PublishMode": "ingress"
                    }
                ]
            },
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 80,
                    "PublishedPort": 80,
                    "PublishMode": "ingress"
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "st2xiy7pjzap093wz4w4u6nbs",
                    "Addr": "10.0.0.15/24"
                }
            ]
        }
    }
]

  

  能夠經過 docker service ps 服務名稱|服務ID 查看服務運行在哪些節點上。

  在對應的任務節點上運行 docker ps 能夠查看該服務對應容器的相關信息。

  

調用服務

  

  接下來咱們測試一下服務是否能被正常訪問,而且該集羣下任意節點的 IP 地址都要能訪問到該服務才行。

  測試結果:5 臺機器都可正常訪問到該服務。

  

彈性服務

  

  將 service 部署到集羣之後,能夠經過命令彈性擴縮容 service 中的容器數量。在 service 中運行的容器被稱爲 task(任務)。

  經過 docker service scale 服務名稱|服務ID=n 能夠將 service 運行的任務擴縮容爲 n 個。

  經過 docker service update --replicas n 服務名稱|服務ID 也能夠達到擴縮容的效果。

  將 mynginx service 運行的任務擴展爲 5 個:

[root@manager1 ~]# docker service scale mynginx=5
mynginx scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   [==================================================>] 
2/5: running   [==================================================>] 
3/5: running   [==================================================>] 
4/5: running   [==================================================>] 
5/5: running   [==================================================>] 
verify: Service converged

  經過 docker service ps 服務名稱|服務ID 查看服務運行在哪些節點上。

  

  咱們再來一波縮容的操做,命令以下:

[root@manager1 ~]# docker service update --replicas 3 mynginx
mynginx
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged

  經過 docker service ps 服務名稱|服務ID 查看服務運行在哪些節點上。

  在 Swarm 集羣模式下真正意義實現了所謂的彈性服務,動態擴縮容一行命令搞定,簡單、便捷、強大。

  

刪除服務

  

  經過 docker service rm 服務名稱|服務ID 便可刪除服務。

[root@manager1 ~]# docker service rm mynginx
mynginx
[root@manager1 ~]# docker service ls
ID                NAME              MODE              REPLICAS          IMAGE             PORTS

  

滾動更新及回滾

  

  如下案例將演示 Redis 版本如何滾動升級至更高版本再回滾至上一次的操做。

  首先,建立 5 個 Redis 服務副本,版本爲 5,詳細命令以下:

# 建立 5 個副本,每次更新 2 個,更新間隔 10s,20% 任務失敗繼續執行,超出 20% 執行回滾,每次回滾 2 個
docker service create --replicas 5 --name redis \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action continue \
--rollback-monitor 20s \
--rollback-parallelism 2 \
--rollback-max-failure-ratio 0.2 \
redis:5
  • --update-delay:定義滾動更新的時間間隔;
  • --update-parallelism:定義並行更新的副本數量,默認爲 1;
  • --update-failure-action:定義容器啓動失敗以後所執行的動做;
  • --rollback-monitor:定義回滾的監控時間;
  • --rollback-parallelism:定義並行回滾的副本數量;
  • --rollback-max-failure-ratio:任務失敗回滾比率,超過該比率執行回滾操做,0.2 表示 20%。

  

  而後經過如下命令實現服務的滾動更新。

docker service update --image redis:6 redis

  

  回滾服務,只能回滾到上一次操做的狀態,並不能連續回滾到指定操做。

docker service update --rollback redis

  

經常使用命令

  

docker swarm

  

命令 說明
docker swarm init 初始化集羣
docker swarm join-token worker 查看工做節點的 token
docker swarm join-token manager 查看管理節點的 token
docker swarm join 加入集羣

  

docker node

  

命令 說明
docker node ls 查看集羣全部節點
docker node ps 查看當前節點全部任務
docker node rm 節點名稱|節點ID 刪除節點(-f強制刪除)
docker node inspect 節點名稱|節點ID 查看節點詳情
docker node demote 節點名稱|節點ID 節點降級,由管理節點降級爲工做節點
docker node promote 節點名稱|節點ID 節點升級,由工做節點升級爲管理節點
docker node update 節點名稱|節點ID 更新節點

  

docker service

  

命令 說明
docker service create 建立服務
docker service ls 查看全部服務
docker service inspect 服務名稱|服務ID 查看服務詳情
docker service logs 服務名稱|服務ID 查看服務日誌
docker service rm 服務名稱|服務ID 刪除服務(-f強制刪除)
docker service scale 服務名稱|服務ID=n 設置服務數量
docker service update 服務名稱|服務ID 更新服務

  

參考資料

  

本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議

你們能夠經過 分類 查看更多關於 Docker 的文章。

  

🤗 您的點贊轉發是對我最大的支持。

📢 掃碼關注 哈嘍沃德先生「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~

相關文章
相關標籤/搜索