一、 Docker-Compose
1.1、 什么是Docker Compose
Compose 项目是 Docker 官方的开源项目,负责实现 Docker 容器集群的快速编排
开源代码在 https://github.com/docker/compose
在工作中,经常会碰到需要多个容器相互配合来完成的某项任务情况,例如工作中的 web 服务容器本身,往往会在后端加上数据库容器,甚至会有负责均衡器,比如 LNMP 服务
Compose 就是来做这个事情的,它允许用户通过一个单独的 docker-compose.yml 模板文件 YAML格式 来定义一组相关联的应用容器为一个项目 project
Compose 中有两个重要的概念:
- 服务 service :一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
- 项目 project :由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml中定义
Docker Compose:容器编排工具
- 基本定义:Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。
核心功能:
- 多容器管理:允许用户在一个 YAML 文件中定义和管理多个容器。
- 服务编排:配置容器间的网络和依赖关系。
- 一键部署:使用单一命令来启动、停止和重建服务。
- 主要用途:简化了多容器应用的配置和管理,特别适用于开发、测试和生产环境中的复杂应用。
1.2、 安装
# 从github中直接下载
# docker-compose版本选择:https://github.com/docker/compose/releases
# curl -L https://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# 从内网下载
wget http://192.168.3.200/Software/docker-compose-linux-x86_64
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
1.3、 命令
# Compose 大部分命令的对象即可以是项目的本身,也可以是指定为项目中的服务或者容器
# 执行docker-compose [COMMAND] --help 或者docker-compose help [COMMAND]可以查看命令的帮助信息
# 具体的使用格式
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS]
参数选项
-f,--file file指定模板文件,默认是docker-compose.yml模板文件,可以多次指定
-p,--project-name name指定项目名称,默认使用所在目录名称作为项目名称
--x-networking 使用Docker的后端可插拔网络特性
--x-networking-driver driver指定网络的后端驱动,默认使用bridge
--verbose 输入更多的调试信息
-v,--version 输出版本信息
Compose所支持的命令:
up 自动完成包括构建镜像、创建服务、启动服务并关联服务相关容器的一系列操作加-d参数在后台运行
ps 列出项目中目前所有的容器
restart 重启项目中的服务
stop 停止已存在的服务容器
start 启动已存在的服务容器
rm 删除所有停止状态的服务容器
down 停止容器并删除由其创建的容器,网络,卷和镜像
top 显示容器正在运行的进程
version 输出版本
build 构建项目中的服务容器
bundle 从Compose文件生成分布式应用程序包
config 验证并查看Compose文件
create 为服务创建容器
events 为项目中的每个容器流式传输容器事件
exec 这相当于docker exec
help 获得一个命令的帮助
kill 通过发送SIGKILL信号来强制停止服务容器
logs 查看服务容器的输出
pause 暂停一个容器
port 打印某个容器端口所映射的公共端口
pull 拉取服务依赖镜像
push 推送服务镜像
run 在指定服务上执行一个命令
scale 设置指定服务执行的容器个数
unpause 恢复处于暂停状态的容器
1.4、文件基本结构
版本(version): 指定 Compose 文件格式的版本。版本决定了可用的配置选项。
version 1.x 版本:
适用于 Docker 1.10 之前的版本;
不需要明确指定 version 字段;
只支持最基础的功能,配置文件中的所有服务都以顶级键的形式定义(没有 services 字段);
已过时,不建议使用。
version 2.x 版本:
适用于 Docker 1.10 及以上版本。
添加了对定义容器依赖、资源限制、网络和卷配置的支持,如容器的资源限制(如 CPU 和内存),以及容器之间的依赖管理。
主要适用于单机环境,允许在 Docker Compose 中定义较复杂的服务配置。
version 3.x 版本:
适用于 Docker 1.13 及以上版本。
增加了对 Docker Swarm 集群的支持;
重点在于跨主机集群管理;
增加了滚动更新、服务扩展等功能;
同时保留了单机环境的基本功能;
在新版的 Docker Compose (2.0及之后版本)中完全取消了 version 关键字。
服务(services): 定义了应用中的每个容器(服务)。每个服务可以使用不同的镜像、环境设置和依赖关系。
- 镜像(image): 从指定的镜像中启动容器,可以是存储仓库、标签以及镜像 ID
- 构建(build): 指定构建镜像的 dockerfile 的上下文路径,或者详细配置对象。用于构建镜像。
- 端口(ports): 映射容器和宿主机的端口
- 依赖(depends_on): 依赖配置的选项,意思是如果 服务启动是如果有依赖于其他服务的,先启动被依赖的服务,启动完成后在启动该服务
- 环境变量(environment): 设置服务运行所需的环境变量。
-
重启(restart): 控制容器的重启策略。在容器退出时,根据指定的策略自动重启容器。
no
:不自动重启。always
:无论退出状态码如何,总是重启容器。on-failure
:仅在容器非正常退出时(退出状态码非零)重启。unless-stopped
:除非手动停止,否则总是重启
-
服务卷(volumes): 定义服务使用的卷,用于数据持久化或在容器之间共享数据。
命令(command): 覆盖容器启动后默认执行的命令。在启动服务时运行特定的命令或脚本,常用于启动应用程序、执行初始化脚本等。
网络(networks): 定义了容器间的网络连接。
卷(volumes): 用于数据持久化和共享的数据卷定义。常用于数据库存储、配置文件、日志等数据的持久化。 在 Docker Compose 中,网络配置是一个重要的组成部分,它允许你定义容器之间的通信方式、隔离级别以及与外部网络的连接。
Docker Compose 支持几种类型的网络:
Bridge (桥接):
- 默认网路类型
- 适用于不同容器之间的通信
Host(主机):
- 容器共享宿主机的网络,没有网络隔离
None(无):
- 容器没有分配网络
Overlay(覆盖):
- 用于不同 Docker 守护进程主机上的容器间通信,主要用于 Docker Swarm。
定义网络
在 docker-compose.yml
文件中,你可以自定义网络配置。例如:
version: '3'
services:
web:
image: nginx
networks:
- webnet
database:
image: postgres
networks:
- webnet
networks:
webnet:
- 定义了两个服务:
web
和database
。 - 创建了一个名为
webnet
的网络。 - 两个服务都连接到这个网络,允许它们相互通信。
网络配置选项
别名(Aliases):
- 你可以为服务在特定网络中设置一个或多个别名。
networks:
webnet:
aliases:
- alias1
IPAM(IP 地址管理):
- 配置 IP 地址分配。
- 例如,指定子网和网关:
networks:
webnet:
ipam:
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
外部网络:
- 如果你想使用 Docker Compose 项目外部定义的网络,可以将其标记为外部网络。
networks:
externalnet:
external: true
注意事项
- 在默认情况下,Docker Compose 为每个项目设置一个默认网络,所有未指定网络的服务都会连接到这个默认网络。
- 使用自定义网络时,确保正确地指定了网络名称,并在服务定义中引用它。
- 网络配置可以根据你的项目需求灵活调整。
数据卷(Volumes)
在 Docker Compose 中使用数据卷(Volumes)是一种有效的方式来实现数据的持久化和共享。数据卷可以用于存储数据库的数据、保存应用的状态、共享文件等。
数据卷的类型
- 匿名卷:由 Docker 自动创建,没有指定明确的名称,适合临时数据。
- 命名卷:具有特定名称,便于引用和重用,适合持久化数据。
- 宿主机卷:直接映射宿主机的目录或文件到容器中,适合开发环境。
数据卷的定义
- 命名卷: 这里定义了一个名为
dbdata
的命名卷,并被db
服务用来存储数据库数据。
version: '3'
services:
db:
image: postgres
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
- 宿主机卷 这里将当前目录下的
html
文件夹挂载到了web
服务的/usr/share/nginx/html
目录。
version: '3'
services:
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html
- 匿名卷 在这个例子中,
app
服务将创建一个匿名卷来存储/app/data
目录的数据。
version: '3'
services:
app:
image: myapp
volumes:
- /app/data
数据卷的其他配置选项
- driver:指定卷的驱动。默认是
local
,但也可以使用其他插件,如nfs
或cloud
存储。 - driver_opts:为卷驱动提供额外的选项。
- labels:给卷添加标签,有助于组织和管理。
数据卷的优点
- 数据持久化:即使容器被删除,卷中的数据仍然保留。
- 效率:相比于复制数据,使用卷更高效。
- 共享:容器间可以共享数据。
注意事项
- 使用宿主机卷时,需要确保文件路径的正确性和权限问题。
- 命名卷在 Docker Compose 项目间是独立的,可以跨容器共享。
- 匿名卷通常用于临时或不重要的数据,因为它们的识别和管理比较困难。
1.5、部署wordpress
让我们通过一个简单的博客系统来演示 Docker Compose 的使用。这个系统将包括两个服务:一个是运行 WordPress 的 web 服务,另一个是 MySQL 数据库服务。我们将使用 Docker Compose 来定义和运行这两个服务。
步骤 1: 创建 Docker Compose 文件
首先,你需要创建一个名为 docker-compose.yml
的文件,并添加以下内容:
version: '3.8'
services:
db:
image: mysql:5.7
volumes:
- /data/mysql/data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
在 docker-compose.yml
文件中,定义了两个服务:db
(MySQL 数据库)和 wordpress
(WordPress 应用)。
MySQL 服务 (db
):
- 使用
mysql:5.7
镜像。 - 持久化 MySQL 数据到本地目录。
- 设置环境变量来配置 MySQL(root 密码、数据库名称、用户和密码)。
WordPress 服务 (wordpress
):
- 依赖于
db
服务。 - 使用最新版本的 WordPress 镜像。
- 端口映射将容器内的 80 端口映射到宿主机的 8000 端口,使 WordPress 在浏览器中可访问。
- 设置环境变量以连接到 MySQL 数据库。
这个配置是一个非常好的示例,展示了如何使用 Docker Compose 来运行和管理依赖于数据库的 web 应用。
步骤 2: 使用 Docker Compose 启动服务
- 在命令行执行
docker-compose up -d
会在后台启动定义在docker-compose.yml
文件中的所有服务。 - 一旦服务启动,您可以通过访问
http://localhost:8000
来设置和使用 WordPress。
步骤 3: 管理和停止服务
- 使用
docker-compose ps
来查看服务的状态。 docker-compose logs
可以用来查看服务的日志,这在调试问题时非常有用。- 当不再需要运行服务时,可以通过
docker-compose down
命令来停止并移除所有由docker-compose.yml
文件定义的服务和网络。请注意,这不会删除db_data
卷,因此您的数据库数据将被保留。
1.6、部署Python项目
# 1. 创建一个目录(里面包含需要的文件)
[root@zuolaoshi]# mkdir compose-py
# 2. 创建一个 Python 应用, 使用 Flask ,将数值记入 Redis
[root@zuolaoshi compose-py]# vim 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! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
# 3. 创建 requirements.txt 文件,里面是需要安装的 Python 包
[root@zuolaoshi compose-py]# vim requirements.txt
flask
redis
# 4. 创建 Dockerfile 文件
[root@zuolaoshi compose-py]# vim Dockerfile
FROM python
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["python", "app.py"]
# 这告诉Docker:
从 Python 开始构建镜像
将当前目录 . 添加到 /code 镜像中的路径
将工作目录设置为 /code
安装 Python 依赖项
将容器的默认命令设置为 python app.py
5. 创建 docker-compose.yml 文件
[root@zuolaoshi compose-py]# vim docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis"
# 此 Compose 文件定义了两个服务,web 和 redis
# 该web服务:
使用从 Dockerfile 当前目录中构建的镜像
将容器上的公开端口 5000 转发到主机上的端口 5000 我们使用 Flask Web 服务器的默认端口 5000
该 redis 服务使用从 Docker Hub 中提取的公共 Redis 映像
# 6. 使用 Compose 构建并运行您的应用程序
[root@zuolaoshi compose-py] docker-compose up -d
# 7. 测试访问,在浏览器访问 IP:5000 每刷新一次就会加一
CPU与内存限制
yaml文件添加deploy内容如下:
version: '3'
services:
web:
image: nginx
deploy:
resources:
#第一种方式
limits:
cpus: '0.50'
memory: 512M
#第二种方式
reservations:
memory: 200M
注意:reservations中不支持cpus,仅支持内存。