1.編排與部署
-
如何批量創建、段哦都和管理容器成了制約Docker技術在任何組織內大規模應用的主要障礙,蔻帶解決的正式容器的編排與部署問題
-
Docker優點:提供了一種全新的軟件發佈機制。
開發者使用Docker鏡像作爲統一的軟件製品載體;
使用Docker容器提供獨立的軟件運行上下文環境;
使用Docker Hub提供鏡像統一操作;
使用Dockerfile定義定義使用者在容器中需要進行的操作,還能定義容器中運行軟件需要的配置,即:軟件開發和運維能夠在一個配置文件上達成統一; -
Dockerfile重現一個容器,Compose重現容器的配置和集羣
-
編排:將部署對象,部署流程,以及部署所需的依賴文件,存儲位置都在編排工具中以指定的格式(eg:配置文件或者特定的代碼)保存起來,能夠在全新的環境中可靠有序地重現出來。
-
部署:指的是按照編排所指定的內容和流程,在目標機器上執行編排指定的環境初始化,存訪指定的依賴和文件,運行指定的部署動作,最終按照編排中的規則來確認部署是否成功。
-
Fig/Compose的eg
(1)Fig是面向Docker容器集羣做的編排部署的唯一工具
(2)Fig被Docker官方改名爲Compose
(3)使用Fig/Compose實現上述編排與部署的eg
(1)Compose的安裝
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-``uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
(2)在Docker宿主機上,創建工作目錄和應用
mkdir composetest & composetest
在該目錄下,創建一個app.py,基於Flask的Web輕應用
from flask import Flask
from flask import Redis
import os
app=Flask(__name__)
redis=Redis(host='redis',port=6379)
@app.route('/') ##訪問跟目錄
def hello():
redis.incr('hits')##返回一個從Redis裏讀取的值,該值通過自加來統計訪問次數
return 'Hello World! I have been seen %s times.' %redis.get('hits')
if __name__="__main__"
app.run(host="0.0.0.0",debug=True)##Web容器在0.0.0.0上監聽默認端口500並啓動
(3)在requirements.txt中指定Python依賴包:flask和redis
(4)定義運行這個應用的Docker容器,Dockerfile如下:
FROM python:2.7 ##安裝依賴
ADD . /code ## 添加工作目錄
WORKDIR /code
RUN pip install -r requirements.txt
(5)一個docker-conmpose.yml來定義這個工作集羣,編排部署的核心:
web:
build: .
command: python app.py
ports:
-"5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image:redis
在該YAML文件裏,可以看到兩個key:web和redis,意味着用Compose定義了由兩個“服務”組成的Docker集羣
(6)執行:docker-compose up,在容器的Python Web服務中可以看到統計的訪問次數
說明:
(1)第一個服務叫web,他從當前目錄的Dockerfile build得到;
在容器中運行python app.py;
把容器內的5000端口映射到主機的5000端口;
掛載執行這些操作所在的目錄到/code目錄下;
代碼的修改會直接在容器中體現
(2)redis直接使用已有的redis鏡像,Dockerfile不必另外寫。
2.Compose原理:僅用一張圖就可以解釋
- 如下圖6-1,以docker-compose up爲例
(1)docker-compose像是docker client增加,它爲docker client引入了組的概念
(2)圖中右上角的docker-compose定義了一組服務來組成一個docker-compose的project
調用過程如下:
(1)首先,用戶執行dcker-compose up指令調用了命令行中的啓動方法。
即:一個docker-compose.yml定義了一個docker-compose 的project,該指令提供的命令行參數則作爲project的啓動參數,交給
peoject去處理
(2)若當前宿主機已經存在與該應用對應的容器,docker-compose將進行行爲邏輯的判斷
(3)啓動容器,完成一個Docker容器啓動所需的主要參數的封裝,並在container模塊執行啓動
(4)container模塊會調用docker-py客戶端來執行,向Docker daemon發起創建容器的POST請求
- 當使用Docker構建服務棧時,容器間的關係,尤其是link和volumes-from這兩個參數是最爲常用的。
(1)一旦需要更新或重啓容器,就必須在容器啓動參數裏添加這2個參數,並且以正確的順序來執行docker run,才能保證新的集羣可以正常工作。
(2)在Compose中,link和volumes-from是在docker-compose.yml中是配置的,一旦在docker-compose up中發現了需要重新創建容器的情況,Compose就會依據容器之間的關係來進行更新操作,保證更新後的容器依然是正常連接的
(3)刪除並創建一個同名的容器是否能更新原先的link信息?
link原理:若存在web->redis這樣的link關係,web容器裏的hosts文件只有在redis容器重啓的情況下才會被更新,而更新並重新創建一個同名redis容器,原web容器黎的hosts文件記錄的還是一箇舊的IP地址。
Compose解決辦法:在Compose的數據結構中,對於重新創建的容器,都會按照project裏所有容器的link關係的排序依次進行。即:更新(重啓)redis容器會連帶更新link它的web容器。
(4)對於volume以及volume-from參數的問題:容器重建操作事實上,就是創建並重新創建一個同名容器,但是如果該容器包含volume,甚至該volume還被其它容器通過volume-from所引用,此時刪除新建的同名容器肯恩可能不具有舊容器的volume內容,還會間接導致引用它的其它容器volume內容丟失(docker-compose會按照拓撲關係重新引用新容器的volume)
Compose解決辦法:docker-compose中使用了中間容器intermediate container來暫時記錄舊的容器,如圖6-2所示
圖6-2的解釋:
(1)中間容器先引用舊容器的volume,然後才刪除舊容器
即:docker rm只刪除容器,舊容器volume裏的內容是保留的。
(2)當重新創建新容器之後,新建容器就可以通過引用中間容器獲得舊容器volume的內容
- 編排工具Compose直接在docker-compose代碼基礎上進行重構和再開發,使用Docker標準API,缺點:
(1)僅在編排,沒有部署
(2)面向單機部署
(3)Docker不能提供跨主機的網絡