目錄html
friendlyhello
鏡像發佈到registry。咱們會在這裏用到這個鏡像username
, repo
, 和 tag
: docker run -p 80:80 username/repo:tag
, 而後查看 http://localhost/
。docker-compose.yml
在第三部分,你使用了第二部分中編寫的引用,而且,經過將它轉換爲服務來 定義它應該如何在生產環境中運行,在此過程當中將其擴展5倍。node
在這裏,會將此應用部署到集羣上,在多臺機器上運行它。經過將多臺機器加入被稱爲swarm的「Dockerized」集羣,是多容器、多機器稱爲可能。linux
一個swarm是一組加入集羣的,運行容器的機器。在此以後,你能夠繼續按照習慣來使用docker命令,但如今這些命令案經過swarm manager運行在集羣上。Swarm中的機器能夠是物理機,也能夠是虛擬機。加入Swarm後,他們被稱爲nodegit
swarm manager 可使用多種策略來運行容器,例如:github
Swarm管理器是swarm中惟一能夠執行命令,或受權其餘機器worker加入swarm的機器。Worker只是用來提供生產力,它並無權限告訴其餘機器本身能夠作什麼,不能夠作什麼。web
到目前爲止,咱們是在本地機器上以單機模式使用Docker。但Docker也可使用swarm的切換到到swarm模式,開啓swarm模式能夠立刻使當前機器成爲Swarm管理器。以後,Docker就能夠在你管理的swarm上執行你的命令,而不只僅只是當前的機器。docker
一個swarm由多個節點組成,節點能夠是物理機或虛擬機。
基本的概念至關簡單:shell
docker swarm init
能夠開啓swarm模式,並使當前的機器成爲swarm管理器docker swarm join
,使其做爲worker加入swarm本地機器上的虛擬機(MAC, LINUX, WINDOWS 7 AND 8)
你須要一個能夠建立虛擬機的hypervisor,能夠安裝Oracle VirtualBox。windows
注意:若是你使用的是安裝了Hyper-V的windows系統,例如Win10,那就不須要安裝VirtualBox,使用Hyper-V便可。若是你正在使用Docker Toolbox,那麼你應該已經安裝了VirtualBox,能夠愉快的開始了。api
如今,使用VirtualBox驅動 用 docker-machine
建立兩臺虛擬機:
docker-machine create --driver virtualbox myvm1 docker-machine create --driver virtualbox myvm2
如今你已建立了兩臺虛擬機,名字叫myvm1
和myvm2
。
使用下面的命令列出虛擬機並獲取他們的IP:
docker-machine ls
下面是個命令的輸出樣例:
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Running tcp://192.168.99.100:2376 v17.06.2-ce myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.06.2-ce
第一臺機器做爲管理器,運行命令和驗證workers加入swarm,第二臺機器爲worker。
你可使用 docker-machine ssh
給你的VMs發送命令。使用 docker swarm init
將vm1
變爲swarm管理器,其輸入以下:
$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>" Swarm initialized: current node <node ID> is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token <token> \ <myvm ip>:<port> To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
✪ 2377 和2367端口
docker swarm init
和docker swarm join
始終使用2377端口(swarm管理器的端口),沒有端口時採用默認端口。
docker-machine ls
返回機器的IP地址和2367端口,2367端口是Docker守護進程的端口。這個端口被其餘程序佔用時會報錯,
✪ 使用ssh出現問題?嘗試一下 --native-shh參數
Docker的機器支持讓你使用系統的SSH,若是由於一些緣由,在給swarm管理器發送命令時遇到問題,只要在調用ssh命令時指定--native-ssh
參數便可。
docker-machine --native-ssh ssh myvm1 ...
如你所見,對 docker swarm init
的響應包含一個預置的 docker swarm join
命令,你能夠在任何你要添加的節點上執行。複製這個命令,經過docker-machine ssh
把它發送給myvm2
,使myvm2
做爲一個worker加入swarm。
$ docker-machine ssh myvm2 "docker swarm join \ --token <token> \ <ip>:2377" This node joined a swarm as a worker.
這樣咱們就建立咱們的第一個swarm。
在管理器上運行docker node ls
能夠查看這個swarm中的節點:
$ docker-machine ssh myvm1 "docker node ls" ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS brtu9urxwfd5j0zrmkubhpkbd myvm2 Ready Active rihwohkh3ph38fhillhhb84sk * myvm1 Ready Active Leader
✪ 脫離swarm
若是你想從新開始,你能夠在每一個節點執行docker swarm leave
最困難的部分已經結束了。如今你只須要在你的swam上重複第三部分的過程便可。但要注意,只有swarm管理器能夠運行Docker命令,worker只提供資源。
至此,你已經能夠經過使用docker-machine ssh
發送命令,來與VMs進行通訊。 另一種選擇是運行docker-machine env <machine>
來獲取並運行一個命令,該命令配置當前的shell以和VM上的Docker守護進程通訊。該方法適用於下面的步驟,由於它容許你使用本地的docker-compose.yml
文件「遠程」部署app,而不須要將其複製到其餘位置,
配置shell的命令因操做系統 Mac, Linux, or Windows 而有所不一樣,示例以下:
Mac、Linux
Mac或Linux上 DOCKER MACHINE的shell環境。
運行 docker-machine env myvm1
獲取配置shell的命令,以和myvm1進行通訊。
$ docker-machine env myvm1 export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.99.100:2376" export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1" export DOCKER_MACHINE_NAME="myvm1" # Run this command to configure your shell: eval $(docker-machine env myvm1)
運行給定的命令,來配置shell以和myvm1進行通訊。
eval $(docker-machine env myvm1)
運行docker-machine ls
來驗證 myvm1 如今是不是活動狀態,以下面的星號所示:
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 * virtualbox Running tcp://192.168.99.100:2376 v17.06.2-ce myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.06.2-ce
Windows
Windows上 DOCKER MACHINE的shell環境。
運行 docker-machine env myvm1
獲取配置shell的命令,以和myvm1進行通訊。
PS C:\Users\sam\sandbox\get-started> docker-machine env myvm1 $Env:DOCKER_TLS_VERIFY = "1" $Env:DOCKER_HOST = "tcp://192.168.203.207:2376" $Env:DOCKER_CERT_PATH = "C:\Users\sam\.docker\machine\machines\myvm1" $Env:DOCKER_MACHINE_NAME = "myvm1" $Env:COMPOSE_CONVERT_WINDOWS_PATHS = "true" # Run this command to configure your shell: # & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
運行給定的命令,來配置shell以和myvm1進行通訊。
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
運行docker-machine ls
來驗證 myvm1 如今是不是活動狀態,以下面的星號所示:
PS C:PATH> docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 * hyperv Running tcp://192.168.203.207:2376 v17.06.2-ce myvm2 - hyperv Running tcp://192.168.200.181:2376 v17.06.2-ce
如今咱們有了myvm1,咱們能夠將其做爲swarm管理器,經過第三部分中使用的docker stack deploy
命令來把app 和docker-compose.yml
的本地拷貝部署到 myvm1. 這個命令可能須要幾秒才能夠完成部署,部署須要一些時間來完成。 在swarm管理器上使用docker service ps <service_name>
命令來驗證全部的服務應被部署。
經過docker-machine
配置shell 連接到myvm1後,咱們仍能夠訪問本地主機上的文件。確保和以前的目錄相同,其下包括在第三部分中建立的docker-conmpose.yml
文件
和以前同樣,運行下面的命令將app部署到myvm1上:
docker stack deploy -c docker-compose.yml getstartedlab
就這樣,app被部署到到了swarm集羣上。
注意:若是你的鏡像保存在一個私有的registry上,你須要使用
docker login <your-registry>
登錄,而後你須要給上面的命令添加--with-registry-auth
參數,例如:
docker login registry.example.com docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
這會使用加密的WAL日誌把登錄token從本地client傳給部署了服務的swarm節點,有了這些信息,節點就能夠登陸到registry並拉取鏡像。
如今你可使用和第三部分中相同的docker命令。只是此次要注意服務(相關容器)在myvm1 和 myvm2上進行分配。
$ docker stack ps getstartedlab ID NAME IMAGE NODE DESIRED STATE jq2g3qp8nzwx getstartedlab_web.1 gordon/get-started:part2 myvm1 Running 88wgshobzoxl getstartedlab_web.2 gordon/get-started:part2 myvm2 Running vbb1qbkb0o2z getstartedlab_web.3 gordon/get-started:part2 myvm2 Running ghii74p9budx getstartedlab_web.4 gordon/get-started:part2 myvm1 Running 0prmarhavs87 getstartedlab_web.5 gordon/get-started:part2 myvm2 Running
使用
docker-machine env
和docker-machine ssh
鏈接VMs
- 設置你的shell像和myvm2通訊同樣,去和其餘機器進行通訊,只須要在相同或不一樣的shell中,從新運行
docker-machine env
,而後運行給定的命令鏈接到myvm2. 這裏特指當前shell。若是你改用一個未配置的shell或打開一個新的shell,你須要從新運行命令。運行docker-machine ls
列出機器,查看他們是什麼狀態,獲取IP地址並找出你鏈接的那一個(若是有的話)。要了解更多內容,請參考 Docker Machine getting started topics.- 或者你可使用
docker-machine ssh <machine> <command>
的形式包裝Docker命令,它能夠直接登陸到VM,但不會讓你當即能夠訪問本地主機上的文件。- 在Mac和Linux上,你可使用
docker-machine scp <file> <machine>:~
跨機器複製文件,但對於Windows用戶,須要是一個相似於Git Bash的Linux終端模擬器來完成該工做。本文演示了
docker-machine ssh
和docker-machine env
,這些內容經過docker-machine
CLI能夠在全部平臺上使用。
你可使用myvm1或myvm2的IP地址來訪問你的app。
你建立的網絡在他們之間進行了共享並進行了負載均衡。運行docker-machine ls
來獲取你的VMs的IP地址,並經過了瀏覽器訪問它們,打開後刷新(或者使用curl
訪問他們)。
會有五個容器ID會循環隨機顯示,這代表實現了負載均衡。
兩個IP地址均可以工做的緣由是swarm中的節點都參與了routing mesh(路由網格)。這確保了部署在在swarm中某個端口的服務使用將該端口保留給本身,不管實際運行的容器運行在哪一個節點。下面是一張圖表,對三節點集羣上一個在8080端口發佈的my-web
服務如何路由網格作了說明:
連接有問題?
請記住,要在swarm中使用 the ingress network(入口網絡),那在開啓swarm模式以前,你須要在swarm節點打開下面的端口:
- 端口 7946 TCP/UDP 用於容器網絡發現
- 端口 4789 UDP 用於容器ingress network(入口網絡)
如今開始你能夠作在第2、三部分學到的任何事情。
經過docker-compose.yml
能夠擴展app。
經過編輯代碼來改變app的行爲,而後從新構建 並推送一個新的鏡像。(爲此,須要按照以前構建app、發佈鏡像的步驟進行操做)
在任一狀況下,只須要簡單的再次運行docker stack deploy
就能夠部署這些更改。
你能夠在myvm2上使用docker swarm join
把任何機器(物理機和虛擬機)加入swarm,將資源加入集羣。以後只要運行docker stack deploy
,你的app就可使用新資源了。
你可使用docker stack rm
來刪除stack,例如:
docker stack rm getstartedlab
保留或刪除swarm
在某些時候你能夠刪除swarm,若是你想使用刪除,能夠在worker上使用docker-machine ssh myvm2 "docker swarm leave"
,在管理器上使用docker-machine ssh myvm1 "docker swarm leave --force"
,但後面咱們還要使用這個swarm,因此先保留它。
使用給定的命令你在取消當前shell中的docker-machine1
環境變量。
在Mac或Linux上的命令:
eval $(docker-machine env -u)
在Windows上的命令是:
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u | Invoke-Expression
這會斷開docker-machine
建立的虛擬機的shell連接,以後你能夠繼續使用同一個的shell,如今使用本地的docker
命令(例如:在mac上的docker 或者 windows上的docker)。要了解更多,請參考Machine topic on unsetting environment variables。
若是你要關閉你的本地主機,docker主機也會中止運行。你能夠運行docker-machine ls
來檢查機器的狀態。
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Stopped Unknown myvm2 - virtualbox Stopped Unknown
要重啓已關閉的機器,請運行:
docker-machine start <machine-name>
例:
$ docker-machine start myvm1 Starting "myvm1"... (myvm1) Check network to re-create if needed... (myvm1) Waiting for an IP... Machine "myvm1" was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. $ docker-machine start myvm2 Starting "myvm2"... (myvm2) Check network to re-create if needed... (myvm2) Waiting for an IP... Machine "myvm2" was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
下面是節使用的終端的一個記錄:
bash-3.2$ docker-machine create --driver virtualbox myvm1 Running pre-create checks... Creating machine... (myvm1) Copying /Users/johnmulhausen/.docker/machine/cache/boot2docker.iso to /Users/johnmulhausen/.docker/machine/machines/myvm1/boot2docker.iso... (myvm1) Creating VirtualBox VM... (myvm1) Creating SSH key... (myvm1) Starting the VM... (myvm1) Check network to re-create if needed... (myvm1) Waiting for an IP... 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 boot2docker... 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 myvm1 bash-3.2$ docker-machine create --driver virtualbox myvm2 Running pre-create checks... (myvm2) Unable to get the latest Boot2Docker ISO release version: Get https://api.github.com/repos/boot2docker/boot2docker/releases/latest: x509: certificate signed by unknown auth ority Creating machine... (myvm2) Unable to get the latest Boot2Docker ISO release version: Get https://api.github.com/repos/boot2docker/boot2docker/releases/latest: x509: certificate signed by unknown auth ority (myvm2) Copying /Users/johnmulhausen/.docker/machine/cache/boot2docker.iso to /Users/johnmulhausen/.docker/machine/machines/myvm2/boot2docker.iso... (myvm2) Creating VirtualBox VM... (myvm2) Creating SSH key... (myvm2) Starting the VM... (myvm2) Check network to re-create if needed... (myvm2) Waiting for an IP... 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 boot2docker... 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 myvm2 bash-3.2$ docker-machine ssh myvm1 "docker swarm init" 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.104 on eth 1) - specify one with --advertise-addr exit status 1 bash-3.2$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Running tcp://192.168.99.104:2376 v17.04.0-ce myvm2 - virtualbox Running tcp://192.168.99.105:2376 v17.04.0-ce bash-3.2$ docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.104:2377" Swarm initialized: current node (x500bs7lrweto9chkg6xq2ybd) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-197eaghawf5wqunblowkmgwjojv38ugtmscs943xrrz0jk6bpc-4uor1vdi4cleb5kqq2ri7s17g \ 192.168.99.104:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. bash-3.2$ docker-machine ssh myvm2 "docker swarm join \ > --token SWMTKN-1-197eaghawf5wqunblowkmgwjojv38ugtmscs943xrrz0jk6bpc-4uor1vdi4cleb5kqq2ri7s17g \ > 192.168.99.104:2377" This node joined a swarm as a worker. bash-3.2$ docker-machine ssh myvm1 "docker node ls" ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS fvenziy5o4xmziyzqxianzd65 myvm2 Ready Active x500bs7lrweto9chkg6xq2ybd * myvm1 Ready Active Leader bash-3.2$ ls docker-compose.yml bash-3.2$ cat docker-compose.yml version: "3" services: web: image: johndmulhausen/get-started:part1 deploy: replicas: 5 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet networks: webnet: bash-3.2$ docker-machine scp docker-compose.yml myvm1:~ docker-compose.yml bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab" Creating network getstartedlab_webnet Creating service getstartedlab_web bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 24 seconds ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 18 seconds ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 24 seconds ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 18 seconds ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 bash-3.2$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Running tcp://192.168.99.104:2376 v17.04.0-ce myvm2 - virtualbox Running tcp://192.168.99.105:2376 v17.04.0-ce bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 6b039c13ef31<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 5bf07e68c49b<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> b98b5bda92e2<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 802ad212c6a0<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 60c1fe7b8cb6<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 6b039c13ef31<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 5bf07e68c49b<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> b98b5bda92e2<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 802ad212c6a0<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 60c1fe7b8cb6<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> bash-3.2$ curl http://192.168.99.105 <h3>Hello World!</h3><b>Hostname:</b> 6b039c13ef31<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
在第四部分,咱們學習了swarm是什麼、swarm中的節點如何成爲管理器或worker、建立一個swarm、在其上部署一個應用程序。你能夠看到第三部門的核心命令並無改變,它們只是須要在swarm的master上運行。還能夠看到Docker網絡的強大能力,它能夠跨容器實現負載均衡,即便它們運行在不一樣的機器上。最後,咱們學習瞭如何在一個集羣上迭代和擴展app。
下面是一些命令,可用於和swarm和VMs進行交互:
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