Docker 入門筆記 4
- Containers
- Services
- Swarms
- Stacks
什麼是 Swarm clusters
考慮將Docker執行在一組機器上作為一個cluster群集使用,此時我們需要一個工具幫助我們建立和管理這些docker主機。 Swarm就是這樣一個工具,有了它我們可以通過一個 Swarm manager執行Docker命令來控制cluster。使用Swarm操作叢集,會使使用者感覺就像是在一臺主機上進行操作。
在Swarm中,只能通過Swarm managers 來執行命令或者授權其他機器作為worker加入swarm。而worker只負責提供計算能力無權控制其他機器工作。
Swarm是執行在Linux機器上的守護程式,它所繫結的網路介面與獨立Docker例項相同(http/2375或https/2376)。Swarm 守護程序可以與標準的Docker客戶端相連線並接受其傳送來的資訊,之後,Swarm服務會對來自Docker客戶端的指令資訊進行配置,最後通過代理的方式把資訊傳送給不同Docker的守護程序,Swarm服務同時也監聽著標準的Docker埠。 比如,Swarm會基於不同的打包演算法並結合Docker守護程序在啟動時指定好標籤(tags),把create命令分配到不同的Docker守護程序上來執行。根據這一特性,使用者可以建立由不同的Docker主機所構成的分割槽叢集(partitioned cluster)並且將整個叢集在邏輯上以一個單一的Docker終端的形式公開給使用者,Swarm使這個過程變得極其簡單。
Swarm守護程序本身相當於是一個排程器和一個路由器。它實際上並沒有執行容器,也就是說,如果Swarm服務停止了,它在終端Docker主機上已分配好的容器仍然是開啟的。另外,由於它不處理任何網路路由(網路連線需要被直接傳送到後端的Docker主機上),即使Swarm守護程序意外終止,執行的容器仍然可用。當Swarm從這樣的崩潰中恢復,它依然能夠查詢終端以重建其元資料的列表。
什麼是Docker machine
簡單的說,Docker Machine 是一個安裝和管理 Docker 的工具。它有自己的命令列工具:docker-machine 以及Docker engine client。
我們可以在本地系統上安裝Docker Machine, 然後通過docker machine 在一個或者多個虛擬機器上安裝docker engine。
安裝Docker machine
$ curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
確認安裝成功
$ docker-machine version
docker-machine version 0.13.0, build 9ba6da9
配置bash補全指令碼
可以選擇安裝指令碼在 /etc/bash_completion.d 或者 /usr/local/etc/bash_completion.d 目錄下
$ scripts=( docker-machine-prompt.bash docker-machine-wrapper.bash docker-machine.bash ); \
for i in "${scripts[@]}"; \
do sudo wget https://raw.githubusercontent.com/docker/machine/v0.13.0/contrib/completion/bash/${i} \
-P /etc/bash_completion.d; done
修改~/.bashrc, 在PS1中新增 $(__docker_machine_ps1),以便啟用docker-machine shell prompt
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]:\[$(__docker_machine_ps1)\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
解除安裝Docker machine
# To remove all machines:
$docker-machine rm -f $(docker-machine ls -q)
# Remove the executable:
$rm $(which docker-machine)
安裝 virtualbox
sudo apt install virtualbox
建立swarm
Swarm大致工作流程如下:
- Docker主機服務(伺服器上的Docker守護程序)通過–label key=value被啟動並對網路進行監聽。
- Swarm守護程序被啟動並指向一個檔案,這個檔案包含有構成叢集的主機以及這些主機所監聽的埠列表。
- Swarm與每個Docker主機互動並確定他們的標記、健康狀況以及資源使用量,並維護後端和它們元資料的列表。
- 客戶端通過它的網路埠(2375)與Swarm互動。與Swarm的互動方式與Docker互動的方式類似:建立、銷燬、執行、依附(attach)並獲得執行容器的日誌以及其他相關內容。
- 當一個命令發出給Swarm,Swarm會:
- 基於提供的constraint標籤、終端的健康程度以及排程演算法來決定把命令傳送到哪裡。
- 針對合適的Docker守護程序執行命令。
- 返回結果的格式與Docker守護程序相同。
使用docker machine 建立一對虛擬機器
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
檢視建立的VMs以及IP
$docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v17.09.1-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.09.1-ce
初始化 Swarm 並新增node
#通過docker-machine ssh到 myvm1, 並將其設為swarm manager
$docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100"
Swarm initialized: current node (llmexl5oj50imsntlkcm9nsxk) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-6001gprr2xe5suwtik7ajuk0vy1wtlabzjsnjdz3157fp05in9-8nem0f30uv6h3gzw7jflxrrdr 192.168.99.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Ports 2377 and 2376
2377是 swarm management port 用於 swarm init 以及 swarm join
2376是 docker machine 返回的machine ip包含2376埠,這個埠實際是Docker daemon的監聽埠
根據 docker init 返回的內容,新增myvm2 到swarm 群集
$ docker-machine ssh myvm2 "docker swarm join \
> --token SWMTKN-1-6001gprr2xe5suwtik7ajuk0vy1wtlabzjsnjdz3157fp05in9-8nem0f30uv6h3gzw7jflxrrdr \
> 192.168.99.100:2377"
This node joined a swarm as a worker.
檢視建立的群集狀態
$ docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
llmexl5oj50imsntlkcm9nsxk * myvm1 Ready Active Leader
nnccrt9u7arepsd1lrblvpuct myvm2 Ready Active
部署app到swarm cluster上
配置docker-machine shell 指向swarm manager。 之後的shell命令都會發往myvm1
$eval $(docker-machine env myvm1)
確認myvm1 是active machine
[myvm1]$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 * virtualbox Running tcp://192.168.99.100:2376 v17.09.1-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.09.1-ce
在swarm manager上部署app
[myvm1]$ docker stack deploy -c docker-compose.yml myClusterApp
Creating network myClusterApp_webnet
Creating service myClusterApp_web
檢視 stack 部署情況,我們可以看見 service 被分佈到了不同nodes 上
[myvm1]$ docker stack ps myClusterApp
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
rpim63c3hp7s myClusterApp_web.1 misterchi/repositorytest:hello myvm2 Running Running about a minute ago
n1tqaa1amsno myClusterApp_web.2 misterchi/repositorytest:hello myvm2 Running Running about a minute ago
ztlo0ybs1k37 myClusterApp_web.3 misterchi/repositorytest:hello myvm1 Running Running about a minute ago
0okow9m17jre myClusterApp_web.4 misterchi/repositorytest:hello myvm2 Running Running about a minute ago
ogxanth75jno myClusterApp_web.5 misterchi/repositorytest:hello myvm1 Running Running about a minute ago
用 docker-machine env 或者 docker-machine ssh 連線VMs
- docker-machine env: 使用 eval $(docker-machine env ) 可以使當前shell 直接指向指定的nodes
- docker-machine ssh “” : 新登入指定node 然後執行命令,再退出。
測試部署在cluster上的 app, 反覆執行可以看見5個不同的 hostname 迴圈出現。
$ curl http://192.168.99.100
<h3>Hello World!</h3><b>Hostname:</b> 18c98332c414<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
$ curl http://192.168.99.101
<h3>Hello World!</h3><b>Hostname:</b> 18c98332c414<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
移除重啟
移除worker : docker-machine ssh myvm2 “docker swarm leave”
移除Manager :docker-machine ssh myvm1 “docker swarm leave –force”
# 拆除 swarm stack
[myvm1]$ docker stack rm myClusterApp
Removing service myClusterApp_web
Removing network myClusterApp_webnet
unset docker-machine 相關的shell 設定
eval $(docker-machine env -u)
停止/啟動 docker machine
docker-machine ls
docker-machine start <machine-name>
docker-machine stop <machine-name>
常用命令
docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1 # View basic information about your node
docker-machine ssh myvm1 "docker node ls" # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>" # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker" # View join token
docker-machine ssh myvm1 # Open an SSH session with the VM; type "exit" to end
docker node ls # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave" # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1 # Start a VM that is currently not running
docker-machine env myvm1 # show environment variables and command for myvm1
eval $(docker-machine env myvm1) # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app> # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u) # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q) # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images