【云原生|Docker系列5】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 )
                  +--------------------+        \_________________/
示例应用程序由以下部分组成:

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: {}

三、安装

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

3.1、pip 安装

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

sudo pip install -U docker-compose 
[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
...

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

3.3、版本查看

 docker-compose -v
[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

可以添加 bash 补全命令:

curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/d ocker-compose > /etc/bash_completion.d/docker-compose
[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

四、容器中执行

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
[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

实际上,查看下载的 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 "$@"

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

五、卸载

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

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

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

sudo pip uninstall docker-compose

六、使用

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)

2.编写 Dockerfile ⽂件。

FROM python:3.6-alpine 
ADD . /code 
WORKDIR /code 
RUN pip install redis flask 
CMD ["python", "app.py"] 

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

version: '3'
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
  redis:
    image: "redis:alpine"

4.运⾏ compose 项⽬

docker-compose up
[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

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

【云原生|Docker系列5】Docker Compose安装使用详解_第1张图片
点赞 收藏 关注

你可能感兴趣的:(云原生,入门到精通,docker,云原生,容器)