第9章 使用Docker Compose 部署應用

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文件應該被當作代碼,因此應該將其保存在源控制庫中挺举。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末杀赢,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子湘纵,更是在濱河造成了極大的恐慌脂崔,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梧喷,死亡現場離奇詭異砌左,居然都是意外死亡,警方通過查閱死者的電腦和手機铺敌,發(fā)現死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門汇歹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偿凭,你說我怎么就攤上這事产弹。” “怎么了弯囊?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵痰哨,是天一觀的道長。 經常有香客問我常挚,道長作谭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任奄毡,我火速辦了婚禮折欠,結果婚禮上,老公的妹妹穿的比我還像新娘吼过。我一直安慰自己锐秦,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布盗忱。 她就那樣靜靜地躺著酱床,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趟佃。 梳的紋絲不亂的頭發(fā)上扇谣,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天昧捷,我揣著相機與錄音,去河邊找鬼罐寨。 笑死靡挥,一個胖子當著我的面吹牛,可吹牛的內容都是我干的鸯绿。 我是一名探鬼主播跋破,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瓶蝴!你這毒婦竟也來了毒返?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舷手,失蹤者是張志新(化名)和其女友劉穎拧簸,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體聚霜,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡狡恬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了蝎宇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡祷安,死狀恐怖姥芥,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情汇鞭,我是刑警寧澤凉唐,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站霍骄,受9級特大地震影響台囱,放射性物質發(fā)生泄漏。R本人自食惡果不足惜读整,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一簿训、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧米间,春花似錦强品、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逻锐,卻和暖如春夫晌,著一層夾襖步出監(jiān)牢的瞬間雕薪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工晓淀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留所袁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓要糊,卻偏偏與公主長得像纲熏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锄俄,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容