云原生|【云原生|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-certificatebackend: image: awesome/database volumes: - db-data:/etc/data networks: - back-tiervolumes: db-data: driver: flocker driver_opts: size: "10GiB"configs: httpd-config: external: truesecrets: server-certificate: external: truenetworks: # 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 % XferdAverage SpeedTimeTimeTimeCurrent DloadUploadTotalSpentLeftSpeed 00000000 --:--:--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 % XferdAverage SpeedTimeTimeTimeCurrent DloadUploadTotalSpentLeftSpeed 00000000 --:--:-- --:--:-- --:--:--0 1002585100258500172900:00:010:00:01 --:--:--3801 [root@iZhp33j6fklnmhbf0lz2obZ ~]# chmod +x /usr/local/bin/docker-compose

实际上,查看下载的 run. sh 脚本内容,如下:
set -eVERSION="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)) shiftcase "$arg" in -f|--file) value=https://www.it610.com/article/$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 Redisapp = 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安装使用详解】云原生|【云原生|Docker系列5】Docker Compose安装使用详解
文章图片

点赞 收藏 关注

    推荐阅读