docker swarm

簡介:
      docker swarm 是 docker 推出的一款用於多主機的容器編排工具
 
 
特性:
      集成 docker Engine: 與 docker 集成的集羣管理工具
 
      聲明性服務模型: 使用聲明性方法來定義應用程序中各種服務的所需狀態
 
      分散式設計: Docker Engine 在運行時處理任何專門化, 而不是在部署時處理節點角色之間的差異, 您可以使用DOCKER Engine 部署 managers 和 nodes
 
      動態伸縮: 對於每個服務, 您可以聲明要運行的任務數. 當您向上或向下擴展時, swarm 管理器會通過添加或刪除任務來自動調整容器數量
 
      期望的狀態協調: swarm 管理器持續監視羣集狀態, 並協調實際狀態與表達的所需狀態之間的任何差異, 直到實際狀態與期望狀態相同
 
      多主機網絡: 您可以爲服務指定覆蓋網絡, swarm 管理器在初始化或更新應用程序時自動爲覆蓋網絡上的容器分配地址
 
      服務發現: Swarm 管理器節點爲 swarm 中的每個服務分配一個唯一的 DNS 名稱, 並負載均衡正在運行的容器
 
      負載均衡: 您可以將服務端口公開給外部負載均衡器. 在內部 swarm 允許您指定如何在節點之間分發服務容器
 
      默認安全: swarm 中的每個節點都強制執行 TLS 相互身份驗證和加密,以保護自身與所有其他節點之間的通信
 
      滾動更新: 在更新時, 您可以逐步將服務更新應用於節點. 通過 swarm 管理器, 您可以控制服務部署到不同節點之間的延遲. 出現問題,您可以將任務回滾到以前的版本

 
 
關鍵概念:
      什麼是 swarm:
           一個 swarm 羣集由多個 Docker 主機組成, 這些主機以羣集模式運行, 並充當 managers 和 workers
           給定的 Docker 主機可以是 manager 或 worker 這兩種角色
           創建服務時, 您可以定義其最佳狀態(可用的副本數量, 網絡和存儲資源, 服務暴露給外部的端口等)
           Docker 努力維持所需的狀態. 例如, 如果工作節點變得不可用, Docker 將該節點上的容器調度到其他節點上運行
 
 
      任務:
           一個任務是一個運行的容器, 是一個 swarm 服務的一部分, 並通過 swarm manager 管理, 而不是一個獨立的容器
           羣集服務相對於獨立容器的一個主要優點是, 您可以修改服務的配置, 包括其連接的網絡和卷, 而無需手動重新啓動服務, Docker 將更新配置
           當 Docker 以羣集模式運行時, 您仍然可以在 swarm 節點上運行獨立容器和羣集服務
           獨立容器和羣集服務之間的關鍵區別在於, 只有羣集管理器可以管理羣集, 而獨立容器可以在任何守護程序上啓動
           與使用 Docker Compose 定義和運行容器的方式相同, 您可以定義和運行 swarm service stacks

 
 

      節點:
           一個節點是一個裝有 Docker Engine 的主機, 要將應用程序部署到 swarm 請將服務定義提交給 manager 節點, manager 節點將任務分派給 work 節點
           manager 節點維護羣集狀態所需的編排和集羣管理功能. manager 節點選擇單個 leader 來執行編排任務
           worker 節點接收並執行從 manager 節點分派的任務
           默認情況下 manager 節點還將作爲 worker 節點運行, 但您可以將它們配置爲僅作爲 manager 節點
           agent 程序在每個 worker 節點上運行, 並報告分配給它的任務
           worker節點向 manager 節點通知其分配的任務和當前狀態, 以便 manager 可以維持每個 worker 的期望狀態

 
 

      服務和任務:
           服務是在 manager 或 worker 節點上執行的任務的定義. 它是 swarm 系統的中心, 是用戶與 swarm 交互的主要根源
           在創建服務時, 指定要使用的容器鏡像以及在運行容器中執行的命令
           在 replicated 服務模型中, swarm 管理器根據您在所需狀態中設置的比例在節點之間分配特定數量的 replica 任務

 
 
      負載均衡:
           swarm 管理器使用入口負載均衡來發布可被外部主機訪問的服務
           swarm 管理器可以自動爲發佈的端口分配服務, 或者可以爲服務發佈端口
           在發佈端口時, 您可以指定任何未使用的端口, 如果您沒有指定端口, swarm 管理器將爲服務分配給一個在 30000-32767 範圍內的端口

 
 
 

安裝 swarm 的前提:

1、安裝 docker
        # 建議安裝 docker 1.12 以上版本
        https://docs.docker.com/install/linux/docker-ce/centos/#prerequisites

2、配置 docker 監聽 TCP 2375端口
        mkdir /etc/systemd/system/docker.service.d/
        cat > /etc/systemd/system/docker.service.d/tcp.conf <<EOF
        [Service]
        ExecStart=
        ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
        EOF

3、重啓 docker 
        systemctl daemon-reload
        systemctl restart docker

 
 
 

創建 swarm 集羣:

    # 初始化 master 節點, 192.168.5.11 爲 master 和其他節點進行通信的 IP
    # 初始化完成後輸出 docker swarm join --token ... 的一條命令, 在節點執行, 將節點加入 swarm 集羣 
    docker swarm init --advertise-addr 192.168.5.11

    # 查看 swarm 集羣狀態
    docker info

    # 查看和節點相關的信息
    docker node ls

    # 查看端口監聽情況
    ss -tunl

    # docker swarm 需要監聽的端口
    # tcp/2377                  # swarm 集羣管理端口
    # tcp/7946 udp/7946         # 節點間通信
    # udp/4789                  # 網絡流量傳輸

 
 
 

節點加入集羣:

    # 將 master端 執行 docker swarm init 後輸出的命令在 node 節點上運行即可
    docker swarm join --token \ 
        SWMTKN-1-4xim2s11yxwlb1rz4pvbm9fsivjfgh5bssspalpdku4p1uk806-baaerpzmlgena74kvzh5dif3a \
        192.168.5.11:2377

    # 如果不小心忘記了, 可以使用此命令獲取
    docker swarm join-token worker

    # 在 master 上運行此命令將看見 node 節點已經加入 swarm
    docker node ls

 
 
 

swarm 集羣基礎操作:

    # 在 maser 上運行此命令(對 swarm 集羣的大多數操作都是在 master 上操作的, 下面的操作如無額外說明都是在 master 上執行)
    docker service create --replicas 1 --name helloworld alpine ping docker.com

    # docker service create     創建一個 swarm 服務
    # --replicas                服務的副本數(一共有多少個容器在運行)
    # --name                    服務名稱
    # alpine ping docker.com    運行 alpine 鏡像, 執行 ping docker.com 命令

    # 查看服務
    docker service ls

    # 輸出 helloworld 服務基礎信息
    docker service inspect --pretty helloworld

    # 輸出 helloworld 服務詳細信息
    docker service inspect helloworld

    # 查看正在運行服務的節點, 在節點對應節點上運行 docker container ls 可以看見該容器在運行
    docker service ps helloworld

    # 將 helloworld 的副本數更改爲 10
    docker service scale helloworld=10

    # 查看服務副本數量(查看 REPLICAS 列)
    docker service ls

    # 將 helloworld 的副本數更改爲 5
    docker service scale helloworld=5

    # 查看服務副本數量, 這次發現 REPLICAS 爲 5/5 (有可能是 10/5 這是因爲雖然服務器已經減少副本的數量了, 但是 docker 還沒有將容器刪除, 出現這種情況多等待一段時間即可)
    docker service ls

    # 查看各個副本所在的 node 節點
    docker service ps helloworld

    # 刪除該服務
    docker service rm helloworld

 
 
 

swarm 滾動更新服務:

    # 創建一個 redis 服務
    docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6

    # --update-delay             指定服務在更新時的延遲時間, 將時間表示爲T, 秒數Ts, 分鐘數Tm, 小時數Th. 所以 10m30s 表示延遲10分30秒
    # --update-parallelism       默認情況下, 調度程序一次更新1個任務, 使用該參數指定同時更新的最大任務數

    # 默認情況下, 對單個任務更新返回的狀態爲 RUNNING 時, 調度程序會繼續更新下一個任務, 直到所有任務更新完成. 如果在更新返回 FAILED 則調度程序會暫停更新
    # 可以使用 --update-failure-action 來控制 docker service create 或 docker service update 的行爲
    # --update-failure-action 可接受的值 pause(默認值, 暫停), continue(繼續), rollback(回滾)

    # 查看 redis 服務(這時 IMAGE 列的值爲 redis:3.0.6)
    docker service ls

    # 更新 redis 服務(swarm 管理器將根據 UpdateConfig 策略將更新應用於節點)
    docker service update --image redis:3.0.7 redis

    # 查看 redis 服務(這時 IMAGE 列的值爲 redis:3.0.7)
    docker service ls

    # 查看更新狀態, 如果更新失敗在 Message 列將顯示和更新失敗相關的內容
    docker service inspect --pretty redis

    # 重啓暫停的更新任務
    docker service update redis

    # 查看服務更新信息(將看見所有的歷史版本)
    docker service ps redis

 
 
 

設置 swarm 節點狀態:

    # 當節點處於 Active 狀態時(docker node ls 的 AVAILABILITY 列), swarm 管理器可以將任務分配給任何 ACTIVE 狀態的節點
    # 有時, 例如服務器維護, 需要將節點狀態設置爲 DRAIN
    # DRAIN 狀態阻止節點從 swarm 管理器接收新任務, 並且 swarm 管理器將停止此節點上運行的任務(一個任務通常就是一個容器), 將其上的任務分配給其他狀態爲 ACTIVE 的節點

    # 查看節點(獲取節點 NODE 名稱)
    docker node ls

    # 將節點狀態設置爲 drain, docker-2 是我 docker 節點的名稱
    docker node update --availability drain docker-2

    # 查看節點狀態
    docker node inspect --pretty docker-2 | grep Availability

    # 查看 swarm 管理器將其任務的分配情況
    docker service ps redis

    # 將節點狀態設置爲 active
    docker node update --availability active docker-2

    # 查看節點狀態
    docker node inspect --pretty docker-2 | grep Availability

 
 
 
swarm 網絡:

    docker swarm 通過發佈端口使得外部主機可以訪問集羣資源, 所有節點都參入到 ingress 路由網格
    路由網格使得集羣中每個節點都能夠接收集羣中已發佈的服務端口的連接, 即使節點上沒有運行該任務
    路由網格將所有傳入請求路由到發佈端口的可用節點的可用容器上
    docker 的路由網格在 Linux 上使用 iptables 實現

    # 在新版本的 docker swarm 中, 使用 --publish 暴露端口, published 爲暴露的端口(即宿主機端口), target 爲容器端口
    # 如果不指定 published 參數 docker swarm 會隨機分配一個高編號的端口
    docker service create --name my-web --publish published=8080,target=80 --replicas 2 nginx

    # 在任何節點上訪問 8080 端口時, docker 會將請求路由到活動容器(狀態健康並且運行了該任務的容器)
    # 在 swarm 節點本身上, 8080 端口實際上可能不受約束, 但路由網格知道如何路由流量並防止發生任何端口衝突
    # 路由網格節點上的發佈端口的所有地址(0.0.0.0:<port>), 對於外網地址, 該端口可以在外部訪問, 對於其他 IP 地址只能在內部訪問

    訪問測試:
        # 查看容器所在的節點
        docker service ps my-web

        # 修改 node 2 節點上的 index.html
        [root@docker-2 ~]# docker container exec -it 4a998a01a9d4 bash                  # 進入 my-web 的任務容器
        root@4a998a01a9d4:/# echo "node2" > /usr/share/nginx/html/index.html            # 修改頁面內容

        # 修改 node 3 節點上的 index.html
        [root@docker-3 ~]# docker container exec -it f1aedec1c1db bash                  # 進入 my-web 的任務容器
        root@f1aedec1c1db:/# echo "node3" > /usr/share/nginx/html/index.html            # 修改頁面內容

        # 在任意節點訪問, 路由網格會自動進行負載均衡
        curl http://127.0.0.1:8080/

    # 對現有的服務進行端口發佈
    docker service update --publish-add published=2222,target=22 my-web

    # 查看已發佈的端口    
    docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web | python -m json.tool

    默認情況下, docker swarm 發佈的端口爲 TCP 端口, 需要發佈 UDP 的端口需要使用 protocol 參數設置
    # 發佈 TCP 端口
    docker service create --name dns-cache --publish published=53,target=53 dns-cache

    # 發佈 TCP 和 UDP 端口
    docker service create --name dns-cache --publish published=53,target=53 --publish published=53,target=53,protocol=udp dns-cache

    # 發佈 UDP 端口
    docker service create --name dns-cache --publish published=53,target=53,protocol=udp dns-cache

            繞過路由網格:
                    您可以繞過路由網格, 以便在訪問給定節點上的綁定端口時, 始終訪問在該節點上運行的服務實例, 這被稱爲 host 模式
                    host 和 ingress 的區別:
                            1、如果一個任務啓動了兩節點上的容器, 那麼在 ingress 模式下, 不管訪問那個 node 其都會對請求做負載均衡, 將請求負載到兩個節點上的容器
                            2、在 host 模式中必須使用 IP 地址訪問運行了該任務的節點, 其訪問是和 IP 地址綁定的
                            3、在 host 模式中, 如果節點沒有運行指定任務則不會簡單指定端口, 或者是其他不同的任務在監聽
                            4、在 host 模式中, 創建服務時不能指定 --replicas 選項
                            5、如果您希望在每個節點上運行多個服務任務(例如: 當您有5個節點但運行10個副本時), 則無法指定靜態目標端口, Docker 會隨機分配高編號端口

                    # 要繞過路由網格, 將 --publish 的 mode 設置爲 host, mode 默認爲 ingress
                    docker service create --name web --publish published=8000,target=80,mode=host --mode global nginx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章