Docker Compose多容器部署


一、wordpress部署

這里先以wordpress的部署為例引出Docker Compose,wordpress的部署需要wordpress和mysql的鏡像:

(一)准備環境

1、拉取wordpress鏡像

[root@docker-node1 /]# docker pull wordpress

2、拉取mysql鏡像

[root@docker-node1 /]# docker pull mysql

3、鏡像列表

[root@docker-node1 /]# docker image ls
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
wordpress                        latest              0947f14b932b        25 hours ago        540MB
mysql                            latest              791b6e40940c        43 hours ago        465MB

(二)運行鏡像

1、運行mysql鏡像

[root@docker-node1 /]# docker run -d --name mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql
b6e7a57a5fcec79f436d3f65240adf833340b4a9640e3b4f9282870078fb8e57

上述命令中 -v指定存儲卷,MYSQL_ROOT_PASSWORD設置數據庫密碼,MYSQL_DATABASE指定創建數據庫的名稱,詳情參考:https://hub.docker.com/_/mysql

查看啟動的容器:

[root@docker-node1 /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
b6e7a57a5fce        mysql               "docker-entrypoint.s…"   6 minutes ago       Up 6 minutes        3306/tcp, 33060/tcp   mysql

2、啟動wordpress鏡像

[root@docker-node1 /]# docker run --name wordpress -e WORDPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 -d wordpress
6cf0c0fc2ef332728a3ea2bf2dbee65299441b26751d5c64f0a66b329f2679f6

上述命令中WORDPRESS_DB_HOST是需要連接的數據庫,指定的就是剛剛創建的mysql容器,這里沒有輸入WORDPRESS_DB_USER、WORDPRESS_DB_PASSWORD的密碼等環境信息,因為默認的就是mysql容器的用戶名、密碼,詳情查看:https://hub.docker.com/_/wordpress

然后查看容器信息:

[root@docker-node1 /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
6cf0c0fc2ef3        wordpress           "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        0.0.0.0:8080->80/tcp   wordpress
b6e7a57a5fce        mysql               "docker-entrypoint.s…"   20 minutes ago      Up 20 minutes       3306/tcp, 33060/tcp    mysql

目前兩個容器都已經起來了,最后可以訪問主機的8080端口即可。

二、Docker Compose

從上面的部署上可以看出存在以下問題:

  • 需要單獨拉取多個容器,一個個的部署
  • 需要同時管理多個容器(包括啟動、停止等動作)

那么有沒有一種類似批處理的方式,不需要這么繁瑣的過程呢?這就需要Docker Compose了。

(一)Docker Compose簡介

1、什么是Docker Compose?

  • Docker Compose是一個工具
  • 這個工具可以通過yml文件來定義多容器的應用
  • 通過一條命令就可以根據yml文件的定義去創建、管理多個容器

2、docker-compose.yml文件

Docker Compose中很重要的就是docker-compose.yml文件,這個文件包含了三個很重要的概念,分別是services、networks以及volumes。

  • services

  一個service就是一個container,這個container可以從dockerhub的image來,也可以從本地的Dockerfile創建的image來;service的啟動類似於docker run,當我們在使用docker run 是可以給其指定參數network和volume,同理也可以給service指定network和volume。

例如:

services:
    db:
        image:postgres:9.4
        volumes:
            -"db-data:/var/lib/postgresql/data"
        networks:
            -back-tier

上面這個yml文件中定義了一個service,其實就相當於下面這條命令:

docker run -d --network back-tier -v db-data:/var/lib/postgresql/data postgres:9.4
  • networks
networks:
    back-tier:
        driver:bridge

上面這個yml文件中定義了一個network,其實就相當於下面這條命令:

docker network create -d bridge back-tier        
  • volumes
volumes:
    db-data:

上面這個yml文件中定義了一個volume,其實就相當於下面這條命令:

 

docker volume create db-data

(二)Docker Compose環境准備

Docker Cmpose是一個工具,所以是需要安裝的,安裝詳情參考:https://docs.docker.com/compose/install/。

1、下載可執行文件

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

2、設置權限

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

3、查看版本

[root@docker-node1 ~]# docker-compose --version
docker-compose version 1.24.1, build 4667896

4、docker-compose中的常用命令

[root@docker-node1 compose-wordpress]# docker-compose --help
Define and run multi-container applications with Docker.

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

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information
  • docker-compose up

用於啟動service創建容器,執行yml文件

  • docker-compose -d

后台執行容器服務

  • docker-compose ps

顯示正在運行的容器

  • docker-compose stop

停止正在運行的容器服務

  • docker-compose down

停止容器服務,並且移除容器(container)、鏡像(image)、網絡(network)以及存儲卷(volume)

  • docker-compose images

顯示通過docker-compose up創建的容器服務的鏡像列表

  • docker-compose exec container(Names) bash

進入某個容器,可以在容器內部進行操作

(三)Docker Compose實戰

1、wordpress

  • 編寫docker-compose.yml文件
version: '3'   #docker-compose.yml版本

services:   #定義多個容器服務

  wordpress:   #wordpress容器名稱
    image: wordpress  #鏡像來源
    ports:        #端口映射
      - 8080:80
    environment:   #環境變量
      WORDPRESS_DB_HOST: mysql  #連接的數據庫,就是下面mysql容器的名稱
      WORDPRESS_DB_PASSWORD: root  #數據庫密碼
    networks:    #使用的網絡,是下面networks中定義的my-bridge
      - my-bridge

  mysql:   #mysql容器名稱
    image: mysql  #mysql鏡像
    command: --default-authentication-plugin=mysql_native_password  #解決數據庫密碼加密問題
    environment: #環境變量
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes: #定義存儲卷,就是下面volumes中定義的
      - mysql-data:/var/lib/mysql
    networks:
      - my-bridge

volumes:
  mysql-data:

networks:
  my-bridge:
    driver: bridge
  • 啟動services中的容器
[root@docker-node1 compose-wordpress]# ls
docker-compose.yml
[root@docker-node1 compose-wordpress]# docker-compose up

  通過docker-compose up啟動容器,這個命令默認執行的就是當前目錄下的docker-compose.yml文件,你也可以將這個命令寫完整就是docker-compose -f docker-compose.yml up

2、Flask Web

  • 新建app.py  docker-compose.yml  Dockerfile三個文件
[root@docker-node1 compose-flask]# ls
app.py  docker-compose.yml  Dockerfile
  • 編寫app.py文件
from flask import Flask
from redis import Redis
import os

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

@app.route('/')
def hello():
   return 'Hello World'

if __name__ == "__main__":
   app.run(host="0.0.0.0",port=5000,debug=True)
  • 編寫Dockerfile文件
FROM python:2.7
COPY . /app/
WORKDIR /app/
RUN pip install flask redis
EXPOSE 5000
CMD ["python","app.py"]
  • 編寫docker-compose.yml文件
version: "3"

services:

  redis:
    image: redis

  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8080:5000
    environment:
      REDIS_HOST: redis
  • 啟動容器服務
[root@docker-node1 compose-flask]# docker-compose up
  • 訪問服務

(四)水平擴展和負載均衡

1、scale 

在上面通過Docker  Compose完成了flask的應用部署,目前運行的容器:

[root@docker-node1 compose-flask]# docker-compose ps
        Name                       Command               State           Ports         
---------------------------------------------------------------------------------------
compose-flask_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp              
compose-flask_web_1     python app.py                    Up      0.0.0.0:8080->5000/tcp

通過docker-compose --help命令,可以看到有一個scale參數:

[root@docker-node1 compose-flask]# docker-compose --help
    scale              Set number of containers for a service

它的意思就是可以啟用多個應用容器:

[root@docker-node1 compose-flask]# docker-compose up --scale web=3 -d

  但是顯然這樣會出錯,為什么呢?因為三個容器端口映射都是一樣的,必然剩下的兩個應用容器會報端口占用的錯誤。此時需要修改一下docker-compose.yml文件將web應用的端口那一項配置去掉:

version: "3"

services:

  redis:
    image: redis

  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:          #去掉這一項
      - 8080:5000
    environment:
      REDIS_HOST: redis

這樣就可以了。

[root@docker-node1 compose-flask]# docker-compose up --scale web=3 -d
Recreating compose-flask_web_1 ... 
Recreating compose-flask_web_1 ... done
Recreating compose-flask_web_2 ... done
Recreating compose-flask_web_3 ... done

查看容器:

[root@docker-node1 compose-flask]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS        NAMES
d0ae3307eb9e        compose-flask_web   "python app.py"          51 seconds ago      Up 46 seconds       5000/tcp    compose-flask_web_1
67483b8decd3        compose-flask_web   "python app.py"          52 seconds ago      Up 47 seconds       5000/tcp    compose-flask_web_2
741766d49902        compose-flask_web   "python app.py"          52 seconds ago      Up 47 seconds       5000/tcp    compose-flask_web_3
be3800004658        redis               "docker-entrypoint.s…"   5 hours ago         Up 6 minutes        6379/tcp    compose-flask_redis_1

但是顯然這樣只能在容器內去訪問,因為端口沒有映射出來,那么這樣接下來怎么做呢?

我們接下來可以這樣做,用一個HAProxy的容器來接收請求,然后通過端口轉發給不同的web服務器,這樣就解決以下問題:

  •  外界不能訪問,只能容器內訪問
  • 負載均衡

2、水平擴展和負載均衡

  • 文件結構
[root@docker-node1 compose-flask]# ls
app.py  docker-compose.yml  Dockerfile
  • 編寫app.py
from flask import Flask
from redis import Redis
import os

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

@app.route('/')
def hello():
   return 'Hello World'

if __name__ == "__main__":
   app.run(host="0.0.0.0",port=80,debug=True)
  • 編寫Dockerfile文件
FROM python:2.7
COPY . /app/
WORKDIR /app/
RUN pip install flask redis
EXPOSE 80
CMD ["python","app.py"]
  • 編寫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 
  • 運行
[root@docker-node1 compose-flask]# docker-compose up -d
Creating network "compose-flask_default" with the default driver
Creating compose-flask_web_1   ... done
Creating compose-flask_redis_1 ... done
Creating compose-flask_lb_1    ... done

可以看到啟動了三個容器,分別為:

[root@docker-node1 compose-flask]# docker-compose ps
        Name                       Command               State                 Ports               
---------------------------------------------------------------------------------------------------
compose-flask_lb_1      /sbin/tini -- dockercloud- ...   Up      1936/tcp, 443/tcp,                
                                                                 0.0.0.0:8080->80/tcp              
compose-flask_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp                          
compose-flask_web_1     python app.py                    Up      5000/tcp    

我們看到web應用目前只有一個,可以啟動多個來處理請求:

[root@docker-node1 compose-flask]# docker-compose up --scale web=5 -d
compose-flask_redis_1 is up-to-date
Starting compose-flask_web_1 ... done
Creating compose-flask_web_2 ... done
Creating compose-flask_web_3 ... done
Creating compose-flask_web_4 ... done
Creating compose-flask_web_5 ... done
compose-flask_lb_1 is up-to-date

可以看到,直接將web應用啟動了5個容器,分擔從HAProxy的請求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM