上一篇: "Docker 三劍客之 Docker Compose" 閱讀目錄: Docker Machine 創建 Docker 主機 Docker Swarm 配置集群節點 Docker Service 部署單個集群服務 Docker Stack 部署多個集群服務,以及 GUI 管理頁面 dock ...
上一篇:Docker 三劍客之 Docker Compose
閱讀目錄:
- Docker Machine 創建 Docker 主機
- Docker Swarm 配置集群節點
- Docker Service 部署單個集群服務
- Docker Stack 部署多個集群服務,以及 GUI 管理頁面
- docker-machine、docker swarm、docker node、docker service 和 docker stack 常用命令
Docker Swarm 和 Docker Compose 一樣,都是 Docker 官方容器編排項目,但不同的是,Docker Compose 是一個在單個伺服器或主機上創建多個容器的工具,而 Docker Swarm 則可以在多個伺服器或主機上創建容器集群服務,對於微服務的部署,顯然 Docker Swarm 會更加適合。
從 Docker 1.12.0 版本開始,Docker Swarm 已經包含在 Docker 引擎中(docker swarm
),並且已經內置了服務發現工具,我們就不需要像之前一樣,再配置 Etcd 或者 Consul 來進行服務發現配置了。
1. Docker Machine 創建 Docker 主機
在進行 Docker Swarm 配置之前,我們還需要說下 Docker 另外一個官方工具 Docker Machine(也是 Docker 三劍客之一),其作用就是快速幫助我們搭建 Docker 主機環境,比如我們要使用 Docker Swarm,就必須有很多的 Docker 主機來進行操作,Docker Machine 就是最理想的工具。
因為我是在 Mac OS 上進行操作的,並且 Docker for Mac 已經包含了 Docker Machine(docker machine
),所以我不需要再額外進行安裝了,如果使用 Linux 系統的話,安裝也非常簡單,命令:
$ sudo curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` > /usr/local/bin/docker-machine
$ sudo chmod +x /usr/local/bin/docker-machine
好了,我們先使用 Docker Machine 創建四個 Docker 主機,命令:
$ docker-machine create -d virtualbox manager1 &&
docker-machine create -d virtualbox manager2 &&
docker-machine create -d virtualbox worker1 &&
docker-machine create -d virtualbox worker2
Running pre-create checks...
(worker1) No default Boot2Docker ISO found locally, downloading the latest release...
(worker1) Latest release for github.com/boot2docker/boot2docker is v17.11.0-ce
(worker1) Downloading /Users/xishuai/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.11.0-ce/boot2docker.iso...
執行上面命令,你會發現速度巨慢(如上),原因是從 GitHub 上下載一個boot2docker.iso
文件(國內網路沒辦法),怎麼解決呢?很簡單,我們使用翻X的瀏覽器手動下載boot2docker.iso
文件,然後拷貝到對應目錄下(我電腦的目錄/Users/xishuai/.docker/machine/cache/
),然後再執行上面的命令,發現速度快的一批。
我們可以查看下創建的 Docker 主機信息,命令:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
manager1 - virtualbox Running tcp://192.168.99.100:2376 v17.11.0-ce
manager2 - virtualbox Running tcp://192.168.99.101:2376 v17.11.0-ce
worker1 - virtualbox Running tcp://192.168.99.102:2376 v17.11.0-ce
worker2 - virtualbox Running tcp://192.168.99.103:2376 v17.11.0-ce
可以看到,我們創建了四個 Docker 主機(兩個 Manager 和兩個 Worker),我們還可以連接到任何一臺伺服器進行操作,命令:
$ docker-machine ssh manager1
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
_ _ ____ _ _
| |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 17.11.0-ce, build HEAD : e620608 - Tue Nov 21 18:11:40 UTC 2017
Docker version 17.11.0-ce, build 1caf76c
2. Docker Swarm 配置集群節點
我們執行下麵命令:
$ docker-machine ssh manager1 "docker swarm init --advertise-addr 192.168.99.100"
Swarm initialized: current node (n0ub7dpn90rxjq97dr0g8we0w) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面是在manager1
主機上,創建一個 Docker Swarm 管理節點(初始化集群的時候,會自動把當前節點設置為管理節點)。
接著,我們在worker1
和worker2
主機上,創建兩個工作節點,並加入到集群中,命令:
$ docker-machine ssh worker1 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377"
This node joined a swarm as a worker.
$ docker-machine ssh worker2 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377"
This node joined a swarm as a worker.
還有另外一個manager2
主機,需要配置為管理節點,我們需要先在manager1
主機上,獲取管理節點對應的token
,然後再配置為管理節點,命令:
$ docker-machine ssh manager1 "docker swarm join-token manager"
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-0koz1b98sco8r5cn3g61eahnu 192.168.99.100:2377
$ docker-machine ssh manager2 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-0koz1b98sco8r5cn3g61eahnu 192.168.99.100:2377"
This node joined a swarm as a manager.
配置好之後,我們進入manager1
主機內(上面的命令也可以在主機內執行),然後查看集群節點的信息,命令:
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
n0ub7dpn90rxjq97dr0g8we0w * manager1 Ready Active Leader
t4cy67qp0bf2spgabsutwxnzt manager2 Ready Active Reachable
if0kmzp4ww3oy57y7cha7v36t worker1 Ready Active
jgg61cujzaeb3du5796fm0x2g worker2 Ready Active
Leader
表示當然集群的頭,Reachable
可以理解為頭的候選人,頭一掛掉它就頂上去了。
需要註意的是,我當天配置好之後,把所有的 Docker 主機都stop
了,然後隔天重新start
之後,出現了下麵問題:
docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.
好像是集群節點丟失了頭,相關問題:如何處理 docker swarm 集群"The swarm does not have a leader"問題,按照文章進行解決:
$ docker swarm init --force-new-cluster
Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on different interfaces (10.0.2.15 on eth0 and 192.168.99.102 on eth1) - specify one with --advertise-addr
$ docker swarm init --force-new-cluster --advertise-addr 192.168.99.102
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
$ docker node ls
卡死
$ docker-machine restart manager1
重啟不了,一直轉圈
沒辦法,後來我只能刪掉四個 Docker 主機,重新進行創建了。
3. Docker Service 部署單個集群服務
在部署集群服務之前,我們需要做些準備工作,因為 Docker 主機中沒有配置 Docker 鏡像加速地址,所以在拉取官方鏡像的時候,肯定會非常慢,除了配置 Docker 鏡像加速地址之外,我們還可以使用 Docker 私有鏡像倉庫,來解決這個問題。
參考文章:Ubuntu Docker Registry 搭建私有倉庫
這邊,我再簡單說明下配置步驟,首先,在 Mac OS 上執行下麵命令:
$ docker run -d -v /Users/xishuai/Documents/Docker:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
$ docker tag nginx 192.168.99.1:5000/nginx:latest &&
docker push 192.168.99.1:5000/nginx:latest &&
docker pull 192.168.99.1:5000/nginx:latest
$ curl http://192.168.99.1:5000/v2/_catalog
{"repositories":["nginx"]}
我們在 Mac OS 上創建了一個私有倉庫容器,並把nginx
鏡像放到私有倉庫中,因為沒有使用 Https,所以在拉取和推送鏡像的時候,會報如下錯誤(Mac OS 和 Docker 主機都會報錯):
$ docker pull 192.168.99.1:5000/nginx:latest
The push refers to a repository [192.168.99.1:5000/nginx]
Get https://192.168.99.1:5000/v1/_ping: http: server gave HTTP response to HTTPS client
解決方式,我們需要分別在四個 Docker 主機中添加配置(Docker for Mac 在管理界面配置即可),命令:
$ sudo touch /etc/docker/daemon.json &&
sudo chmod 777 /etc/docker/daemon.json &&
sudo echo '{ "insecure-registries": ["192.168.99.1:5000"] }' > /etc/docker/daemon.json
然後重啟四個 Docker 主機(Docker for Mac 也需要重啟),命令:
$ docker-machine restart manager1 &&
docker-machine restart manager2 &&
docker-machine restart worker1 &&
docker-machine restart worker2
上面比較啰嗦,我們接下來正式部署集群服務,還是拿nginx
鏡像做為示例,命令(docker service create
命令詳細說明):
$ docker service create --replicas 4 -p 8088:80 --name nginx 192.168.99.1:5000/nginx:latest
ap8h8srb8yh3mni0h2nz61njz
overall progress: 4 out of 4 tasks
1/4: running [==================================================>]
2/4: running [==================================================>]
3/4: running [==================================================>]
4/4: running [==================================================>]
verify: Service converged
需要註意的是,--replicas 4
表示創建服務的實例個數(預設是一個),啥意思?比如4,就是在四個 Docker 主機上,分別創建一個nginx
服務,如果是3,那就是三個 Docker 主機,或者你可以理解為 Docker 主機的個數,另外,REPLICAS
會有進度顯示,並且執行是非同步的。
我們也可以手動設置實例個數,命令:
$ docker service scale nginx=4
部署好服務後,我們就可以進行查看了,命令:
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
ap8h8srb8yh3 nginx replicated 4/4 192.168.99.1:5000/nginx:latest *:8080->8080/tcp
$ docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l2rdrwzs5zog nginx.1 192.168.99.1:5000/nginx:latest manager1 Running Running about a minute ago
vsfczzbwanx3 nginx.2 192.168.99.1:5000/nginx:latest manager2 Running Running about a minute ago
qtbgw5h6dsi9 nginx.3 192.168.99.1:5000/nginx:latest worker Running Running about a minute ago
za2ejnvb3n6z nginx.4 192.168.99.1:5000/nginx:latest worker2 Running Running about a minute ago
我們任意使用四個 Docker 主機中的一個 IP 地址,瀏覽器打開:http://192.168.99.100:8088/
4. Docker Stack 部署多個集群服務,以及 GUI 管理頁面
docker service
部署的是單個服務,我們可以使用docker stack
進行多服務編排部署,使用的同樣是docker-compose.yml
配置文件,示例:
version: "3"
services:
nginx:
image: 192.168.99.1:5000/nginx:latest
ports:
- 8088:80
deploy:
mode: replicated
replicas: 4
visualizer:
image: 192.168.99.1:5000/dockersamples/visualizer:latest
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
portainer:
image: 192.168.99.1:5000/portainer/portainer:latest
ports:
- "9000:9000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
如上所示,我們總共需要部署三個服務,出了nginx
服務作為示例之外,visualizer
(官方地址)和portainer
(官方地址)都是集群 GUI 管理服務。
部署命令:
$ docker stack deploy -c docker-compose.yml deploy-demo
Creating service deploy-demo_nginx
Creating service deploy-demo_visualizer
Creating service deploy-demo_portainer
部署成功之後,我們可以查看具體詳情,命令:
$ docker stack ls
NAME SERVICES
deploy-demo 3
查看visualizer
GUI 集群管理,瀏覽器打開:http://192.168.99.100:8080/
查看portainer
GUI 集群管理,需要先配置賬號信息,瀏覽器打開:http://192.168.99.100:9000/
可以看到,portainer
比visualizer
強大太多了,甚至我們所有的操作都可以在portainer
上完成。
5. docker-machine、docker swarm、docker node、docker service 和 docker stack 常用命令
docker-machine 常用命令
命令 | 說明 |
---|---|
docker-machine create | 創建一個 Docker 主機(常用-d virtualbox ) |
docker-machine ls | 查看所有的 Docker 主機 |
docker-machine ssh | SSH 到主機上執行命令 |
docker-machine env | 顯示連接到某個主機需要的環境變數 |
docker-machine inspect | 輸出主機更多信息 |
docker-machine kill | 停止某個主機 |
docker-machine restart | 重啟某台主機 |
docker-machine rm | 刪除某台主機 |
docker-machine scp | 在主機之間複製文件 |
docker-machine start | 啟動一個主機 |
docker-machine status | 查看主機狀態 |
docker-machine stop | 停止一個主機 |
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 rm | 刪除某個節點(-f 強制刪除) |
docker node inspect | 查看節點詳情 |
docker node demote | 節點降級,由管理節點降級為工作節點 |
docker node promote | 節點升級,由工作節點升級為管理節點 |
docker node update | 更新節點 |
docker node ps | 查看節點中的 Task 任務 |
docker service 常用命令
命令 | 說明 |
---|---|
docker service create | 部署服務 |
docker service inspect | 查看服務詳情 |
docker service logs | 產看某個服務日誌 |
docker service ls | 查看所有服務詳情 |
docker service rm | 刪除某個服務(-f 強制刪除) |
docker service scale | 設置某個服務個數 |
docker service update | 更新某個服務 |
docker stack 常用命令
命令 | 說明 |
---|---|
docker stack deploy | 部署新的堆棧或更新現有堆棧 |
docker stack ls | 列出現有堆棧 |
docker stack ps | 列出堆棧中的任務 |
docker stack rm | 刪除堆棧 |
docker stack services | 列出堆棧中的服務 |
docker stack down | 移除某個堆棧(不會刪除數據) |
參考資料:
- Get Started, Part 4: Swarms
- Docker 三劍客之 Docker Swarm
- Docker Swarm 入門一篇文章就夠了
- Docker 的命令之集群節點管理 Swarm node
- docker service 命令
- Docker 命令行參考(37) – docker service create 創建一個服務
- Docker Machine 是什麼?
- docker swarm 學習命令整理