docker:編排與部署小神器Compose

1.docker-compose是什麼

Compose是定義和運行多容器Docker應用程序的工具。 使用Compose,您可以使用YAML文件來配置應用程序的服務。 然後,使用單個命令,您可以創建並啓動配置中的所有服務。

Compose適用於所有環境:生產,開發,測試以及CI工作流程。使用Compose基本上是一個三步過程:

  1. 使用Dockerfile定義應用程序的環境,以便在任何地方進行復制。
  2. 在docker-compose.yml中定義組成應用程序的服務,以便它們可以在隔離的環境中一起運行。
  3. 運行docker-compose並撰寫開始並運行你的整個應用程序。

可以參考docker-compose官方說明詳細瞭解:https://docs.docker.com/compose/overview/

還沒有完全理解的朋友,用通俗的語言來說:

docker-compose 是用來做docker 的多容器控制,docker-compose 是一個用來把 docker 自動化的東西,有了 docker-compose 你可以把所有繁複的 docker 操作全都一條命令,自動化的完成。來看看下面這張圖你也許又能更好的理解了:

docker:編排與部署小神器Compose
從上圖可以看到,這位compose哥們非常開心的把N多個容器抓在一起,根據自己的心情來編排部署。

2.談談容器編排與部署

 Docker有很多優勢,但對於運維或開發者來說,Docker最大的有點在於它提供了一種全新的發佈機制。這種發佈機制,指的是我們使用Docker鏡像作爲統一的軟件製品載體,使用Docker容器提供獨立的軟件運行上下文環境,使用Docker Hub提供鏡像統一協作,最重要的是該機制使用Dockerfile定義容器內部行爲和容器關鍵屬性來支撐軟件運行。

 Dockerfile作爲整個機制的核心。這是一個非常了不起的創新,因爲在Dockerfile中,不但能夠定義使用者在容器中需要進行的操作,而且能夠定義容器中運行軟件需要的配置,於是軟件開發和運維終於能夠在一個配置文件上達成統一。運維人員使用同一個Dockerfile能在不同的場合下“重現”與開發者環境中一模一樣的運行單元(Docker容器)出來。

2.1爲什麼要使用Compose

docker:編排與部署小神器Compose
 先來想一下我們平時是怎麼樣使用docker的?把它進行拆分一下:

1、docker search 鏡像,是不是先查找一個鏡像;
2、docker run -itd 鏡像名稱 ,然後在運行這個鏡像;
3、然後如果你要在運行第二個鏡像、第三個鏡像.....等等鏡像,你是不是又要docker search、docker run運行。

 上面“ docker run it 鏡像名稱 ”這只是最小的動作, 如果你要映射硬盤,設置nat網絡或者映射端品,等等…你就要做更多的 docker 操作, 這顯然是非常沒有效率的,況且如果你要大規模部署,是不是覺得就很麻煩了。

 但是我們寫在 docker-compose.file 裏面就很好了。你只需要寫好後只運行一句:
docker-compose up -d

 一切都是那麼的簡單!!!

2.2瞭解下編排和部署

編排,即orchestration,它根據被部署的對象之間的耦合關係,以及被部署對象環境的依賴,制定部署流程中各個動作的執行順序,部署過程所需要的依賴文件的存儲位置和獲取方式,以及如何驗證部署成功。這些信息都會在編排工具中以指定的格式(比如配置文件或者特定的代碼)來要求運維人員定義並保存起來,從而保證這個流程能夠隨時在全新的環境中可靠有序地重現出來。

部署,即deployment,它是指按照編排所指定的內容和流程 ,在目標機器上執行編排指定環境初始化,存放指定的依賴和文件,運行指定的部署動作,最終按照編排中的規則來確認聯署成功。

這麼來解釋吧,編排是一個指揮家,他的大腦裏存儲了整個樂曲的演奏流程,對於每一個小節每一段音樂的演奏方式、開始、結束他都瞭然於胸;部署就是整個樂隊,他們嚴格按照指揮家的意圖用樂器來完成樂譜的執行,在需要時開始演奏,又在適當的時機停止演奏。最終,兩者通過協作就能把每一位演奏者獨立的演奏通過組合、重疊、銜接來形成高品位的交響樂。
docker:編排與部署小神器Compose

而在Compose的世界裏,編排和部署的組合結果,就是一朵“容器雲”。

3.一探究竟~~ Compose原理

docker-compose的調用過程扁平的像一張紙,僅用一張簡單的模塊圖就足夠解釋明白,如下圖所示:
docker:編排與部署小神器Compose
首先,用戶執行的docker-compose up指令調用了命令行中的啓動方法。功能很簡單明瞭,一個docker-compose.yml定義了一個docker-compose的project,docker-compose操作提供的命令行參數則作爲這個project的啓動參數交由project模塊去處理。

其次,如果當前宿主機已經存在與該應用對應的容器,docker-compose將進行行爲邏輯判斷。如果用戶指定可以重新啓動已有服務,docker-compose就會執行service模塊的容器重啓方法,否則就將直接啓動已有容器。這兩種操作的區別在於前者會停止舊的容器,創建啓動新的容器,並把舊容器移除掉。在這個過程中創建容器的各項定義參數都是從docker-compose up 指令和docker-compose.yml中傳入的。

接下來,啓動容器的方法也很簡潔,這個方法中完成了一個Docker容器啓動所需的主要參數的封裝,並在container模塊執行啓動。該方法所支持的參數我想大多數朋友過是有所瞭解的。

最後,container模塊會調用docker-py客戶端執行向Docker daemon發起創建容器的POST請求,再往後就是Docker處理的範疇了,相信看過我這篇文章 Docker:架構拆解請 的朋友就明白了。

爲了能夠說明compose如何實現上述編排與部署的原理,下面和大家分享一個通過compose來編排部署LNMP服務來更好的理解它。

4.compose編排LNMP服務

4.1 yaml

YAML是一種標記語言,可讀性很強。類似於XML數據描述語言,語法比XML簡單的多。YAML數據結構通過縮進來表示,連續的項目通過減號來表示,鍵值對用冒號分融,數組用括號括起來,hash用花括號括起來。詳細瞭解的朋友可以參考 YAML百度百科 https://baike.baidu.com/item/YAML/1067697?fr=aladdin

YAML文件格式注意事項:

  1. 在縮排中空白字符的數目並不是非常重要,只要相同階層的元素左側對齊就可以了(不過不能使用TAB字符);
  2. 通常開頭縮進2個空格;
  3. 字符的後面縮進1個空格,比如冒號、逗號、橫杆;
  4. 支持#註釋;
  5. 允許在文件中加入選擇性的空行,以增加可讀性;

docker-compose中YAML常用的字段:

docker:編排與部署小神器Compose

4.2 目錄結構

我們先來看下所需要的文件、目錄結構是怎樣的:

[root@ganbing /]# tree  compose_lnmp/
compose_lnmp/
├── docker-compose.yml
├── mysql
│   ├── conf
│   │   └── my.cnf
│   └── data
├── nginx
│   ├── Dockerfile
│   ├── nginx-1.12.1.tar.gz
│   └── nginx.conf
├── php
│   ├── Dockerfile
│   ├── php-5.6.31.tar.gz
│   └── php.ini
└── wwwroot
    ├── index.html
    └── index.php

其實看過筆者 docker:Dockerfile構建LNMP平臺 這篇文章的朋友,應該對這個目錄結構很熟悉,是不是發現nginx、php這兩個目錄和我之前寫的《docker:Dockerfile構建LNMP平臺》中的目錄結構是一樣的,無非這裏多了兩個目錄:
mysql目錄>>conf目錄>>my.cnf(mysql默認配置)
mysql目錄>>data目錄(用於後期掛載到mysql容器)

wwwroot目錄>>index.html和index.php這兩個首頁,用於部署成功後進行訪問測試

4.3 安裝docker-compose

下載最新版本安裝,下載時間可能比較長

[root@ganbing ~]# curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

[root@ganbing ~]# chmod  +x /usr/local/bin/docker-compose

或者用pip安裝:pip install docker-compose

docker-compose用法

Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]

docker-compose常用命令:
build  構建或重建服務
kill   殺掉容器
logs  顯示容器的輸出內容
port  打印綁定的開放端口
ps   顯示容器
pull  拉取服務鏡像
restart 重啓服務
rm  刪除停止的容器
run  運行一個一次性命令
scale 設置服務的容器數目
exec 在容器裏搪行命令
start 開啓服務
stop 停止服務
up  創建並啓動容器

其實這些常用命令用docker的命令功能是一樣的。

4.4 一鍵部署lnmp平臺

我們先來看下/compose_lnmp目錄下的docker-compose.yml文件:

[root@ganbing compose_lnmp]# ls
docker-compose.yml  mysql  nginx  php  wwwroot

[root@ganbing compose_lnmp]# cat docker-compose.yml
version: '3'
services:
  nginx:
    hostname: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    networks:
      - lnmp
    volumes:
      - ./wwwroot:/usr/local/nginx/html

  php:
    hostname: php
    build:
      context: ./php
      dockerfile: Dockerfile
    networks:
      - lnmp
    volumes:
      - ./wwwroot:/usr/local/nginx/html

  mysql:
    hostname: mysql
    image: mysql:5.6
    ports:
      - 3306:3306
    networks:
      - lnmp
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/data:/var/lib/mysql
    command: --character-set-server=utf8
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
      MYSQL_USER: ganbing
      MYSQL_PASSWORD: ganbing123

networks:
  lnmp:

可以看到一份標準配置文件應該包含 version、services、networks 三大部分,共有三級標籤,每一級都是縮進兩個空格。下面來詳細說明一下里面的內容:

  1. version: '3'
    這是定義compose的版本號爲version 3,可以參考官方文檔詳細瞭解具體有哪些版本 https://docs.docker.com/compose/compose-file/

  2. services:
    nginx:這是services下面的二級標籤,名字用戶自己定義,它將是服務運行後的名稱;
    hostname: nginx 這是定義容器的主機名,將寫入到/etc/hostname中;
    build:
     context: ./nginx 指定nginx服務的上下文路徑;
     dockerfile:Dockerfile 指定通過上面指定路徑中的Dockerilfe來構建;
    ports:
     - 80:80 端口映射沒什麼好說的;
    networks:
     -lnmp 指定的網絡環境
    volumes:把宿主機的/wwwroot目錄綁定到容器中的/usr/local/nginx/html目錄;

php:這個二級標籤服務和下面的內容跟nginx差不多;

mysql:這個二級標籤服務也和nginx、php差不多,唯一不同的是多了個images標籤、還有定義了些環境變量。
image: mysql:5.6 它是通過mysql:5.6鏡像來構建mysql服務器,前面nginx、php都指定了上下文通過Dockerfile來構建的。
environment:
 MYSQL_ROOT_PASSWORD:定義root用戶密碼變量爲123456;
 MYSQL_DATABASE:定義了數據變量爲wordpress;
 MYSQL_USER:定義了普通用戶變量爲ganbing;
 MYSQL_PASSWORD:定義了普通用戶密碼變量爲ganbing123;

3、networks:
   lnmp: 相當於執行docker network create lnmp命令了;

最後來運行docker-compose命令來啓動:

[root@ganbing /]# cd compose_lnmp/

[root@ganbing compose_lnmp]# docker-compose  -f docker-compose.yml  up -d

來查看一下是否啓動完成:

[root@ganbing compose_lnmp]# docker-compose ps
       Name                      Command               State           Ports          
-------------------------------------------------------------------------------------
composelnmp_mysql_1   docker-entrypoint.sh --cha ...   Up      0.0.0.0:3306->3306/tcp 
composelnmp_nginx_1   ./sbin/nginx -g daemon off;      Up      0.0.0.0:80->80/tcp     
composelnmp_php_1     ./sbin/php-fpm -c /usr/loc ...   Up      9000/tcp    

從上面可以看出這3個服務都是UP狀態,運行 docker-compose ps必須要在有docker-compose.yml文件目錄下執行纔可以。

同樣,還可以用docker ps來查看:
docker:編排與部署小神器Compose

在來訪問一下nginx服務index.html靜態頁面,通過暴露的nginx 80端口來訪問:
docker:編排與部署小神器Compose

在前面我們在docker-compse.yml中的nginx服務把宿主機/wwwroot綁定到了容器/usr/local/nginx/html目錄中,所以我們可以修改下宿主機中/wwwroot/index.html的內容來驗證一下:

[root@ganbing /]#echo "add test" >> /compose_lnmp/wwwroot/index.html

修改然後測試可以看到index.html修改了:
docker:編排與部署小神器Compose

接下來訪問下index.php頁面是否正常,從下面可以看到也是沒問題的:
docker:編排與部署小神器Compose

既然用docker-compose編排部署LNMP平臺搞定了,只要你弄懂了原理和方法,用docker-compose編排部署其它服務也是一樣的,只不過是思路的問題。

5.總結思考

  大家想想,僅僅使用Compose,就可以構建自己的容器雲嗎?答案顯然是否定的。docker-compose解決的問題侷限在“編排”二字,甚至連“部署”範疇都涉足甚少,而在一個能夠服務於大衆的雲平臺中,編排與部署也僅僅是其中的一個組成部分而已。來一起分析一下它的侷限制會有哪些:

  1. docker-compse是面向單宿主機部署的,這是一種部署能力的欠缺。在更多的場合下,管理員需要面對大量物理服務器(或者虛擬機),這時如果要實現基於docker-compose的容器自動化編排與部署,管理員就得藉助成熟的自動化運維工具(ansible、puppet、chef、saltstack)來負責管理多個目標主機,將docker-compose所需的所有資源(配置文件、用戶代碼)交給目標主機,然後在目標主機上執行docker-compose指令。
  2. 同樣網絡和存儲也比較棘手,Docker不能提供跨宿主機的網絡,完全面向Docker daemon的docker-compose當然也不支持。這意味着管理員必須部署一套類似於Open vSwich的獨立網絡工具,而且管理員還需要完成集成工作。當好不容易把容器編排都安排妥當之後,又會發現容器還處在內網環境中,於是負載均衡、服務發現等一堆問題就面臨而來了,這些問題很快能消耗掉工程師所有的耐心。

那麼,是否有一種能夠提供完善的面向服務器集羣的Docker編排和部署方案呢?Docker官方給出的答案是Compose同Machine和Swarm聯動,其實還有大家近期經常聽到了kubernetes(k8s)。後期筆者會更新出這些內容和大家一起來討論。

喜歡我的文章,請點擊最上方右角處的《關注》支持一下!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章