1九、Docker Compose

  編排(Orchestration)功能是複雜系統實現靈活可操做性的關鍵。特別是docker應用場景中,編排意味着用戶能夠靈活地對各類容器資源實現定義和管理。python

  在咱們部署多容器的應用時:mysql

  • 要從Dockerfile build image或者從dockerhub拉取image
  • 要建立多個container
  • 要管理這些container(啓動、中止、刪除)

  爲了方便咱們部署和管理多容器的應用,docker compose就出現了。git

docker-compose

19.1 什麼是docker compose

  docker compose項目是docker官方的開源項目,負責實現對docker容器集羣的快速編排。其代碼在GitHub上開源https://github.com/docker/composegithub

  • Docker Compose是一個工具
  • 這個工具能夠經過一個yml文件定義多容器的docker應用
  • 經過一條命令就能夠根據yml文件的定義去建立或者管理這多個容器

  Compose定位是「定義和運行多個docker容器的應用」。它容許用戶經過一個單獨的docker-compose.yml模板文件(YAML格式)來定義一組相關聯的應用容器爲一個項目(project)。web

Compose中有三個重要的概念:

  • 服務(services)

  一個service表明一個container,這個container能夠從dockerhub的image建立,或者從本地的Dockerfile build出來的image來建立。redis

  service的啓動相似docker run,咱們能夠給其指定network和volume,因此能夠給service指定network和volume的引用。sql

  • 網絡(networks)
  • 數據卷(volumes)

舉例

  • service舉例
services: 
  db:
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
    network:
      - back-tier

  這個例子相似於運行了下面這條命令:docker

docker run -d --network back-tier -v db-data:/var/lib/postgresql/data postgres:9.4
services:
  worker:
    build: ./worker    # 指定了Dockerfile的路徑
    links:
      - db
      - redis

    networks:
      - back-tier

  安裝WordPress的一個docker compose文件:shell

version: '3'  # 指定docker compose的版本

services:

  wordpress:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD: root
    networks:
      - my-bridge

  mysql:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - my-bridge

volumes:
  mysql-data:

networks:
  my-bridge:
    driver: bridge

19.2 docker-compose安裝

  docker compose 官方安裝文檔flask

curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

19.3 docker-compose命令說明

1. -f, --file           指定使用的Compose模板文件,默認爲當前目錄下的docker-compose.yml文件。
2. -p, --project-name   指定項目名稱,默認將使用當前所在目錄名稱做爲項目名。
3. --verbose            打印更多的日誌輸出
4. --log-level          設置日誌級別,(DEBUG, INFO, WARNING, ERROR, CRITICAL)
5. -v, --version        打印版本並退出
6. -H, --host           指定鏈接到的守護進程
7. build                構建(從新構建)項目中的服務容器
8. logs                 查看服務容器的輸出
9. kill                 強制中止服務容器
10. pause               暫停一個服務容器
11. port                打印某個容器端口所映射的公共端口
12. ps                  列出項目中目前的全部容器
13. pull                拉取服務依賴的鏡像
14. restart             重啓項目中的服務
15. rm                  刪除全部(中止狀態的)服務容器
16. run                 在指定服務上執行一個命令
17. exec                在指定服務上執行一個命令
17. scale               設置指定服務運行的容器個數
18. start               啓動已經存在的服務容器
19. stop                中止已經處於運行狀態的容器,可是不能刪除
20. unpause             恢復處於暫停狀態的服務
21. up                  自動完成包括構建鏡像、建立服務、建立指定網絡、啓動服務並關聯服務相關容器的一系列操做
22. migrate-to-labels   建立容器,並添加lable
23. version             打印版本信息
24. down                中止正在運行的容器並刪除容器和網絡

19.4 經過docker-compose scale實現負載均衡

  經過haproxy實現flask調用redis的負載均衡

  docker-compose.yml:

version: "3"

services:
  redis:
    image: redis
  web:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      REDIS_HOST: redis
  lb:
    image: dockercloud/haproxy
    links:
      - web
    ports:
      - 8080:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  Dockerfile:

FROM python:2.7
LABEL maintaner="Peng Xiao xiaoquwl@gmail.com"
COPY . /app
WORKDIR /app
RUN pip install flask redis
EXPOSE 80
CMD [ "python", "app.py" ][

  app.py:

from flask import Flask
from redis import Redis
import os
import socket

app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)


@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=80, debug=True)

  首先經過docker-compose up -d啓動:

[root@docker lb-scale]# docker-compose up -d
Creating network "lb-scale_default" with the default driver
Creating lb-scale_redis_1 ... done
Creating lb-scale_web_1   ... done
Creating lb-scale_lb_1    ... done
[root@docker lb-scale]#

  經過docker-compose ps查看:

[root@docker lb-scale]# docker-compose ps
      Name                    Command               State                    Ports
---------------------------------------------------------------------------------------------------
lb-scale_lb_1      /sbin/tini -- dockercloud- ...   Up      1936/tcp, 443/tcp, 0.0.0.0:8080->80/tcp
lb-scale_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp
lb-scale_web_1     python app.py                    Up      80/tcp
[root@docker lb-scale]# \

  經過 curl 127.0.0.1:8080

[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 1 times and my hostname is 857fdbc456fb.
[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 2 times and my hostname is 857fdbc456fb.
[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 3 times and my hostname is 857fdbc456fb.
[root@docker lb-scale]#

  經過scale建立多個web服務的容器數,而且經過haproxy是愛你負載均衡:

[root@docker lb-scale]# docker-compose up --scale web=3 -d
lb-scale_redis_1 is up-to-date
Starting lb-scale_web_1 ... done
Creating lb-scale_web_2 ... done
Creating lb-scale_web_3 ... done
lb-scale_lb_1 is up-to-date
[root@docker lb-scale]#

  再次經過 curl 127.0.0.1:8080

[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 4 times and my hostname is 857fdbc456fb.
[root@docker lb-scale]#curl 127.0.0.1:8080
Hello Container World! I have been seen 5 times and my hostname is 43f2925c52d1.
[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 6 times and my hostname is 354a407ee7b1.
[root@docker lb-scale]# curl 127.0.0.1:8080
Hello Container World! I have been seen 7 times and my hostname is 857fdbc456fb.
[root@docker lb-scale]#curl 127.0.0.1:8080
Hello Container World! I have been seen 8 times and my hostname is 43f2925c52d1.
[root@docker lb-scale]#curl 127.0.0.1:8080
Hello Container World! I have been seen 9 times and my hostname is 354a407ee7b1.
[root@docker lb-scale]#

  繼續增長WEB容器的數量,並訪問:

[root@docker lb-scale]# docker-compose up --scale web=10 -d
lb-scale_redis_1 is up-to-date
Starting lb-scale_web_1 ... done
Starting lb-scale_web_2 ... done
Starting lb-scale_web_3 ... done
Creating lb-scale_web_4  ... done
Creating lb-scale_web_5  ... done
Creating lb-scale_web_6  ... done
Creating lb-scale_web_7  ... done
Creating lb-scale_web_8  ... done
Creating lb-scale_web_9  ... done
Creating lb-scale_web_10 ... done
lb-scale_lb_1 is up-to-date
[root@docker lb-scale]#for i in `seq 10`;do curl 127.0.0.1:8080;done
Hello Container World! I have been seen 10 times and my hostname is 857fdbc456fb.
Hello Container World! I have been seen 11 times and my hostname is a529d9001556.
Hello Container World! I have been seen 12 times and my hostname is 43f2925c52d1.
Hello Container World! I have been seen 13 times and my hostname is 354a407ee7b1.
Hello Container World! I have been seen 14 times and my hostname is 25698b41ea54.
Hello Container World! I have been seen 15 times and my hostname is 4114fe5258fa.
Hello Container World! I have been seen 16 times and my hostname is 749e6918a6c5.
Hello Container World! I have been seen 17 times and my hostname is 7792a42d1219.
Hello Container World! I have been seen 18 times and my hostname is c91ab986a554.
Hello Container World! I have been seen 19 times and my hostname is 01fc4550b204.
[root@docker lb-scale]#

  能夠看出,經過docker-compose的scale能夠快速的實現某個服務容器數量的增長,在訪問量突增的狀況下能夠輕鬆應對,減輕服務器壓力。

當訪問量恢復正常的時候也能夠5個docker-compose up --scale來減小容器的數量:

[root@docker lb-scale]# docker-compose up --scale web=5 -d
lb-scale_redis_1 is up-to-date
Stopping and removing lb-scale_web_6  ... done
Stopping and removing lb-scale_web_7  ... done
Stopping and removing lb-scale_web_8  ... done
Stopping and removing lb-scale_web_9  ... done
Stopping and removing lb-scale_web_10 ... done
Starting lb-scale_web_1               ... done
Starting lb-scale_web_2               ... done
Starting lb-scale_web_3               ... done
Starting lb-scale_web_4               ... done
Starting lb-scale_web_5               ... done
lb-scale_lb_1 is up-to-date
[root@docker lb-scale]# docker-compose ps
      Name                    Command               State                    Ports
---------------------------------------------------------------------------------------------------
lb-scale_lb_1      /sbin/tini -- dockercloud- ...   Up      1936/tcp, 443/tcp, 0.0.0.0:8080->80/tcp
lb-scale_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp
lb-scale_web_1     python app.py                    Up      80/tcp
lb-scale_web_2     python app.py                    Up      80/tcp
lb-scale_web_3     python app.py                    Up      80/tcp
lb-scale_web_4     python app.py                    Up      80/tcp
lb-scale_web_5     python app.py                    Up      80/tcp
[root@docker lb-scale]#

  上述只是實現了單機的容器編排,畢竟單臺服務器的資源是有限的,容器數量過多會致使單臺服務器資源使用率不夠用,可是,若是能夠在多機服務器上編排容器數量,那麼服務器的性能將會獲得更好的利用,可以承受的併發將會呈指數上升。

  在docker-compose 3.0以前,docker-compose只支持單機的容器編排,到3.0的時候,docker-compose已經能夠支持多機的容器編排了,也就是說利用3.0及以上的docker-compose能夠實現多服務器上的容器編排。

相關文章
相關標籤/搜索