Docker基础知识 (4) - Docker Compose

 

1. Compose 简介

    Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML(YAML) 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

    YML(YAML) 文件配置参考 Springboot基础知识(02)- starter 简介和 YAML 配置
    
    Compose 使用的三个步骤:

        (1) 使用 Dockerfile 定义应用程序的环境。
        (2) 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
        (3) 执行 docker-compose up 命令来启动并运行整个应用程序。

    docker-compose.yml 示例如下(配置参数参考下文):

 1         # yaml 配置实例
 2         version: '3'
 3         services:
 4             web:
 5                 build: .
 6                 ports:
 7             - "5000:5000"
 8                 volumes:
 9             - .:/code
10                 - logvolume01:/var/log
11                 links:
12             - redis
13             redis:
14                 image: redis
15         volumes:
16             logvolume01: {}

 

2. Compose 安装

    1) Linux

        Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。

        运行以下命令以下载 Docker Compose 的当前稳定版本:

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

            注:安装其他版本,请替换 v2.6.1

        如果访问 GitHub 太慢,可以访问国内镜像,执行下面的命令:

            $ sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

        设置执行文件:

            $ sudo chmod +x /usr/local/bin/docker-compose   # 将可执行权限应用于二进制文件
            $ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose  # 创建软链
        
        测试运行:

            $ docker-compose --version
        
                Docker Compose version v2.6.1

    2) macOS

        Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Mac 用户不需要单独安装 Compose。Docker 安装说明可以参阅 MacOS Docker 安装。

    3) Windows

        Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Windows 用户不需要单独安装 Compose。Docker 安装说明可以参阅 Windows Docker 安装。


3. 示例

    1) 创建测试目录和文件

        $ mkdir composedemo
        $ cd composedemo

        在 composedemo 目录下创建 app.py 文件,内容如下:

 1             import time
 2 
 3             import redis
 4             from flask import Flask
 5 
 6             app = Flask(__name__)
 7             cache = redis.Redis(host='redis', port=6379)
 8 
 9 
10             def get_hit_count():
11                 retries = 5
12                 while True:
13                     try:
14                         return cache.incr('hits')
15                     except redis.exceptions.ConnectionError as exc:
16                         if retries == 0:
17                             raise exc
18                         retries -= 1
19                         time.sleep(0.5)
20 
21 
22             @app.route('/')
23             def hello():
24                 count = get_hit_count()
25                 return 'Hello World! I have been seen {} times.\n'.format(count)


        在 composedemo 目录下创建 requirements.txt 文件,内容如下:

            flask
            redis

    2) 创建 Dockerfile 文件

        在 composedemo 目录中,创建 Dockerfile 的文件,内容如下:

1             FROM python:3.7-alpine
2             WORKDIR /code
3             ENV FLASK_APP app.py
4             ENV FLASK_RUN_HOST 0.0.0.0
5             RUN apk add --no-cache gcc musl-dev linux-headers
6             COPY requirements.txt requirements.txt
7             RUN pip install -r requirements.txt
8             COPY . .
9             CMD ["flask", "run"]


        Dockerfile 内容说明:

            FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
            WORKDIR /code: 将工作目录设置为 /code。

            ENV FLASK_APP app.py
            ENV FLASK_RUN_HOST 0.0.0.0

                设置 flask 命令使用的环境变量。

            RUN apk add --no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。

            COPY requirements.txt requirements.txt
            RUN pip install -r requirements.txt

                复制 requirements.txt 并安装 Python 依赖项。

            COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
            CMD ["flask", "run"]: 容器提供默认的执行命令为:flask run。

    3) 创建 docker-compose.yml

        在 composedemo 目录下创建 docker-compose.yml 文件,内容如下:

1             # yaml 配置
2             version: '3'
3             services:
4                 web:
5                     build: .
6                     ports:
7                     - "5000:5000"
8                 redis:
9                     image: "redis:alpine"


        该 Compose 文件定义了两个服务:web 和 redis。

            web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。

            redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。

    4) 使用 Compose 命令构建和运行

        在 composedemo 目录下,执行以下命令来启动应用程序:

            $ docker-compose up

        如果在后台执行可以加上 -d 参数:

            $ docker-compose up -d

        控制台显示如下:

 1             [+] Running 2/0
 2             ⠿ Container composetest-redis-1  Created                                                                          0.0s
 3             ⠿ Container composetest-web-1    Created                                                                          0.0s
 4             Attaching to composetest-redis-1, composetest-web-1
 5             composetest-redis-1  | 1:C 31 Jul 2022 20:12:01.851 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
 6             composetest-redis-1  | 1:C 31 Jul 2022 20:12:01.851 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
 7             composetest-redis-1  | 1:C 31 Jul 2022 20:12:01.851 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
 8             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.852 * monotonic clock: POSIX clock_gettime
 9             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.855 * Running mode=standalone, port=6379.
10             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
11             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 # Server initialized
12             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
13             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 * Loading RDB produced by version 6.2.6
14             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 * RDB age 347 seconds
15             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 * RDB memory usage when created 0.79 Mb
16             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 # Done loading RDB, keys loaded: 1, keys expired: 0.
17             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 * DB loaded from disk: 0.000 seconds
18             composetest-redis-1  | 1:M 31 Jul 2022 20:12:01.856 * Ready to accept connections
19             composetest-web-1    | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
20             composetest-web-1    |  * Serving Flask app 'app.py'
21             composetest-web-1    |  * Debug mode: off
22             composetest-web-1    |  * Running on all addresses (0.0.0.0)
23             composetest-web-1    |    WARNING: This is a development server. Do not use it in a production deployment.
24             composetest-web-1    |  * Running on http://127.0.0.1:5000
25             composetest-web-1    |  * Running on http://172.18.0.2:5000 (Press CTRL+C to quit)


        浏览器访问 http://192.168.0.2:5000/ (Docker 容器所在宿主主机的 IP),页面显示如下:

            Hello World! I have been seen 1 times.


4. YML(YAML) 配置指令参考

    1) version
    
        指定本 yml 依从的 compose 哪个版本制定的,格式如下。
        
        version: "3.7"

    2) build
    
        指定为构建镜像上下文路径,格式如下。

        services:
            webapp:
                build: ./dir

    3) cap_add,cap_drop

        添加或删除容器拥有的宿主机的内核功能,格式如下。

        cap_add:
            - ALL # 开启全部权限
        cap_drop:
            - SYS_PTRACE # 关闭 ptrace权限

    4) cgroup_parent
    
        为容器指定父 cgroup 组,意味着将继承该组的资源限制,格式如下。
        
        cgroup_parent: m-executor-abcd

    5) command
    
        覆盖容器启动的默认命令,格式如下。
        
        command: ["bundle", "exec", "thin", "-p", "3000"]

    6) container_name
    
        指定自定义容器名称,而不是生成的默认名称,格式如下。
        
        container_name: my-web-container

    7) depends_on
    
        设置依赖关系,格式如下。

 1         version: "3.7"
 2         services:
 3             web:
 4                 build: .
 5                 depends_on:
 6                     - db
 7                     - redis
 8             redis:
 9                 image: redis
10             db:
11                 image: postgres


        以依赖性顺序启动服务。在以上示例中,先启动 db 和 redis ,才会启动 web。
        
            docker-compose up

        自动包含 SERVICE 的依赖项。在以上示例中,docker-compose up web 还将创建并启动 db 和 redis。

            docker-compose up SERVICE

        按依赖关系顺序停止服务。在以上示例中,web 在 db 和 redis 之前停止。

            docker-compose stop

        注:web 服务不会等待 redis db 完全启动 之后才启动。         

    8) deploy
    
        指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用,格式如下。

 1         version: "3.7"
 2         services:
 3             redis:
 4                 image: redis:alpine
 5                 deploy:
 6                     mode:replicated
 7                     replicas: 6
 8                     endpoint_mode: dnsrr
 9                     labels:
10                         description: "This redis service label"
11                     resources:
12                         limits:
13                             cpus: '0.50'
14                             memory: 50M
15                         reservations:
16                             cpus: '0.25'
17                             memory: 20M
18                     restart_policy:
19                         condition: on-failure
20                         delay: 5s
21                         max_attempts: 3
22                         window: 120s


    9) devices
    
        指定设备映射列表,格式如下。

        devices:
            - "/dev/ttyUSB0:/dev/ttyUSB0"

    10) dns
    
        自定义 DNS 服务器,可以是单个值或列表的多个值,格式如下。

        dns: 8.8.8.8

        dns:
            - 8.8.8.8
            - 9.9.9.9

    11) dns_search
    
        自定义 DNS 搜索域。可以是单个值或列表,格式如下。

        dns_search: example.com

        dns_search:
            - dc1.example.com
            - dc2.example.com

    12) entrypoint
    
        覆盖容器默认的 entrypoint,格式如下。

            entrypoint: /code/entrypoint.sh

        或

            entrypoint:
                - php
                - -d
                - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
                - -d
                - memory_limit=-1
                - vendor/bin/phpunit

    13) env_file
    
        从文件添加环境变量。可以是单个值或列表的多个值,格式如下。
            
            env_file: .env

        或
            env_file:
                - ./common.env
                - ./apps/web.env
                - /opt/secrets.env  
    
    14) environment
    
        添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False,格式如下。

        environment:
            RACK_ENV: development
            SHOW: 'true'
            
    15) expose
    
        暴露端口,但不映射到宿主机,只被连接的服务访问,仅可以指定内部端口为参数,格式如下。

        expose:
            - "3000"
            - "8000"

    16) extra_hosts
    
        添加主机名映射。类似 docker client --add-host,格式如下。

        extra_hosts:
            - "somehost:162.242.195.82"
            - "otherhost:50.31.209.229"

        以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:

            162.242.195.82  somehost
            50.31.209.229   otherhost
    
    17) healthcheck
    
        用于检测 docker 服务是否健康运行,格式如下。

        healthcheck:
            test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
            interval: 1m30s # 设置检测间隔
            timeout: 10s # 设置检测超时时间
            retries: 3 # 设置重试次数
            start_period: 40s # 启动后,多少秒开始启动检测程序
    
    18) image
    
        指定容器运行的镜像,以下格式都可以,格式如下。

        image: redis
        image: ubuntu:14.04
        image: tutum/influxdb
        image: example-registry.com:4000/postgresql
        image: a4bc65fd # 镜像id

    19) logging
    
        服务的日志记录配置,格式如下,格式如下。

 1         logging:
 2             driver: json-file   # json-file | syslog | none
 3             options:
 4                 max-size: "200k" # 单个文件大小为200k
 5                 max-file: "10" # 最多10个文件
 6         
 7  8              
 9         logging:
10             driver: syslog
11             options:                
12                 syslog-address: "tcp://192.168.0.42:123"

   
    20) network_mode
    
        设置网络模式,格式如下。

        network_mode: "bridge" | "host" | "none" | "service:[service name]" | "container:[container name/id]"
              
    21) secrets
    
        存储敏感数据,例如密码,格式如下。

 1         version: "3.1"
 2         services:
 3 
 4         mysql:
 5             image: mysql
 6             environment:
 7                 MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
 8             secrets:
 9                 - my_secret
10 
11         secrets:
12             my_secret:
13                 file: ./my_secret.txt


    22) security_opt
    
        修改容器默认的 schema 标签,格式如下。

        security-opt:
            - label:user:USER   # 设置容器的用户标签
            - label:role:ROLE   # 设置容器的角色标签
            - label:type:TYPE   # 设置容器的安全策略标签
            - label:level:LEVEL  # 设置容器的安全等级标签

    23) restart
    
        格式如下。

        restart:no | always | on-failure | unless-stopped

        no:是默认的重启策略,在任何情况下都不会重启容器。
        always:容器总是重新启动。
        on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
        unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

    24) stop_grace_period
    
        指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器,格式如下。

        stop_grace_period: 1s # 等待 1 秒
        stop_grace_period: 1m30s # 等待 1 分 30 秒
    
    25) stop_signal
    
        设置停止容器的替代信号。默认情况下使用 SIGTERM ,格式如下。

        stop_signal: SIGUSR1  # 使用 SIGUSR1 替代信号 SIGTERM 来停止容器
    
    26) sysctls
    
        设置容器中的内核参数,可以使用数组或字典格式,格式如下。

1         sysctls:
2             net.core.somaxconn: 1024
3             net.ipv4.tcp_syncookies: 0
4 
5         sysctls:
6             - net.core.somaxconn=1024
7             - net.ipv4.tcp_syncookies=0


    27) tmpfs
    
        在容器内安装一个临时文件系统。可以是单个值或列表的多个值,格式如下。

        tmpfs: /run

        tmpfs:
            - /run
            - /tmp
                
    28) ulimits
    
        覆盖容器默认的 ulimit,格式如下。

        ulimits:
            nproc: 65535
            nofile:
                soft: 20000
                hard: 40000

    29) volumes
    
        将主机的数据卷或着文件挂载到容器里,格式如下。

1         version: "3.7"
2         services:
3             db:
4                 image: postgres:latest
5                 volumes:
6                     - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
7                     - "/localhost/data:/var/lib/postgresql/data"

 



posted @ 2022-08-04 13:57  垄山小站  阅读(307)  评论(0编辑  收藏  举报