在Docker中拾弃,鏡像是一個輕量級的值桩,獨立的可執(zhí)行程序包,包含運行一個軟件所需的所有東西豪椿,包括代碼奔坟、運行環(huán)境、庫搭盾、環(huán)境變量和配置文件咳秉。容器是鏡像的運行實例,默認情況下鸯隅,它與主機環(huán)境完全隔離澜建,只有在配置時才訪問主機文件和端口。
在《Docker集群的創(chuàng)建與管理》中蝌以,設置了一個運行Docker的機器集群炕舵,并部署了一個應用程序,容器在多臺機器上運行「現(xiàn)在你可以了解分布式應用程序?qū)哟谓Y(jié)構(gòu)的頂層:堆棧咽筋。堆棧是一組相互關聯(lián)的服務,它們可以共享依賴關系徊件,并且可以一起協(xié)調(diào)和縮放奸攻。單個堆棧能夠定義和協(xié)調(diào)整個應用程序的功能蒜危。
添加一個新服務并重新部署
將服務添加到docker-compose.yml
文件很容易,首先添加一個免費的可視化器服務睹耐,使我們能看到是如何調(diào)度容器舰褪。在編輯器中打開docker-compose.yml
,并用下面的代碼替換它的內(nèi)容:
version: "3"
services:
web:
# 用你的名稱和鏡像細節(jié)替換username/repo:tag
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:
這里唯一新增的就是名為visualizer
的web
對等服務疏橄,在這里可以看到兩個新東西:volumes
密鑰占拍,賦予visualizer
訪問Docker的主機套接字文件的權限,以及一個placement
密鑰捎迫,確保此服務只能在集群管理器上運行晃酒。這個由Docker創(chuàng)建的開源項目構(gòu)建的容器可以顯示集群上運行的Docker服務。
確保你的終端被配置為與myvm1進行通信窄绒,運行docker-machine ls
列出機器贝次,并確保已連接到myvm1,如果需要可以重新運行docker-machine env myvm1
彰导,然后運行給定的命令來配置終端蛔翅。在管理器上重新運行docker stack deploy
命令,任何需要更新的服務都將被更新:
$ docker stack deploy -c docker-compose.yml getstartedlab
在docker-compose.yml
文件中可以看到位谋,visualizer
在端口8080上運行山析,通過運行docker-machine ls
來獲取其中一個節(jié)點的IP地址,轉(zhuǎn)到8080端口的IP地址掏父,將看到visualizer
正在運行:
visualizer
的單個副本按照預期在管理器上運行笋轨,并且網(wǎng)絡的5個實例遍布整個集群,可以通過運行docker stack ps <stack>
來證實這個可視化:
$ docker stack ps getstartedlab
visualizer
是一個獨立的服務赊淑,可以在任何包含它的應用程序中運行爵政,它不依賴于其他任何東西。現(xiàn)在創(chuàng)建一個具有依賴性的服務陶缺,Redis服務將提供訪問者計數(shù)器钾挟。
數(shù)據(jù)持久化
再次通過相同的工作流程來添加一個用于存儲應用程序數(shù)據(jù)的Redis數(shù)據(jù)庫,保存這個新的docker-compose.yml
文件饱岸,最后添加一個Redis服務:
version: "3"
services:
web:
# 用你的名稱和鏡像細節(jié)替換username/repo:tag
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:
Redis在Docker庫中有一個官方鏡像掺出,并且已經(jīng)被授予redis
的簡短鏡像名稱,所以在這里沒有username/repo
伶贰。Redis端口6379已經(jīng)由Redis預先配置好蛛砰,從容器中暴露給主機罐栈,在docker-compose.yml
文件中黍衙,將它從主機暴露給外部,這樣就可以為任何節(jié)點到Redis桌面管理器中荠诬,并管理這個Redis實例琅翻。
最重要的是位仁,redis
規(guī)范中有幾件事情使數(shù)據(jù)在這個堆棧的部署之間持續(xù)存在:redis
總是在管理器上運行,所以它總是使用相同的文件系統(tǒng)方椎;redis
在主機的文件系統(tǒng)中訪問一個任意目錄作為容器內(nèi)部的/data
聂抢,這是Redis存儲數(shù)據(jù)的地方√闹冢總之琳疏,這是在Redis數(shù)據(jù)的主機物理文件系統(tǒng)中創(chuàng)建“真實來源”。如果沒有這個闸拿,Redis將把它的數(shù)據(jù)存儲在容器文件系統(tǒng)中的/data
中空盼,如果這個容器被重新部署的話,這些數(shù)據(jù)將被清除新荤。
這個真實來源有兩個組成部分:placement
在Redis服務上的placement
約束揽趾,確保它始終使用相同的主機;創(chuàng)建的volumes
允許容器作為/data
(在Redis容器內(nèi))訪問/data
(在主機上)苛骨,在容器來來去去的時候篱瞎,存儲在指定主機上的/data
文件將會持續(xù)存在,從而保持連續(xù)性痒芝。
在管理器上創(chuàng)建一個/data
目錄:
$ docker-machine ssh myvm1 "mkdir ./data"
確保終端被配置為與myvm1進行通信俐筋,運行docker-machine ls
列出機器,并確保已連接到myvm1严衬,如果需要可以重新運行docker-machine env myvm1
校哎,然后運行給定的命令來配置終端。在管理器上重新運行docker stack deploy
命令瞳步,任何需要更新的服務都將被更新:
$ docker stack deploy -c docker-compose.yml getstartedlab
運行docker service ls
以驗證這三個服務是否按預期運行:
$ docker service ls
查看您的某個節(jié)點的網(wǎng)頁闷哆,您將看到訪客計數(shù)器的結(jié)果,該計數(shù)器現(xiàn)在已經(jīng)存在并將信息存儲在Redis上:
另外单起,使用任一節(jié)點的IP地址8080端口訪問可視化器抱怔,將看到隨web
和visualizer
服務一起運行的redis
服務: