前面我們已經學習過了Docker Compose,它可以用來進行一個完整的應用程序相互依賴的多個容器的編排的,但是缺點是只能在單機模式使用,不能在分布式多機器上使用;前面我們也學習了Docker swarm,它可以將單個服務部署為多個容器,并運行在不同集群節點上,構成服務集群,缺點是只能部署單個服務,不能同時編排多個服務。
但是在實際的生產開發中,我們一個完整的應用需要的服務往往不止一個,通過docker service命令來部署的話會很麻煩,那么能不能結合Docker Compose+Docker swarm的優點呢?這就是Docker Stack。
Docker Stack用于向swarm集群部署完整的應用程序堆棧,可以在分布式多機器上同時編排多個有依賴關系的服務。能夠在單個聲明文件中定義復雜的多服務應用,還提供了簡單的方式來部署應用并管理其完整的生命周期:初始化部署 -> 健康檢查 -> 擴容 -> 更新 -> 回滾,以及其他功能!可以簡單地理解為Docker Stack是集群下的Docker Compose。
Docker Compose中的不支持項
Docker Stack編排依賴于聲明文件,其實也就是Docker Compse文件,不過Docker Stack對于Docker Compose文件有一個要求,文件的規范版本(頂層關鍵字version)必須是“3.0”或以上,而且一些Docker Compse文件中的關鍵字不受支持,如:
- build
- cgroup_parent
- container_name
- devices
- tmpfs
- external_links
- links
- network_mode
- restart
- security_opt
- userns_mode
由于build關鍵字在Docker Stack中不受支持,不能在編排的過程中構建鏡像,docker stack部署用到的鏡像必須是已經構建發布好,并且發布到docker倉庫的,在服務編排過程各個節點中直接從docker倉庫拉取。
先構建鏡像:
$ sudo docker image build -t flask-demo .
登陸遠程鏡像倉庫:
$ sudo docker login --username=xxx@xxxx.com registry.cn-hangzhou.aliyuncs.com
這里使用的是阿里云的免費鏡像倉庫:https://cr.console.aliyun.com/cn-hangzhou/instances
再修改鏡像的tag:
$ sudo docker image tag flask-demo:latest registry.cn-hangzhou.aliyuncs.com/morris131/flask-demo:latest
最后將鏡像推送至遠程倉庫:
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/morris131/flask-demo:latest
手動部署多service
先創建一個overlay網絡:
$ sudo docker network create -d overlay mynet
kunkv8prss5gihgz5deowhdfw
然后部署redis service:
$ sudo docker service create --name redis --network mynet redis:latest redis-server --requirepass ABC
bn507bk9aaggf1lhhpnask9kq
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
部署flask-demo service
$ sudo docker service create --name flask-demo --network mynet --env REDIS_HOST=REDIS --env REDIS_PASS=ABC -p 8080:5000 flask-demo:latest
image flask-demo:latest could not be accessed on a registry to record
its digest. Each node will access flask-demo:latest independently,
possibly leading to different nodes running different
versions of the image.xx9chfrx2ro3j8cnvab5vp0pm
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
查看服務,可以看到flask-demo和redis都已經部署成功:
$ sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
7yr3lamfse5k flask-demo replicated 1/1 flask-demo:latest *:8080->5000/tcp
bn507bk9aagg redis replicated 1/1 redis:latest
訪問flask-demo服務:
$ curl 172.20.160.13:8080
Hello Container World! I have been seen 3 times and my hostname is bf03f59d3bab.
Docker Stack部署多service
前面可以看到通過docker service手動部署多個service非常繁瑣,需要一個一個service部署。
接下來使用Docker Stack來部署多service的服務。
編寫docker-compose.yml:
version: "3.3"services:flask-demo:image: registry.cn-hangzhou.aliyuncs.com/morris131/flask-demoenvironment:- REDIS_HOST=redis-server- REDIS_PASS=ABCnetworks:- demo-networkports:- 8080:5000redis-server:image: redis:latestcommand: redis-server --requirepass ABCnetworks:- demo-networknetworks:demo-network:
啟動服務:
$ sudo docker stack deploy --compose-file docker-compose.yml flask
Creating network flask_demo-network
Creating service flask_redis-server
Creating service flask_flask-demo
訪問服務:
$ curl 172.20.160.13:8080
Hello Container World! I have been seen 1 times and my hostname is 4a88aad138e7.
Stack基本命令的使用
Docker stack命令用于swam集群中對應用堆棧涉及到的多個服務進行編排部署和全生命周期管理。
常用的命令如下,可用help命令查看詳細說明:
$ sudo docker stack helpUsage: docker stack COMMANDManage Swarm stacksCommands:config Outputs the final config file, after doing merges and interpolationsdeploy Deploy a new stack or update an existing stackls List stacksps List the tasks in the stackrm Remove one or more stacksservices List the services in the stackRun 'docker stack COMMAND --help' for more information on a command.
docker stack deploy
docker stack deploy [OPTIONS] STACK
根據Stack文件(通常是 docker-compose.yml)部署和更新Stack服務的命令,常用選項如下:
- -c:指定compose文件路徑
- –with-registry-auth:服務創建的時候,各個工作節點同步管理節點的私有倉庫登錄憑證,從而各個節點可用拉取私有倉庫鏡像
docker stack ls
docker stack ls
列出Swarm集群中的全部Stack,包括每個Stack擁有多少服務。
例如:
$ sudo docker stack ls
NAME SERVICES
flask 2
docker stack ps
docker stack ps [OPTIONS] STACK
列出某個已經部署的Stack相關詳情。該命令支持Stack名稱作為其主要參數。
在服務啟動失敗時,docker stack ps命令是首選的問題定位方式。該命令展示了Stack中每個服務的概況,包括服務副本所在節點、當前狀態、期望狀態以及異常信息,再配合docker service logs查看某個具體服務或任務的詳細信息。
$ sudo docker stack ps flask
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
oaq79y2xpvz0 flask_flask-demo.1 registry.cn-hangzhou.aliyuncs.com/morris131/flask-demo:latest node1 Running Running 6 minutes ago
03j987pc0yyn flask_redis-server.1 redis:latest node2 Running Running 5 minutes ago
docker stack services
docker stack services [OPTIONS] STACK
列出某個已經部署的Stack的服務,包括服務的模式,使用的鏡像,端口映射等。
$ sudo docker stack services flask
ID NAME MODE REPLICAS IMAGE PORTS
yoynkqh2mh9n flask_flask-demo replicated 1/1 registry.cn-hangzhou.aliyuncs.com/morris131/flask-demo:latest *:8080->5000/tcp
yrg986m18pps flask_redis-server replicated 1/1 redis:latest
docker stack rm
docker stack rm [OPTIONS] STACK [STACK...]
從Swarm集群中移除一個或多個Stack。移除操作執行前并不會進行二次確認。
$ sudo docker stack rm flask
Removing service flask_flask-demo
Removing service flask_redis-server
Removing network flask_demo-network