docker多主機管理
前面我們的實驗環境中只有一個 docker host,所有的容器都是運行在這一個 host 上的。但在真正的環境中會有多個 host,容器在這些 host 中啟動、運行、停止和銷毀,相關容器會通過網絡相互通信,無論它們是否位於相同的 host。
對於這樣一個 multi-host 環境,我們將如何高效地進行管理呢?
我們面臨的第一個問題是:為所有的 host 安裝和配置 docker。
對於多主機環境手工方式效率低且不容易保證一致性,針對這個問題,docker 給出的解決方案是 Docker Machine。
用 Docker Machine 可以批量安裝和配置 docker host,這個 host 可以是本地的虛擬機、物理機,也可以是公有雲中的雲主機。
Docker Machine 為這些環境起了一個統一的名字:provider。對於某個特定的 provider,Docker Machine 使用相應的 driver 安裝和配置 docker host
安裝docker machine
在172.20.10.2主機上面安裝docker machine
然后通過docker-machine命令在172.20.10.7和172.20.10.9兩個主機上部署docker
官方安裝文檔:https://docs.docker.com/machine/install-machine/
第一步:根據官方文檔進行安裝
[root@ken1 ~]# base=https://github.com/docker/machine/releases/download/v0.16.0 && curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && sudo install /tmp/docker-machine /usr/local/bin/docker-machine
第二步:查看版本
[root@ken1 ~]# docker-machine version docker-machine version 0.16.0, build 702c267f
為了得到更好的體驗,我們可以安裝 bash completion script,這樣在 bash 能夠通過 tab 鍵補全 docker-mahine 的子命令和參數
第一步:進入到/etc/bash_completion.d目錄下
執行如下的命令
[root@ken1 ~]# cd /etc/bash_completion.d && base=https://raw.githubusercontent.com/docker/machine/v0.16.0 for i in docker-machine-prompt.bash docker-machine-wrapper.bash docker-machine.bash do sudo wget "$base/contrib/completion/bash/${i}" -P /etc/bash_completion.d done
第二步:查看下載的腳本文件
[root@ken1 bash_completion.d]# ls docker-machine.bash docker-machine-wrapper.bash gluster salt.bash docker-machine-prompt.bash git iprutils yum-utils.bash
第三步:使腳本生效
[root@ken1 bash_completion.d]# source /etc/bash_completion.d/docker-machine-prompt.bash
第四步:將如下代碼添加到~/.bashrc:
[root@ken ~]# source .bashrc
其作用是設置 docker-machine 的命令行提示符,不過要等到部署完其他兩個 host 才能看出效果。
PS1='[\u@\h \W$(__docker_machine_ps1)]\$ '
上述操作只需要根據官方文檔說明進行操作即可。
Docker Machine 已經就緒
創建machine
對於 Docker Machine 來說,術語 Machine 就是運行 docker daemon 的主機。
“創建 Machine” 指的就是在 host 上安裝和部署 docker。
第一步:查看當前的machine
先執行 docker-machine ls 查看一下當前的 machine:
[root@ken1 ~]# docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
當前還沒有 machine,接下來我們創建第一個 machine: host1 - 172.20.10.7。
如果出現下面的錯誤:
[root@ken1 ~]# docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
-bash: __docker_machine_ps1: command not found
執行下面的命令:
[root@ken1 ~]# source /etc/bash_completion.d/docker-machine-prompt.bash [root@ken1 ~]# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
第二步:發送密鑰
創建 machine 要求能夠無密碼登錄遠程主機,所以需要先通過如下命令將 ssh key 拷貝到 172.20.10.7:
[root@ken1 ~]# ssh-copy-id 172.20.10.7
第三步:創建machine
一切准備就緒,執行 docker-machine create 命令創建 host1:
[root@ken ~]# docker-machine create --driver generic --generic-ip-address=172.20.10.7 host1 Creating CA: /root/.docker/machine/certs/ca.pem Creating client certificate: /root/.docker/machine/certs/cert.pem Running pre-create checks... Creating machine... (host1) No SSH key specified. Assuming an existing key at the default location. Waiting for machine to be running, this may take a few minutes... Detecting operating system of created instance... Waiting for SSH to be available... Detecting the provisioner... Provisioning with centos... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... Checking connection to Docker... Docker is up and running! To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env host1
因為我們是往普通的 Linux 中部署 docker,所以使用 generic driver,其他 driver 可以參考文檔 https://docs.docker.com/machine/drivers/。
--generic-engine-port:用於Docker守護程序的端口(注意:此標志不適用於boot2docker)。
--generic-ip-address:主機所需的 IP地址。
--generic-ssh-key:SSH用戶私鑰的路徑。
--generic-ssh-user:用於連接的SSH用戶名。
--generic-ssh-port:用於SSH的端口。
由於 Docker Engine 的官方 repo 在國內訪問非常不穩定,在創建機器時可能會出現 Error Creating machine: Error running provisioning: error installing docker 之類的錯誤。
目前我沒有找到好的解決方法,只能多次嘗試。網上有人推薦使用國內源,使用--engine-registry-mirror 指定。
第四步:查看machine
[root@ken ~]# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS host1 - generic Running tcp://172.20.10.7:2376 v18.09.0
另外machine主機的主機名已經設置為host1
第五步:使用同樣的額方法創建host2
[root@ken ~]# docker-machine create --driver generic --generic-ip-address=172.20.10.9 host2
查看machine
[root@ken ~]# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS host1 - generic Running tcp://172.20.10.7:2376 v18.09.0 host2 - generic Running tcp://172.20.10.9:2376 v18.09.1
管理machine
用 docker-machine 創建machine 的過程很簡潔,非常適合多主機環境。除此之外,Docker Machine 也提供了一些子命令方便對 machine 進行管理。其中最常用的就是無需登錄到 machine 就能執行 docker 相關操作。
Docker Machine 則讓這個過程更簡單。docker-machine env host1顯示訪問 host1 需要的所有環境變量:
[root@ken ~]# docker-machine env host1 export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://172.20.10.7:2376" export DOCKER_CERT_PATH="/root/.docker/machine/machines/host1" export DOCKER_MACHINE_NAME="host1" # Run this command to configure your shell: # eval $(docker-machine env host1)
根據提示,執行 eval $(docker-machine env host1):
[root@ken ~]# eval $(docker-machine env host1) [root@ken ~ [host1]]#
然后,就可以看到命令行提示符已經變了,其原因是我們之前在$HOME/.bashrc 中配置了 PS1='[\u@\h \W$(__docker_machine_ps1)]\$ ',用於顯示當前 docker host。
在此狀態下執行的所有 docker 命令其效果都相當於在 host1 上執行,例如啟動一個 busybox 容器:
[root@ken ~ [host1]]# docker run -itd busybox 9c469371692c1aa465cc59ab6c6660c966871d8f00380658476e8a5284e63130 [root@ken ~ [host1]]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9c469371692c busybox "sh" 4 seconds ago Up 2 seconds vibrant_lamarr e69a5bec56eb weaveworks/weave:2.5.1 "/home/weave/weaver …" About an hour ago Up 14 minutes weave
執行 eval $(docker-machine env host2) 切換到 host2:
[root@ken ~ [host1]]# eval $(docker-machine env host2)
[root@ken ~ [host2]]#
docker-machine scp 可以在不同 machine 之間拷貝文件,比如:
docker-machine scp host1:/tmp/a host2:/tmp/b