docker:編排與部署小神器Compose

1.docker-compose是什麼

Compose是定義和運行多容器Docker應用程序的工具。 使用Compose,您可使用YAML文件來配置應用程序的服務。 而後,使用單個命令,您能夠建立並啓動配置中的全部服務。php

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

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

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

尚未徹底理解的朋友,用通俗的語言來講:nginx

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

docker:編排與部署小神器Compose
從上圖能夠看到,這位compose哥們很是開心的把N多個容器抓在一塊兒,根據本身的心情來編排部署。github

2.談談容器編排與部署

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

 Dockerfile做爲整個機制的核心。這是一個很是了不得的創新,由於在Dockerfile中,不但可以定義使用者在容器中須要進行的操做,並且可以定義容器中運行軟件須要的配置,因而軟件開發和運維終於可以在一個配置文件上達成統一。運維人員使用同一個Dockerfile能在不一樣的場合下「重現」與開發者環境中如出一轍的運行單元(Docker容器)出來。docker

2.1爲何要使用Compose

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

一、docker search 鏡像,是否是先查找一個鏡像;
二、docker run -itd 鏡像名稱 ,而後在運行這個鏡像;
三、而後若是你要在運行第二個鏡像、第三個鏡像.....等等鏡像,你是否是又要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;

三、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)。後期筆者會更新出這些內容和你們一塊兒來討論。

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

相關文章
相關標籤/搜索