目錄html
friendlyhello
鏡像發佈到registry。咱們會在這裏用到這個鏡像username
, repo
, 和 tag
: docker run -p 80:80 username/repo:tag
, 而後查看 http://localhost/
。docker-compose.yml
docker-machine ls
來驗證。若是機器已經中止運行,運行docker-machine start myvm1
啓動管理器,而後運行docker-machine start myvm2
來啓動worker。docker-machine ssh myvm1 "docker node ls"
來驗證。若是swarm已經運行,那兩個節點都會報告一個ready
狀態,若是沒有,按照第四部分中的部署swarm中的內容從新初始化swarm並加入worker。在第四部分,咱們學習瞭如何部署一個swarm(swarm是一個運行Docker的機器集羣),部署一個應用到swarm,其中容器在多臺機器上運行。
在本節,你會了解到分佈式程序層次結構的頂層:Stack。Stack一組相互關聯的服務,他們共享依賴關係,並能夠在一塊兒被編排和擴展。單個Stack能夠定義和協調整個應用程序的功能(雖然複雜度很高的應用可能須要使用多個Stack)。node
好消息是,在第三部分中當你建立Compose 文件並使用docker stack deploy
時,你就已經開始使用Stack技術。可是那只是運行在一臺單獨的主機上的一個單個的Stack,一般在生產環境裏不會這麼使用。在這裏,你能夠根據所學內容,使多個服務彼此關聯,並運行在多臺機器上。web
在docker-compose.yml
文件中添加一個服務很簡單。首先,咱們先添加一個可視化服務,看看swarm是如何調度容器的。
1.編輯docker-compose.yml
文件,使用下面的內容替換原內容。確保使用你的鏡像信息替換username/repo:tag
:redis
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet:
這裏惟一改變的地方是新增了和web同級的visualizer
服務。有兩個事情須要注意: volumes
密鑰讓可視化工具能夠攔截到Docker的主機套接字文件;placement
密鑰,確保該服務只運行在swarm管理器上,而不是worker上。這是由於這個容器是由Docker建立的開源項目構建的,使用圖示的方式顯示swarm上運行的docker服務。
咱們如今就來看看placement約束和volumes。docker
2.確保你的shell已被配置爲可與myvm1進行通訊。(完整的例子點這裏)shell
docker-machine ls
列出機器,並確保你已經鏈接到myvm1.docker-machine env myvm1
,而後運行指定的命令來配置shell。Mac 和 Linux上的命令:數據庫
eval $(docker-machine env myvm1)
Windows上的命令:瀏覽器
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
3.在管理器上從新運行docker stack deploy
,並更新須要更新的服務。bash
$ docker stack deploy -c docker-compose.yml getstartedlab Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm) Creating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
4.在可視化工具中查看
從Compose文件中能夠看出visualizer
運行在8080端口。運行docker-machine ls
獲取其中一個節點
的IP地址。訪問該IP地址的8080端口就能夠看到正在運行的visualizer:app
visualizer
的其中一個副本正如咱們預期的同樣運行在管理器上。咱們能夠運行docker stack ps <stack>
來確認這個
docker stack ps getstartedlab
該可視化工具是一個獨立的服務,能夠在stack裏任何包含它的app上運行。它不依賴任何其餘內容。如今咱們建立一個具備依賴關係的服務:提供瀏覽器計數器的Redis服務。
咱們能夠經過相同的步驟來添加一個Redis數據庫來存儲應用數據。
1.在docker-compose.yml文件末尾點擊一個Redis服務,並保存這個新文件。確保使用你的鏡像信息替換username/repo:tag
。
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet redis: image: redis ports: - "6379:6379" volumes: - "/home/docker/data:/data" deploy: placement: constraints: [node.role == manager] command: redis-server --appendonly yes networks: - webnet networks: webnet:
Docker庫中有一個Redis的官方鏡像,使用了一個很短的鏡像名字:redis
,所以這裏沒有使用username/repo
來表示。Redis的6379端口已經被預設爲從容器暴露給主機,在咱們的compose文件中,咱們將其從主機暴露給公網,所以,若是你選擇這樣作,你就能夠在任何節點鏈接Redis桌面管理器並管理該redis節點。
最重要的是,在該stack上部署redis期間,redis規範中有一些內容可使數據保持不變。
/data
目錄,用來存儲redis數據。總之,這會在主機的物理文件系統上爲Redis數據建立一個」真實數據源(官方叫「source of truth」)「。若是沒有這個,Redis會把數據保存在容器內的/data
目錄,若是容器被從新部署,那麼數據就會被刪除。
真實的數據源有兩部分組成:
./data
(主機上的)做爲/data
(redis容器上)來進行訪問。當容器建立刪除時,在指定主機上的。/data
下存儲的文件會一直存在,從而實現連續性。到這裏,咱們就作好了部署Redis stack的準備。
2.在管理器上建立./data
目錄
docker-machine ssh myvm1 "mkdir ./data"
3.確保你的shell已被配置爲可與myvm1通訊(點此查看完成例子)
docker-machine ls
,列出機器,確保你已經連接上myvm1
,以下條所示。docker-machine env myvm1
,而後運行給定的命令來配置shell。# Mac 或 Linux上的命令: eval $(docker-machine env myvm1) # Winidows上的命令: & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
4.再次運行docker stack deploy
$ docker stack deploy -c docker-compose.yml getstartedlab
5.運行docker service ls
來驗證三個服務是否按照預期運行。
$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS x7uij6xb4foj getstartedlab_redis replicated 1/1 redis:latest *:6379->6379/tcp n5rvhm52ykq7 getstartedlab_visualizer replicated 1/1 dockersamples/visualizer:stable *:8080->8080/tcp mifd433bti1d getstartedlab_web replicated 5/5 gordon/getstarted:latest *:80->80/tcp
6.在其中一個檢點上檢查web頁面,例如http://192.168.99.101
,查看瀏覽計數器的結果,該計數器已存在並將信息存儲在redis上。
另外,檢查任意節點IP地址上的8080端口的可視化工具,注意redis
服務與web服務和visualizer服務都在運行,
下面是本節內容的回顧:
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 node ls" ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS fvenziy5o4xmziyzqxianzd65 myvm2 Ready Active x500bs7lrweto9chkg6xq2ybd * myvm1 Ready Active Leader 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 15 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 15 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 15 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 15 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 Running Running 15 minutes ago bash-3.2$ ls docker-compose.yml bash-3.2$ more 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 visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] 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 service getstartedlab_visualizer Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ts3ud4mdf9qi getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 34 seconds ago kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 20 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 19 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 20 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 19 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 bash-3.2$ more docker-compose-WITH-REDIS.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 visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet redis: image: redis ports: - "6379:6739" volumes: - ./data:/data deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet: bash-3.2$ docker-machine scp docker-compose-WITH-REDIS.yml myvm1:~ docker-compose-WITH-REDIS.yml bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose-WITH-REDIS.yml getstartedlab" Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) Updating service getstartedlab_visualizer (id: uwd8tja3fpcpsy8kumk19orr8) Creating service getstartedlab_redis bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" PORTS o2xct1jotx55 getstartedlab_redis.1 redis:latest myvm1 Ready Rejected 1 second ago "invalid mount config for type… " tf1s212hfh9c \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 6 seconds ago "invalid mount config for type… " sizyxk5f0a5h \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 11 seconds ago "invalid mount config for type… " xd8s1ljsj9oq \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 16 seconds ago "invalid mount config for type… " 6h4wfo8nophs \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 21 seconds ago "invalid mount config for type… " ts3ud4mdf9qi getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 4 minutes ago kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 24 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 23 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 24 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 23 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 bash-3.2$ docker-machine ssh myvm1 "mkdir ./data" bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose-WITH-REDIS.yml getstartedlab" Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) Updating service getstartedlab_visualizer (id: uwd8tja3fpcpsy8kumk19orr8) Updating service getstartedlab_redis (id: oxlqkgq0vcmlzc5k1gk0rthdf) bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS xl9qttm6cg7v getstartedlab_redis.1 redis:latest myvm1 Running Running 32 seconds ago ihuhl093b492 getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 33 seconds ago 3jpjjz6hdmex getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago q9w4v6g14bxm getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 34 seconds ago w8z6vyae3cyb getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago xgpfmyhp2uub getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 34 seconds ago jdkgknm7wlip getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago 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> cfc0b7af2d99<br/><b>Visits:</b> 1 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 8900768882f9<br/><b>Visits:</b> 2 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 3adb6b451c2e<br/><b>Visits:</b> 3 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 8398387efdb7<br/><b>Visits:</b> 4 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 67e3e4c066ee<br/><b>Visits:</b> 5 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> cfc0b7af2d99<br/><b>Visits:</b> 6
本節瞭解到stack是所有一致運行的相互關聯的服務,而且,從第三節就開始使用stack。還學習了想stakc中添加服務,將它們加氟Compose文件中。最後,學習了經過位置約束和卷組的組合,你能夠建立一個永久的源來保存數據,通常在銷燬並重部署容器時,app的數據仍會存在。