• 【云原生】Docker Compose安装使用详解


    前言

    Docker Compose是一种用于定义和共享多容器应用程序的工具。本文主要介绍 Compose 项目的具体情况,以及如何进行安装和使用。

    一、Compose 简介

    Compose 项目是 Docker 官方的开源项目,负责实现对基于 Docker器的多应用服务的快速编排。从功能上看,跟 OpenStack 中的 Heat 十分类似。其代码目前在 https://github.com/docker/compose上开源。Compose 定位是“定义和运行多个 Docker 容器的应用”,其前身是开源项目 Fig, 目前仍然兼容 Fig 格式的模板文件。

    通过前面的学习我们已经知道使用一个 Dockerfile 模板文件,可以让用户很方便地定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括前端的负载均衡容器等。

    Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml模板文件 (YAML 格式)来定义一组相关联的应用容器为一个服务栈 (stack)。

    Compose 中有两个重要的概念:

    服务 (service) :一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
    项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

    Compose 的默认管理对象是项⽬,通过子命令对项⽬中的多个服务进行便捷的生命周期管理。

    Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API, 就可以在其上利用 Compose 来进行编排管理。

    二、Compose示例

    以下示例通过一个具体的示例应用程序说明了 Compose 规范概念。

    将应用程序拆分为前端 Web 应用程序和后端服务。

    前端在运行时使用由基础设施管理的 HTTP 配置文件进行配置,提供外部域名和由平台的安全机密存储注入的 HTTPS 服务器证书。

    后端将数据存储在持久卷中。

    两个服务在隔离的后端网络上相互通信,而前端也连接到前端网络并公开端口 443 以供外部使用。

    (External user) --> 443 [frontend network]
                                |
                      +--------------------+
                      |  frontend service  |...ro...
                      |      "webapp"      |...ro... #secured
                      +--------------------+
                                |
                            [backend network]
                                |
                      +--------------------+
                      |  backend service   |  r+w   ___________________
                      |     "database"     |=======( persistent volume )
                      +--------------------+        \_________________/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    示例应用程序由以下部分组成:

    2 个服务,由 Docker 镜像支持:webapp和database

    1 个密钥(HTTPS 证书),注入前端

    1个配置(HTTP),注入前端

    1 个持久卷,附加到后端

    2 个网络

    services:
      frontend:
        image: awesome/webapp
        ports:
          - "443:8043"
        networks:
          - front-tier
          - back-tier
        configs:
          - httpd-config
        secrets:
          - server-certificate
    
      backend:
        image: awesome/database
        volumes:
          - db-data:/etc/data
        networks:
          - back-tier
    
    volumes:
      db-data:
        driver: flocker
        driver_opts:
          size: "10GiB"
    
    configs:
      httpd-config:
        external: true
    
    secrets:
      server-certificate:
        external: true
    
    networks:
      # The presence of these objects is sufficient to define them
      front-tier: {}
      back-tier: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    三、安装

    Compose ⽀持 Linux、macOS、Windows 10 三⼤平台。Compose 可以通过 Python 的包管理⼯ 具 pip 进⾏安装,也可以直接下载编译好的⼆进制⽂件使⽤,甚⾄能够直接在 Docker 容器中运⾏。 前两种⽅式是传统⽅式,适合本地环境下安装使⽤;最后⼀种⽅式则不破坏系统环境,更适合云计算场景。

    3.1、pip 安装

    这种⽅式是将 Compose 当作⼀个 Python 应⽤来从 pip 源中安装。执⾏安装命令:

    sudo pip install -U docker-compose 
    
    • 1
    [root@iZhp33j6fklnmhbf0lz2obZ ~]# sudo pip3 install -U docker-compose 
    WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
    Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
    To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
    Looking in indexes: http://mirrors.cloud.aliyuncs.com/pypi/simple/
    Collecting docker-compose
      Downloading http://mirrors.cloud.aliyuncs.com/pypi/packages/f3/3e/ca05e486d44e38eb495ca60b8ca526b192071717387346ed1031ecf78966/docker_compose-1.29.2-py2.py3-none-any.whl (114 kB)
         |████████████████████████████████| 114 kB 51.5 MB/s            
    Collecting distro<2,>=1.5.0
      Downloading http://mirrors.cloud.aliyuncs.com/pypi/packages/e1/54/d08d1ad53788515392bec14d2d6e8c410bffdc127780a9a4aa8e6854d502/distro-1.7.0-py3-none-any.whl (20 kB)
    Collecting python-dotenv<1,>=0.13.0
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.2、二进制安装

    在 Linux 上的也安装⼗分简单,从 官⽅ GitHub Release 处直接下载编译好的⼆进制⽂件即可。例 如,在 Linux 64 位系统上直接下载对应的⼆进制包。

    sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-` uname -s`-`uname -m` > /usr/local/bin/docker-compose 
    sudo chmod +x /usr/local/bin/docker-compose
    
    • 1
    • 2

    3.3、版本查看

     docker-compose -v
    
    • 1
    [root@iZhp33j6fklnmhbf0lz2obZ ~]# docker-compose -v
    /usr/local/lib/python3.6/site-packages/paramiko/transport.py:33: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release.
      from cryptography.hazmat.backends import default_backend
    docker-compose version 1.29.2, build unknown
    
    • 1
    • 2
    • 3
    • 4

    可以添加 bash 补全命令:

    curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/d ocker-compose > /etc/bash_completion.d/docker-compose
    
    • 1
    [root@iZhp33j6fklnmhbf0lz2obZ ~]# curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/d ocker-compose > /etc/bash_completion.d/docker-compose
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:--  0:00:34 --:--:--     0
    
    • 1
    • 2
    • 3
    • 4

    四、容器中执行

    Compose 既然是一个 Python 应用,自然也可以直接用容器来执行它:

    curl -L https://github.com/docker/compose/releases/download/1.29.2/run.sh > /usr/local/bin/docker-compose 
    chmod +x /usr/local/bin/docker-compose
    
    • 1
    • 2
    [root@iZhp33j6fklnmhbf0lz2obZ ~]# curl -L https://github.com/docker/compose/releases/download/1.29.2/run.sh > /usr/local/bin/docker-compose 
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
    100  2585  100  2585    0     0   1729      0  0:00:01  0:00:01 --:--:--  3801
    [root@iZhp33j6fklnmhbf0lz2obZ ~]# chmod +x /usr/local/bin/docker-compose
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实际上,查看下载的 run. sh 脚本内容,如下:

    set -e
    
    VERSION="1.29.2"
    IMAGE="docker/compose:$VERSION"
    
    
    # Setup options for connecting to docker host
    if [ -z "$DOCKER_HOST" ]; then
        DOCKER_HOST='unix:///var/run/docker.sock'
    fi
    if [ -S "${DOCKER_HOST#unix://}" ]; then
        DOCKER_ADDR="-v ${DOCKER_HOST#unix://}:${DOCKER_HOST#unix://} -e DOCKER_HOST"
    else
        DOCKER_ADDR="-e DOCKER_HOST -e DOCKER_TLS_VERIFY -e DOCKER_CERT_PATH"
    fi
    
    
    # Setup volume mounts for compose config and context
    if [ "$(pwd)" != '/' ]; then
        VOLUMES="-v $(pwd):$(pwd)"
    fi
    if [ -n "$COMPOSE_FILE" ]; then
        COMPOSE_OPTIONS="$COMPOSE_OPTIONS -e COMPOSE_FILE=$COMPOSE_FILE"
        compose_dir="$(dirname "$COMPOSE_FILE")"
        # canonicalize dir, do not use realpath or readlink -f
        # since they are not available in some systems (e.g. macOS).
        compose_dir="$(cd "$compose_dir" && pwd)"
    fi
    if [ -n "$COMPOSE_PROJECT_NAME" ]; then
        COMPOSE_OPTIONS="-e COMPOSE_PROJECT_NAME $COMPOSE_OPTIONS"
    fi
    if [ -n "$compose_dir" ]; then
        VOLUMES="$VOLUMES -v $compose_dir:$compose_dir"
    fi
    if [ -n "$HOME" ]; then
        VOLUMES="$VOLUMES -v $HOME:$HOME -e HOME" # Pass in HOME to share docker.config and allow ~/-relative paths to work.
    fi
    i=$#
    while [ $i -gt 0 ]; do
        arg=$1
        i=$((i - 1))
        shift
    
        case "$arg" in
            -f|--file)
                value=$1
                i=$((i - 1))
                shift
                set -- "$@" "$arg" "$value"
    
                file_dir=$(realpath "$(dirname "$value")")
                VOLUMES="$VOLUMES -v $file_dir:$file_dir"
            ;;
            *) set -- "$@" "$arg" ;;
        esac
    done
    
    # Setup environment variables for compose config and context
    ENV_OPTIONS=$(printenv | sed -E "/^PATH=.*/d; s/^/-e /g; s/=.*//g; s/\n/ /g")
    
    # Only allocate tty if we detect one
    if [ -t 0 ] && [ -t 1 ]; then
        DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -t"
    fi
    
    # Always set -i to support piped and terminal input in run/exec
    DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -i"
    
    
    # Handle userns security
    if docker info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -q 'name=userns'; then
        DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS --userns=host"
    fi
    
    # shellcheck disable=SC2086
    exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $ENV_OPTIONS $VOLUMES -w "$(pwd)" $IMAGE "$@"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    可以看到,它其实是下载了 docker/compose 镜像并运行。

    五、卸载

    如果是二进制包方式安装的,删除二进制文件即可:

    sudo rm /usr/local/bin/docker-compose
    
    • 1

    如果是通过 Python pip 工具安装的,则可以执行如下命令删除:

    sudo pip uninstall docker-compose
    
    • 1

    六、使用

    1.⽤ Python 编写记录访问web网站技术的app.py文件。

    from flask import Flask
    from redis import Redis
    
    app = Flask(__name__)
    redis = Redis(host='redis', port=6379)
    
    @app.route('/')
    def hello():
        count = redis.incr('hits')
        return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
    
    if __name__ == "__main__":
    	# 设置运行信息
        app.run(host="127.0.0.1",  debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.编写 Dockerfile ⽂件。

    FROM python:3.6-alpine 
    ADD . /code 
    WORKDIR /code 
    RUN pip install redis flask 
    CMD ["python", "app.py"] 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.编写 docker-compose.yml ⽂件。

    version: '3'
    services:
      web:
        build: .
        ports:
          - "8000:5000"
        volumes:
          - .:/code
      redis:
        image: "redis:alpine"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.运⾏ compose 项⽬

    docker-compose up
    
    • 1
    [root@iZhp33j6fklnmhbf0lz2obZ admin]# docker-compose up
    Starting admin_web_1   ... done
    Starting admin_redis_1 ... done
    Attaching to admin_web_1, admin_redis_1
    redis_1  | 1:C 17 Aug 2022 06:49:50.124 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis_1  | 1:C 17 Aug 2022 06:49:50.124 # Redis version=7.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1  | 1:C 17 Aug 2022 06:49:50.124 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    redis_1  | 1:M 17 Aug 2022 06:49:50.125 * monotonic clock: POSIX clock_gettime
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * Running mode=standalone, port=6379.
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 # Server initialized
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 # 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.redis_1  | 1:M 17 Aug 2022 06:49:50.126 * Loading RDB produced by version 7.0.4
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * RDB age 1576 seconds
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * RDB memory usage when created 0.82 Mb
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * Done loading RDB, keys loaded: 0, keys expired: 0.
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * DB loaded from disk: 0.000 seconds
    redis_1  | 1:M 17 Aug 2022 06:49:50.126 * Ready to accept connections
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    5.访问

    此时访问本地 8000 端⼝,每访问一次,计数加 1。

    [root@iZhp33j6fklnmhbf0lz2obZ admin]# curl -v localhost:8000
    * Rebuilt URL to: localhost:8000/
    *   Trying ::1...
    * TCP_NODELAY set
    * Connected to localhost (::1) port 8000 (#0)
    > GET / HTTP/1.1
    > Host: localhost:8000
    > User-Agent: curl/7.61.1
    > Accept: */*
    > 
    * HTTP 1.0, assume close after body
    < HTTP/1.0 200 OK
    < Content-Type: text/html; charset=utf-8
    < Content-Length: 44
    < Server: Werkzeug/2.0.3 Python/3.6.15
    < Date: Wed, 17 Aug 2022 06:56:07 GMT
    < 
    Hello World! 该页面已被访问 8 次。
    * Closing connection 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述
    点赞 收藏 关注

  • 相关阅读:
    VScode将代码提交到远程服务器、同时解决每次提交都要输入密码的问题(这里以gitee为例子)
    【uniapp微信小程序+springBoot(binarywang)
    【操作系统】段式存储中 逻辑地址转物理地址详细分析
    谷歌最新开源大模型 Gemma,采用与创建 Gemini 模型相同的研究和技术,专为负责任的人工智能开发而设计。
    力扣(LeetCode)124. 二叉树中的最大路径和(C++)
    The Missing Semester of Your CS Education(计算机教育中缺失的一课)
    c# 浅拷贝vs深拷贝
    PDF如何转Word?用这两个方法轻松搞定
    yarn资源配置及使用
    Java并发之AQS详解
  • 原文地址:https://blog.csdn.net/qq_35764295/article/details/126351551