• 19、Docker Compose


      编排(Orchestration)功能是复杂系统实现灵活可操作性的关键。特别是docker应用场景中,编排意味着用户可以灵活地对各种容器资源实现定义和管理。

      在我们部署多容器的应用时:

    • 要从Dockerfile build image或者从dockerhub拉取image
    • 要创建多个container
    • 要管理这些container(启动、停止、删除)

      为了方便我们部署和管理多容器的应用,docker compose就出现了。

    docker-compose

    19.1 什么是docker compose

      docker compose项目是docker官方的开源项目,负责实现对docker容器集群的快速编排。其代码在GitHub上开源https://github.com/docker/compose

    • Docker Compose是一个工具
    • 这个工具可以通过一个yml文件定义多容器的docker应用
    • 通过一条命令就可以根据yml文件的定义去创建或者管理这多个容器

      Compose定位是“定义和运行多个docker容器的应用”。它允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)。

    Compose中有三个重要的概念:

    • 服务(services)

      一个service代表一个container,这个container可以从dockerhub的image创建,或者从本地的Dockerfile build出来的image来创建。

      service的启动类似docker run,我们可以给其指定network和volume,所以可以给service指定network和volume的引用。

    • 网络(networks)
    • 数据卷(volumes)

    举例

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

      这个例子类似于运行了下面这条命令:

    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文件:

    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 官方安装文档

    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.
    ' % (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可以实现多服务器上的容器编排。

  • 相关阅读:
    atitit.session的原理以及设计 java php实现的异同
    atitit.破解 拦截 绕过 网站 手机 短信 验证码 之自动获取手机短信方式 attilax 总结
    java softReference 详解
    android开发:TextView中android:autoLink属性的作用
    抽象类和接口的简单差别
    android一个简单的线程实例
    Java 批注
    最简单的菜单操作
    AsyncTask的参数介绍
    (转)android中ListView在划屏到底部的时候动态添加ListView的Item实现
  • 原文地址:https://www.cnblogs.com/jie-fang/p/10279774.html
Copyright © 2020-2023  润新知