Docker 入門筆記 4 - 用Swarm部署服務

本筆記參考 https://docs.docker.com/get-started/part4/

  • 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

安裝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>

Swarm ingress network

移除重啓

移除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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章