9.1 使用Docker Compose 部署應用——簡介
多數的現代應用通過多個更小的服務相互協同來組成一個完整可用的應用握侧。比如一個簡單的示例應用可能由如下4個服務組成。
- Web前端
- 訂單管理
- 品類管理
- 后臺數據庫
將以上服務組織在一起抵拘,那就是一個可用的應用。部署和管理繁多的服務是困難的。而這正式Docker Compose要解決的問題躺枕。
Docker Compose 并不是通過腳本和各種冗長的docker命令來將應用組件組織起來肴颊,而是通過一個聲明式的配置文件描述整個應用氓栈,從而使用一條命令完成部署。
應用部署成功后婿着,還可以通過一系列的命令實現對其完整聲明周期的管理授瘦。甚至,配置文件還可以至于版本控制系統(tǒng)中進行存儲和管理竟宋。這是顯著的進步提完。
9.2 使用Docker Compose 部署應用——詳解
9.2.1 Docker Compose 的背景
Docker Compose的前身是Fig,這是一家由Orchard公司開發(fā)的強有力的工具丘侠,用于進行多容器管理徒欣。在14年,該公司被Docker公司收購蜗字,Fig也改名為Docker Compose打肝,該工具稱為了綁定在Docker引擎之上的外部工具。
Docker Compose 是一個需要在Docker主機上進行安裝的外部Python工具挪捕。使用它時粗梭,首先編寫定義多容器(多服務)應用的YAML文件,然后將其交由給docker-compose命令處理级零,Docker Compose就會基于Docker引擎API完成應用的部署断医。
9.2.2 安裝Docker Compose
我們可以直接下載Docker Compose的二進制包,然后修改下文件權限即可使用Docker Compose.
##下載二進制包妄讯,目前最新版本時1.24.1
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
##修改文件權限
sudo chmod +x /usr/local/bin/docker-compose
##查看docker-compose查看版本信息
docker-compose --version
9.2.3 Compose文件
Docker Compose使用YAML文件來定義多服務的應用孩锡。YAML是JSON的一個子集,因此也可以使用JSON亥贸。不過本章的例子全部采用YAML躬窜。Dockers Compose默認使用的文件名為 docker-compose.yml。當然炕置,用戶也可以使用 -f 參數指定具體文件荣挨。
下面是一個簡單的Compose文件的示例,它定義了一個包含兩個服務(web-fe和redis)的小型Flask應用朴摊。這是一個能夠對訪問者進行計數并將其保存到Redis的簡單的Web服務默垄。我們可以到GitHub上獲取代碼。
git clone https://github.com/nigelpoulton/counter-app.git
進入到拉取的代碼目錄甚纲,查看docker-compose.yml文件
version: "3.5"
services:
web-fe:
build: .
command: python app.py
ports:
- target: 5000
published: 5000
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: "redis:alpine"
networks:
counter-net:
networks:
counter-net:
volumes:
counter-vol:
首先我們可以看到這個文件的基本結構口锭,這里包含了4個一級key:version、services、networks鹃操、volumes韭寸。
version時必須指定的,而且總是位于文件的第一行荆隘。它定義了Compose文件格式(主要時API)的版本恩伺。建議使用最新版。注意椰拒,version并非定義Dockers Compose或者Docker引擎的版本號晶渠。這里我們使用的Compose文件都使用3及以上的版本。
services用于定義不同的應用服務燃观。上面定義了兩個服務:一個名為web-fe的web前端服務以及一個名為redis的內存數據庫服務褒脯。Docker Compose會將每個服務部署在各自的容器中。
networks用于指引Docker主機創(chuàng)建新的網絡仪壮。默認情況下憨颠,Docer Compose會創(chuàng)建bridge網絡。這是一種單主機網絡积锅,只能夠實現同一主機上容器的連接爽彤。當然,也可以使用driver屬性來指定不同類型的網絡缚陷。
volumes用于指引Docker來創(chuàng)建新的卷适篙。
這里分析下上面的Compose文件。
上面的例子中Compose文件使用的是v3.5版本的格式箫爷,定義了兩個服務嚷节,一個名為counter-net的網絡和一個名為counter-vol的卷。更多的信息是在services中虎锚,我們著重分析下硫痰。
在services部分定義了兩個二級key:web-fe和redis。他們各自定義了一個應用程序服務窜护。需要明確的是效斑,Docker Compose會將每個服務部署為一個容器,并且會使用key作為容器名字的一部分柱徙。本例中定義了兩個key,因此Docker Compose會部署兩個容器缓屠。
其中web-fe的服務定義中,包含了以下指令护侮。
build: .指定Docker基于當前目錄下Dockrfile中定義的指令去構建一個新的鏡像敌完,該鏡像會被用于啟動該服務的容器。
command: python app.py指定Docker在容器中執(zhí)行名為app.py的python腳本作為主程序羊初。因此鏡像中必須包含app.py文件以及python滨溉,這一點在Dockerfile中可以得到滿足。
ports:指定Docker將容器內(-target)的5000端口映射到主機(published)的5000端口。這意味著發(fā)送到Docker主機5000端口的流量會被轉發(fā)到容器的5000端口业踏。
networks:使得Docker可以將服務連接到指定的網絡上禽炬。這個網絡就是我們下面定義的涧卵。
volumes:指定Docker將counter-vol卷掛載到容器內的 /code.這個卷也是我們下面定義的勤家。
綜上,Docker Compose會調用Docker來為web-fe服務部署一個獨立的容器柳恐。該容器基于于Compose文件同一目錄的Docker構建的鏡像伐脖。基于該鏡像啟動的容器會運行app.py作為其主程序乐设,將5000端口暴露給宿主機讼庇,連接到counter-net網絡上,并且掛載一個卷到 /code近尚。
事實上我們在Docker Compose中不用定義 command命令了蠕啄,因為鏡像的Dockerfile已經定義了。
redis服務的定義相對來說就比較簡單了戈锻。
image:redis:alpine使得Docker可以基于redis:alpine鏡像啟動一個獨立的名為redis的容器歼跟,這個容器會從Docker Hub上拉取下來。
networks:配置redis容器連接到counter-net網絡格遭。
由于兩個服務都連接到counter-net網絡哈街,因此他們可以通過名稱解析到對方的地址。了解這一點很重要拒迅,本例中上層應用被配置為通過名稱與Redis服務通信骚秦。
9.2.4 使用Dockers Compose部署應用
上面我們已經把源碼從github上面下載下來了,進入目錄我們大概看下里面的那幾個文件:
- app.py 是應用程序代碼
- docker-compose.yml 是Compose文件璧微,其中定義了Docker如何部署應用
- Dockerfile 定義了如何構建web-fe服務所使用的鏡像作箍。
- requirements.txt 列出了應用所依賴的python包
下面我們使用docker-compose來把應用給部署然后啟動起來。
cd counter-app
docker-compose up &
常用的啟動一個Compose應用的方式就是docker-compose up 命令前硫。它會構建所需的鏡像胞得,創(chuàng)建網絡和卷,并啟動容器开瞭。默認情況下懒震,docker-compose up 會查找名為docker-compose.yml或者docker-compose.yaml的Compose文件。如果使用其他的文件名嗤详,請使用 -f 參數去指定个扰。要后臺啟動更加合理的方式是使用 -d 參數,使用 & 的話不大正規(guī)葱色。
最后递宅,這個命令會創(chuàng)建3個鏡像(有個python基礎鏡像是Dockerfile拉取的),并且啟動其中的兩個(web-fe和redis).
[pangcm@docker01 ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f43b3727185 redis:alpine "docker-entrypoint.s…" 22 seconds ago Up 17 seconds 6379/tcp counter-app_redis_1
3e9d124ae4a5 counter-app_web-fe "python app.py" 22 seconds ago Up 17 seconds 0.0.0.0:5000->5000/tcp counter-app_web-fe_1
到這里,多容器的應用已經借助Docker Compose成功部署了办龄。你可以是用瀏覽器打開Docker主機的5000端口查看成果烘绽。
9.2.5 使用Docker Compose 管理應用
本節(jié)會介紹如何使用Docker Compose 啟動、停止和刪除應用俐填,以及獲取應用狀態(tài)安接。還會演示如何使用掛載的卷來實現對Web前端的更新。
前面我們啟動了應用英融,接下來我們使用 docker-compose down 來關閉應用盏檐。
[pangcm@docker01 counter-app]$ docker-compose down
Stopping counter-app_redis_1 ... done
Stopping counter-app_web-fe_1 ... done
Removing counter-app_redis_1 ... done
Removing counter-app_web-fe_1 ... done
Removing network counter-app_counter-net
這里可以看到關閉的過程,停止并刪除容器驶悟,然后刪除網絡胡野。可以看到我們的卷并沒有被刪除掉痕鳍,因為卷是用來做持久化存儲的硫豆。如果你使用的是 docker-compose up & 來啟動過的話,還可以看到更多的過程笼呆。
然后我們再次來啟動熊响,使用docker-compose ps 觀察應用的狀態(tài)。
[pangcm@docker01 counter-app]$ docker-compose up -d
Creating network "counter-app_counter-net" with the default driver
Creating counter-app_web-fe_1 ... done
Creating counter-app_redis_1 ... done
[pangcm@docker01 counter-app]$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------
counter-app_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
counter-app_web-fe_1 python app.py Up 0.0.0.0:5000->5000/tcp
輸出的內容會顯示容器的名稱抄邀,其中運行的Command耘眨、當前狀態(tài)以及其偵聽的網絡端口。
使用docker-compose top 命令可以列出各個服務內運行的進程境肾。
[pangcm@docker01 counter-app]$ docker-compose top
counter-app_redis_1
UID PID PPID C STIME TTY TIME CMD
-------------------------------------------------------------------
polkitd 10501 10468 0 18:01 ? 00:00:00 redis-server
counter-app_web-fe_1
UID PID PPID C STIME TTY TIME CMD
--------------------------------------------------------------------------------------
root 10514 10492 0 18:01 ? 00:00:00 python app.py
root 10632 10514 0 18:01 ? 00:00:00 /usr/local/bin/python /code/app.py
這里需要注意的是PID編號是在Docker主機上的進程ID剔难,而不是容器里面的。
使用docker-compose stop 可以停止應用奥喻,但是不會刪除資源偶宫。
[pangcm@docker01 counter-app]$ docker-compose stop
Stopping counter-app_redis_1 ... done
Stopping counter-app_web-fe_1 ... done
[pangcm@docker01 counter-app]$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------
counter-app_redis_1 docker-entrypoint.sh redis ... Exit 0
counter-app_web-fe_1 python app.py Exit 0
已經停止的應用可以使用 docker-compose rm命令去刪除資源,這里也一樣不會刪除卷和鏡像的环鲤。使用docker-compose restart 可以重啟應用纯趋。
docker-compose restart
上面多處提到卷不會被刪除,那么我們來看下卷的情況冷离。查看卷可以使用 docker volome ls命令查看吵冒。
[pangcm@docker01 counter-app]$ docker volume ls
DRIVER VOLUME NAME
local counter-app_counter-vol
這個卷我們把它掛載到容器的 /code 目錄下,/code 目錄是應用的工作目錄西剥,我們的項目文件就是存放在這個目錄下痹栖,從Dockerfile文件可以得到確定。
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
這就是說我們的項目文件實際上持久化在對應的卷上的了瞭空,如果我們在Docker主機對卷中的文件做修改揪阿,會不會馬上反應到應用中呢疗我?下面驗證下。
首先我們要找到我們這個卷所在的位置南捂,使用 inspect 可以查看到吴裤。
[pangcm@docker01 counter-app]$ docker volume inspect counter-app_counter-vol |grep Mountpoint
"Mountpoint": "/var/lib/docker/volumes/counter-app_counter-vol/_data",
可以看到這個卷實際上在Docker主機的 /var/lib/docker/volumes/目錄下,我們進入到該目錄溺健,然后修改里面的app.py文件麦牺,最后在頁面上驗證下結果即可。
##修改這行的內容即可
return "What's up PCM1 Docker Deep Divers! You've visited me {} times.\n".format(count)
在生產環(huán)境中我們不會這么做矿瘦,但是在開發(fā)環(huán)境下能節(jié)省很多時間枕面。這里可以看到,Docker Compose可以用來部署和管理復雜得多的應用缚去。
9.3 使用Docker Compose 部署應用——命令
- docker-compose up 命令用于部署一個Compose應用。
- docker-compose stop 命令會停止Compose應用相關的所有容器琼开,但不會刪除他們易结。
- docker-compose rm 命令用于刪除停止的Compose應用。
- docker-compose restart 命令會重啟已停止的Compose應用柜候。
- docker-compose ps 命令用于列出Compose應用中的各個容器搞动。輸出內容包括當前狀態(tài)、容器運行的命令以及網絡端口渣刷。
- docker-compose down 會停止并刪除運行中的Compose應用鹦肿。它會刪除容器和網絡,但是不會刪除卷和鏡像辅柴。
9.4 本章小結
本章介紹了如何使用Docker Compose 部署和管理一個多容器的應用箩溃。Docker Compose是一個基于Docker Engine進行安裝的Python工具。該工具使得用戶可以在一個聲明式的配置文件中定義一個多容器的應用碌嘀,并通過一個簡單的命令完成部署涣旨。
Compose文件可以是YAML或者JSON格式,其中定義了所有的容器股冗、網絡霹陡、卷以及應用所需的密碼。docker-compose命令行工具會解析該文件止状,并調用Docker來執(zhí)行部署烹棉。
一旦應用完成部署,用戶就可以使用不同的docker-compose子命令來管理應用的整個生命周期怯疤。
本章還介紹了如何使用掛載卷來修改容器內的文件浆洗。Docker Compose 在開發(fā)者中得到廣泛使用,而且對應用來說旅薄,Compose文件也是一種非常不錯的文檔——其中定義了組成應用的所有服務辅髓,他們使用的鏡像泣崩、網絡和卷,暴露的端口洛口,以及更多信息矫付。基于此第焰,我們可以彌合開發(fā)與運維之間的隔閡买优。Compose文件應該被當作代碼,因此應該將其保存在源控制庫中挺举。