動手學Docker-第五彈-Docker多容器部署

完整項目請查看Github:連接python

或經過gitbook在線查看: 連接mysql


經過以前的案例咱們也實現了Docker的多容器部署,可是有沒有以爲仍然很麻煩,咱們開發程序更習慣講配置信息寫到配置文件裏再繼續操做,那麼Docker有沒有實現這樣的功能呢?答案是有的。git

Docker Compose

Docker Compose是一個工具,它支持經過yml文件來定義和配置多個容器,並且在定義好容器以後咱們能夠經過跟簡單的命令快速的搭建起一個基於Docker的多容器應用。 默認狀況下咱們是建立一個docker-compose.yml文件,在這個文件中咱們會定義三個比較重要的東西。github

  1. services:裏面對應的每一個service表明一個容器,容器對應的鏡像能夠經過DockerHub拉取,也能夠經過build命令構建。而且在建立時咱們還能夠指定對應的network和volume。
  2. volumes:對應以前Docker持久化存儲那裏的-v參數
  3. networks:對應以前Docker網絡那裏的-net參數

其實咱們在最開始的Docker初體驗裏就已經使用過這個Docker Compose了,不知道你們還記不記得,咱們這裏再回顧一下。 web

在這裏插入圖片描述

Docker Compose安裝

通常狀況下在mac和windows上安裝Docker時會自動安裝docker-compose,Linux上須要手動安裝。 首先經過命令redis

docker-compose --version
複製代碼

查看你的服務器是否已經安裝好了Docker Compose。若沒有安裝則繼續閱讀如下安裝步驟sql

在這裏插入圖片描述

Docker Compose基本使用

在建立好docker-compose.yml文件後,能夠經過這個命令將文件中定義的容器都啓動起來,在docker compose中咱們更習慣於將每個容器叫作service。docker

docker-compose up
複製代碼

命令後會自動接一個默認值-f docker-compose.yml,也就是默認是使用docker-compose.yml文件的。咱們也能夠給文件起名爲docke-test.yml,這樣在使用時指定文件名,可是爲了符合規範,仍是統一爲docker-compose.ymlflask

docker-compose up -f docer-test.yml
複製代碼

可是直接經過這種方式的話會直接將啓動時的輸出打印到終端,因此咱們常會加上-d參數。windows

docker-compose up -d
複製代碼

接下來能夠查看一下咱們建立的service狀態

docker-compose ps
複製代碼

如何中止已經運行的services呢,可使用如下兩個命令

docker-compose stop
docker-compose down
複製代碼

其中stop是直接中止services,而down則會中止並刪除建立的service,volume和network。

那麼如何進入容器呢

docker-compose exec mysql bash
複製代碼

exec後面接的就是咱們要進入具體的service的名字,名字後面就是咱們要執行的命令。

flask-redis Docker Compose實戰

咱們在以前是使用docker的命令將flask和redis進行鏈接,詳情見flask-redis實戰

接下來咱們使用docker-compose的方式實現一樣的功能。

編寫python文件

首先編輯好一個python文件,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=5000, debug=True)
複製代碼

編寫Dockerfile

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

編寫docker-compose

version: "3"

services:

  redis:
    image: redis

  web:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      REDIS_HOST: redis
複製代碼

能夠看到在文件中咱們定義了兩個service,一個叫作redis,一個叫作web,並且web的鏡像常見方式是build。

建立服務

docker-compose up -d
複製代碼

能夠看到這裏咱們也並無像以前同樣使用--link命令,是由於咱們經過docker-compose up啓動後會默認建立一個network。

在這裏插入圖片描述

咱們再具體看一下網絡中的具體內容,能夠看到咱們建立的兩個service確實是鏈接到這個network中的。因此他們兩個之間是能夠直接通訊的。

在這裏插入圖片描述

接下來咱們訪問一下,能夠看到效果和以前是同樣的

在這裏插入圖片描述

負載均衡

如今的需求是這樣的,咱們剛纔建立的那個flask-redis服務由於訪問的人多如今須要拓展幾個容器來同時提供服務,以平衡單個容器的訪問壓力,咱們如何實現這個需求呢?

水平拓展

咱們先來看一下如今的狀況

在這裏插入圖片描述

Docker Compose有一個scale參數,經過這個參數能夠實現容器的水平拓展。

docker-compose up --scale web=3 -d
複製代碼

在這裏插入圖片描述

咱們再經過命令查看一下如今的容器狀態

在這裏插入圖片描述

如今能夠看到咱們有了三個web服務,這三個web會同時對外提供服務,以減輕訪問單個容器的壓力。

出現的問題

可是如今這樣還有一個問題就是咱們每一個容器都是暴露出本身的端口5000,並且由於本地服務器只有一個8080端口,咱們無法讓多個容器都綁定上去,那咱們如何經過訪問服務器的地址來自動的映射到其餘容器呢?

解決辦法

這時咱們就須要haproxy來支持。

HAProxy是一個免費的負載均衡軟件,能夠運行於大部分主流的Linux操做系統上。

HAProxy提供了L4(TCP)和L7(HTTP)兩種負載均衡能力,具有豐富的功能。HAProxy的社區很是活躍,版本更新快速(最新穩定版1.7.2於2017/01/13推出)。最關鍵的是,HAProxy具有媲美商用負載均衡器的性能和穩定性。

由於HAProxy的上述優勢,它當前不只僅是免費負載均衡軟件的首選,更幾乎成爲了惟一選擇。

修改dokcer-compose.yml文件。

version: "3"

services:

  redis:
    image: redis

  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports: ["8080"]
    environment:
      REDIS_HOST: redis

  lb:
    image: dockercloud/haproxy
    links:
      - web
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock 
複製代碼

修改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)
複製代碼

修改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" ] 複製代碼

啓動服務

docker-compose up -d
複製代碼

作水平拓展

docker-compose up --scale web=3 -d
複製代碼

咱們先看一下service的具體狀況

在這裏插入圖片描述

如今來訪問一下服務

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

能夠看到咱們在訪問的過程當中是近乎輪詢式的,經過這樣的方式來減輕單個服務器的壓力,實現負載均衡。


歡迎你們關注咱們的公衆號:知識沉澱部落。

知識沉澱部落
相關文章
相關標籤/搜索