zoukankan      html  css  js  c++  java
  • 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的请求。

  • 相关阅读:
    Vue组件别名及Ctrl跳转组件问题
    Scrapy Item Loaders
    scrapy Selector
    NSSM 注册windows服务
    windows 删除注册的服务
    RedisDesktopManager软件窗口不显示
    hexo + Matery主题 + Nginx + 阿里云 搭建个人博客网站
    sublime text3 安装插件
    关于 Windows 10 时间更新
    动画 | 什么是堆排序?
  • 原文地址:https://www.cnblogs.com/shenjianping/p/12257642.html
Copyright © 2011-2022 走看看