一、docker-compose介绍
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。 Docker-Compose项目由Python编写(v2版本后主要由golang编写) github:docker-compose,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。
Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。
- Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。
- 一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。
- 一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。
docker-compose 功能:
- 提供工具用于定义和运行多个docker容器应用;
- 使用yaml文件来配置应用服务(docker-compse.yml);
- 可以通过一个简单的命令docker-compse up可以按照依赖关系启动所有服务;
- 可以通过一个简单的命令docker-compose down停止所有服务;
- 当一个服务需要的时候,可以很简单地通过–scale进行扩容
Docker Compose有以下特征:
- 更高的可移植性,Docker Compose仅需一个
docker-compse up
可以完成按照依赖关系启动所有服务,然后使用docker-compose down
轻松将其拆解。帮助我们更轻松地部署复杂的应用程序; - 单个主机上的多个隔离环境,Compose可以使用项目名称将环境彼此隔离,这带可以在一台计算机上运行同一环境的多个副本,它可以防止不同的项目和服务相互干扰;
Docker-Compose缺陷:
只能用在单一host上进行容器编排,无法跨节点host对容器进行编排
二、安装docker-compose
2.1、docker-compose与docker 版本依赖关系
compose文件格式版本 | docker-compose 版本 | docker engie 版本 |
3.8 | 19.03.0+ | |
3.7 | 18.06.0+ | |
3.6 | 18.02.0+ | |
3.5 | 17.12.0+ | |
3.4 | 17.09.0+ | |
3.3 | 17.06.0+ | |
3.2 | 17.04.0+ | |
3.1 | 1.13.1+ | |
3.0 | 1.13.0+ | |
2.4 | v1.21.0+ | 17.12.0+ |
2.3 | v1.16.0+ | 17.06.0+ |
2.2 | v1.13.0+ | 1.13.0+ |
2.1 | v1.9.0+ | 1.12.0+ |
2.0 | 1.10.0+ | |
1.0 | 1.9.1.+ |
其他版本信息请查阅官网:https://docs.docker.com/compose/compose-file/compose-versioning/#version-3
docker-compose版本和compose文件格式版本的对应关系如下:
Docker Compose 版本 | Compose 文件格式版本 |
1.x | 1 |
2.x | 2 |
3.x | 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6 |
需要注意的是,Compose文件格式版本是指Compose文件中所用的语法版本,例如使用version: "3.4"来指定Compose文件格式版本为3.4。而Docker Compose版本则是指使用的Docker Compose工具的版本。
2.2、安装
2.2.1 、pip 安装
pip install docker-compose
2.2.2、yum 安装
yum install docker-compose
2.2.3、官网安装包安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
2.3、验证是否安装成功
docker-compose version
docker-compose version 1.21.0, build 5920eb0
docker-py version: 3.7.3
CPython version: 2.7.5
OpenSSL version: OpenSSL 1.0.2k-fips 26 Jan 2017
三、docker-compose 应用
3.1、docker-compose.yml 配置文件编写
详见:
3.2、使用实例
创建简单的flask web项目,使用到web服务和redis服务。
新建项目目录usecompose,在此目录下新建flask应用文件app.py
,内容如下:
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
#count = get_hit_count()
return 'Hello World! \n'
同目录新建依赖文件requirements.txt
,内容如下:
flask
redis
同目录新建Dockerfile
,内容如下
#基础镜像
FROM python3:1.3
#设置镜像的工作目录
WORKDIR /home/gyy01167504/daily-test/usecompose
#构建的时候设置环境变量
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV LC_ALL=en_US.utf-8
ENV LANG=en_US.utf-8
#安装gcc编译器
RUN yum install -y python-pip
#把刚刚我们创建的requirements.txt文件拷贝到镜像里
COPY requirements.txt requirements.txt
#下载requirements.txt里写好的flask和redis
RUN pip3 install -r requirements.txt
#指定5000为对外暴露的端口
EXPOSE 5000
#把当前目录拷贝进镜像里
COPY . .
#指定这个容器启动的时候要运行的命令,执行的命令为:flask run
CMD ["flask", "run"]
同目录新建docker-compose.yml
,内容如下:
version: "3.3"
#build后可以跟自己写的Dockerfile文件,写在build后面的Dockerfile文件用于生成镜像
services:
web:
build: .
ports:
- "8000:5000"
#如果build后没值,则镜像用从DockerHub上拉下来的redis镜像
redis:
image: "redis:latest"
拉取需要的镜像到本机
docker pull python3:1.3
docker pull redis:latest
启动docker-compse:
docker-compose up --build
Building web
Step 1/12 : FROM python3:1.3
---> f4b95d7919ec
Step 2/12 : WORKDIR /home/usecompose
---> 3c00d1379232
Step 3/12 : ENV FLASK_APP=app.py
---> 35a30912fb1e
Step 4/12 : ENV FLASK_RUN_HOST=0.0.0.0
---> 0d1e57292603
Step 5/12 : ENV LC_ALL=en_US.utf-8
---> 1f9f28e7f8fb
Step 6/12 : ENV LANG=en_US.utf-8
---> 649a76ac4f7e
Step 7/12 : RUN yum install -y python-pip
---> Running in bd6977d4615d
Loaded plugins: bestyumcache, branch, fastestmirror
Trying branch: stable
Determining fastest mirrors
Resolving Dependencies
--> Running transaction check
---> Package python-pip.noarch 0:7.1.0-1.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
python-pip noarch 7.1.0-1.el7 alios.7u2.base.x86_64 1.5 M
Transaction Summary
================================================================================
Install 1 Package
Total download size: 1.5 M
Installed size: 6.6 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : python-pip-7.1.0-1.el7.noarch 1/1
Verifying : python-pip-7.1.0-1.el7.noarch 1/1
Installed:
python-pip.noarch 0:7.1.0-1.el7
Complete!
Removing intermediate container bd6977d4615d
---> 3ada8adcd97b
Step 8/12 : COPY requirements.txt requirements.txt
---> 3934b409f73b
Step 9/12 : RUN pip3 install -r requirements.txt
---> Running in 67f939a97ebc
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting flask (from -r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/cd/77/59df23681f4fd19b7cbbb5e92484d46ad587554f5d490f33ef907e456132/Flask-2.0.3-py3-none-any.whl (95kB)
Collecting redis (from -r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/d6/f6/19237b28c632935c7359bddf703395ba13bbd134fc5e2eb297c4c120398c/redis-4.3.6-py3-none-any.whl (248kB)
Collecting Werkzeug>=2.0 (from flask->-r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/f4/f3/22afbdb20cc4654b10c98043414a14057cd27fdba9d4ae61cea596000ba2/Werkzeug-2.0.3-py3-none-any.whl (289kB)
Collecting click>=7.1.2 (from flask->-r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/4a/a8/0b2ced25639fb20cc1c9784de90a8c25f9504a7f18cd8b5397bd61696d7d/click-8.0.4-py3-none-any.whl (97kB)
Collecting itsdangerous>=2.0 (from flask->-r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/9c/96/26f935afba9cd6140216da5add223a0c465b99d0f112b68a4ca426441019/itsdangerous-2.0.1-py3-none-any.whl
Collecting Jinja2>=3.0 (from flask->-r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/20/9a/e5d9ec41927401e41aea8af6d16e78b5e612bca4699d417f646a9610a076/Jinja2-3.0.3-py3-none-any.whl (133kB)
Collecting packaging>=20.4 (from redis->-r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl (40kB)
Requirement already satisfied: typing-extensions; python_version < "3.8" in /usr/local/lib/python3.6/site-packages (from redis->-r requirements.txt (line 2))
Collecting importlib-metadata>=1.0; python_version < "3.8" (from redis->-r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/a0/a1/b153a0a4caf7a7e3f15c2cd56c7702e2cf3d89b1b359d1f1c5e59d68f4ce/importlib_metadata-4.8.3-py3-none-any.whl
Collecting async-timeout>=4.0.2 (from redis->-r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/d6/c1/8991e7c5385b897b8c020cdaad718c5b087a6626d1d11a23e1ea87e325a7/async_timeout-4.0.2-py3-none-any.whl
Collecting dataclasses; python_version < "3.7" (from Werkzeug>=2.0->flask->-r requirements.txt (line 1))
Downloading http://yum.tbsite.net/pypi/packages/fe/ca/75fac5856ab5cfa51bbbcefa250182e50441074fdc3f803f6e76451fab43/dataclasses-0.8-py3-none-any.whl
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib64/python3.6/site-packages (from Jinja2>=3.0->flask->-r requirements.txt (line 1))
Collecting pyparsing!=3.0.5,>=2.0.2 (from packaging>=20.4->redis->-r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl (98kB)
Collecting zipp>=0.5 (from importlib-metadata>=1.0; python_version < "3.8"->redis->-r requirements.txt (line 2))
Downloading http://yum.tbsite.net/pypi/packages/bd/df/d4a4974a3e3957fd1c1fa3082366d7fff6e428ddb55f074bf64876f8e8ad/zipp-3.6.0-py3-none-any.whl
Installing collected packages: dataclasses, Werkzeug, zipp, importlib-metadata, click, itsdangerous, Jinja2, flask, pyparsing, packaging, async-timeout, redis
Successfully installed Jinja2-3.0.3 Werkzeug-2.0.3 async-timeout-4.0.2 click-8.0.4 dataclasses-0.8 flask-2.0.3 importlib-metadata-4.8.3 itsdangerous-2.0.1 packaging-21.3 pyparsing-3.0.9 redis-4.3.6 zipp-3.6.0
Removing intermediate container 67f939a97ebc
---> 9e3d2ef13dde
Step 10/12 : EXPOSE 5000
---> 7e3ef9cfeb77
Step 11/12 : COPY . .
---> c29447e3ce81
Step 12/12 : CMD ["flask", "run"]
---> Running in 298d8ea26547
Removing intermediate container 298d8ea26547
---> 1ffb139f73c9
Successfully built 1ffb139f73c9
Successfully tagged usecompose_web:latest
Recreating usecompose_web_1 ... done
Starting usecompose_redis_1 ... done
Attaching to usecompose_redis_1, usecompose_web_1
redis_1 | 1:C 19 Apr 2023 10:26:39.049 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 19 Apr 2023 10:26:39.049 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 19 Apr 2023 10:26:39.049 # 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 19 Apr 2023 10:26:39.050 * monotonic clock: POSIX clock_gettime
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * Running mode=standalone, port=6379.
redis_1 | 1:M 19 Apr 2023 10:26:39.050 # Server initialized
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * Loading RDB produced by version 7.0.11
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * RDB age 52 seconds
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * RDB memory usage when created 0.82 Mb
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * Done loading RDB, keys loaded: 0, keys expired: 0.
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * DB loaded from disk: 0.000 seconds
redis_1 | 1:M 19 Apr 2023 10:26:39.050 * Ready to accept connections
web_1 | * Serving Flask app 'app.py' (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on all addresses.
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | * Running on http://172.18.0.3:5000/ (Press CTRL+C to quit)
web_1 | 30.39.220.140 - - [19/Apr/2023 18:27:39] "GET / HTTP/1.1" 200 -
查看容器启动情况:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49f93d2c3ab0 usecompose_web "flask run" 43 seconds ago Up 42 seconds 0.0.0.0:8000->5000/tcp usecompose_web_1
db7c00fd9a2d redis:latest "docker-entrypoint.s…" About an hour ago Up 42 seconds 6379/tcp usecompose_redis_1
测试访问:
curl http://11.166.91.186:8000/
Hello World!
四、docker-compose 常用命令
4.1 docker-compose up
构建镜像并启动容器
docker-compose up
Creating network "usecompose_default" with the default driver
Creating usecompose_web_1 ... done
Creating usecompose_redis_1 ... done
Attaching to usecompose_redis_1, usecompose_web_1
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # 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 20 Apr 2023 02:31:14.377 * monotonic clock: POSIX clock_gettime
redis_1 | 1:M 20 Apr 2023 02:31:14.378 * Running mode=standalone, port=6379.
redis_1 | 1:M 20 Apr 2023 02:31:14.378 # Server initialized
redis_1 | 1:M 20 Apr 2023 02:31:14.378 * Ready to accept connections
web_1 | * Serving Flask app 'app.py' (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on all addresses.
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)
4.2 docker-compose ps
查看docker-compose 启动的容器
docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------
usecompose_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
usecompose_web_1 flask run Up 0.0.0.0:8000->5000/tcp
4.3 docker-compose down
停止容器,删除容器,移除自定义网络
docker-compose down
Stopping usecompose_web_1 ... done
Stopping usecompose_redis_1 ... done
Removing usecompose_web_1 ... done
Removing usecompose_redis_1 ... done
Removing network usecompose_default
docker-compose ps
Name Command State Ports
------------------------------
4.4 docker-compose restart
重启容器
docker-compose restart
Restarting usecompose_web_1 ... done
Restarting usecompose_redis_1 ... done
4.5 docker-compose logs
查看容器日志
docker-compose logs
Attaching to usecompose_web_1, usecompose_redis_1
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
web_1 | * Serving Flask app 'app.py' (lazy loading)
redis_1 | 1:C 20 Apr 2023 02:31:14.377 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
web_1 | * Environment: production
redis_1 | 1:M 20 Apr 2023 02:31:14.377 * monotonic clock: POSIX clock_gettime
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
redis_1 | 1:M 20 Apr 2023 02:31:14.378 * Running mode=standalone, port=6379.
web_1 | Use a production WSGI server instead.
redis_1 | 1:M 20 Apr 2023 02:31:14.378 # Server initialized
web_1 | * Debug mode: off
redis_1 | 1:M 20 Apr 2023 02:31:14.378 * Ready to accept connections
web_1 | * Running on all addresses.
redis_1 | 1:signal-handler (1681958294) Received SIGTERM scheduling shutdown...
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
redis_1 | 1:M 20 Apr 2023 02:38:14.877 # User requested shutdown...
web_1 | * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)
redis_1 | 1:M 20 Apr 2023 02:38:14.877 * Saving the final RDB snapshot before exiting.
web_1 | 30.236.61.90 - - [20/Apr/2023 10:31:54] "GET / HTTP/1.1" 200 -
redis_1 | 1:M 20 Apr 2023 02:38:14.879 * DB saved on disk
web_1 | * Serving Flask app 'app.py' (lazy loading)
redis_1 | 1:M 20 Apr 2023 02:38:14.880 # Redis is now ready to exit, bye bye...
web_1 | * Environment: production
redis_1 | 1:C 20 Apr 2023 02:38:15.182 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
redis_1 | 1:C 20 Apr 2023 02:38:15.182 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
web_1 | * Debug mode: off
redis_1 | 1:C 20 Apr 2023 02:38:15.182 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
web_1 | * Running on all addresses.
redis_1 | 1:M 20 Apr 2023 02:38:15.182 * monotonic clock: POSIX clock_gettime
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * Running mode=standalone, port=6379.
web_1 | * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)
redis_1 | 1:M 20 Apr 2023 02:38:15.183 # Server initialized
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * Loading RDB produced by version 7.0.11
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * RDB age 1 seconds
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * RDB memory usage when created 0.82 Mb
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * Done loading RDB, keys loaded: 0, keys expired: 0.
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * DB loaded from disk: 0.000 seconds
redis_1 | 1:M 20 Apr 2023 02:38:15.183 * Ready to accept connections
打印具体某个services 日志
docker-compose logs -f web
Attaching to usecompose_web_1
web_1 | * Serving Flask app 'app.py' (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on all addresses.
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)
web_1 | 30.236.61.90 - - [20/Apr/2023 10:31:54] "GET / HTTP/1.1" 200 -
web_1 | * Serving Flask app 'app.py' (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on all addresses.
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)
4.6 docker-compose config
查看docker-compose 配置
docker-compose config --services
web
redis
docker-compose config # 实际就是docker-compose.yml
services:
redis:
image: redis:latest
web:
build:
context: /home/usecompose
ports:
- published: 8000
target: 5000
version: '3.3'
4.7、docker-compose images
列出镜像
docker-compose images
Container Repository Tag Image Id Size
--------------------------------------------------------------------
usecompose_redis_1 redis latest eca1379fe8b5 112 MB
usecompose_web_1 usecompose_web latest 1ffb139f73c9 890 MB
4.8、docker-compose top
展示容器进程信息
docker-compose top
usecompose_redis_1
UID PID PPID C STIME TTY TIME CMD
--------------------------------------------------------------------------
polkitd 56399 56337 0 10:38 ? 00:00:00 redis-server *:6379
usecompose_web_1
UID PID PPID C STIME TTY TIME CMD
---------------------------------------------------------------------------------------------
root 56868 56814 0 10:38 ? 00:00:00 /usr/bin/python3 /usr/local/bin/flask run
4.9 docker-compose scale
设置指定服务运行的容器个数。通过service=num的参数来设置数量
docker-compose scale web=3 redis=1
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
WARNING: The "web" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.
Starting usecompose_web_1 ... done
Starting usecompose_web_3 ... done
Creating usecompose_web_4 ... done
Desired container number already achieved