docker - 容器编排
什么是docker compose
docker-compose 是 Docker 官方的开源项目,使用 python 编写,实现上调用了 Docker 服务的 API 进行容器管理及编排,其官方定义为定义和运行多个 Docker 容器的应用。
docker-compose 中有两个非常重要的概念:
服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目( project ):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义, 整个 docker-compose.yml 定义一个项目。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周 期管理。通过 compose 可以方便的管理多个服务。
为什么需要docker compose
• Docker 是一个轻量化的应用程序,Docker 官方推荐每个 Docker 容器中只运行一 个进程。
• 如果一个应用需要涉及到 MySQL、nginx 等环境, 那么我们需要分别为应用、数 据库和 nginx 创建单独的 docker 容器,然后分别启动容器。
• 想象一下,当我们构建好 Docker 之后,每次启动应用,都至少需要 docker run 三次, 或者写一些脚本来实现, 这样会比较繁琐。
• 另外,这些 docker 容器都是分散独立的,也不方便镜像管理。那既然这些 docker 容器 都是为了同一个应用服务,我们就应该把它们放到一起,这就引出了 docker compose 来解决这类型的问题。
docker compose功能
1、使用步骤
• 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中 一起运行。
• 最后,执行 docker compose up 命令来启动并运行整个应用程序。
2、核心功能
Compose 具有管理应用程序整个生命周期的命令:
• 启动,停止和重建服务
• 查看正在运行的服务的状态
• 流式传输运行服务的日志输出
• 在服务上运行一次性命令
docker compose使用场景
单主机部署
快速搭建一个单节点开发或者测试环境,方便使用。
不同环境隔离
通过指定 project 来运行不同的环境,实现隔离的目的。
docker compose文件
文件语法版本
目前官方支持三个大版本, 即 Version 1、Version 2 及 Version 3, 其中 Version 1 已 经被废弃掉了。
当前最新的版本是 3.8,它支持的 Docker Engine 版本不得低于 19.03.0。 本课程主 要基于 3.8 版本的 Compose file 语法进行讲解,其他版本介绍参见https://docs.docker.com/reference/compose-file/legacy-versions/
文件基本结构及常见指令
version: "3.8" # 定义版本, 表示当前使用的 docker-compose 语法的版本
services: # 服务,可以存在多个
servicename: # 服务名字,它也是内部 bridge 网络可以使用的 DNS name, 如果不是集群模式相当于 docker run 的时候指定的一个名称,
#集群(Swarm)模式是多个容器的逻辑抽象
image: # 必选,镜像的名字
command: # 可选,如果设置,则会覆盖默认镜像里的 CMD 命令
environment: # 可选,等价于 docker container run 里的 --env 选项 设置环境变量
volumes: # 可选,等价于 docker container run 里的 -v 选项 绑定数据 卷
networks: # 可选,等价于 docker container run 里的 --network 选项 指定网络
ports: # 可选,等价于 docker container run 里的 -p 选项指定端口映 射
expose: # 可选,指定容器暴露的端口
build: #构建目录
depends_on: #服务依赖配置
env_file: #环境变量文件
servicename2:
image:
command:
networks:
ports:
servicename3:
#...
volumes: # 可选,等价于 docker volume create
networks: # 可选,等价于 docker network create
常见字段格式语法
image
指定容器运行的镜像。以下格式都可以:
image: redis
image: redis:5
image:
redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398 bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis
创建一个docker-compose.yml文件,并编写内容

然后构建,执行命令 docker compose up -d

就创建了服务的网络和容器,并把容器和网络关联。
进行清理,执行命令 docker compose down

command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
command: bundle exec thin -p 3000
在yml中加入如下

然后构建,查看启动的容器的详情,cmd字段就被改了

但是也导致,nginx没有完成启动。
执行命令 docker exec -it prj2-web-1 curl 127.0.0.1

因为command命令把nginx的启动命令换了,所以nginx压根没有启动。
entrypoint
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
对yml文件进行修改

然后构建,检查启动容器的详情,Entrypoint就被改了

但是也导致,nginx没有完成启动。
执行命令 docker exec -it prj2-web-1 curl 127.0.0.1

是因为entrypoint也将nginx的启动命令覆盖了
environment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以 确保 YML 解析器不会将其转换为 True 或 False。
#map 语法
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
#数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
修改yml文件

然后构建,查看容器详情中的Env字段

环境变量就配进去了
networks
指定容器运行的网络:
配置容器网络
services:
frontend:
image: awesome/webapp
networks:
- front-tier
- back-tier
monitoring:
image: awesome/monitoring
networks:
- admin
backend:
image: awesome/backend
networks:
back-tier:
aliases:
- database
admin:
aliases:
- mysql
networks:
front-tier:
back-tier:
admin:
配置网络驱动和子网信息
services:
frontend:
image: awesome/webapp
networks:
front-tier:
ipv4_address: 172.16.238.10
networks:
front-tier:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
修改yml文件。

执行命令 docker compose config

如果正常打印,就说明语法是ok的。
构建项目,然后查看容器详情的网络字段

volumes
将主机的数据卷或者文件挂载到容器里。
#短语法
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
#完整语法
services:
backend:
image: awesome/backend
volumes:
- type: volume
#命名卷
source: db-data
target: /data
volume:
nocopy: true
#绑定卷
- type: bind
source: /var/run/postgres/postgres.sock
target: /var/run/postgres/postgres.sock
volumes:
db-data:
修改yml文件

执行命令 docker compose config
语法有问题会报错,没问题就会对yml解释
构建项目,然后再进入容器访问nginx主页

返回错误页面。
然后再宿主机的绑定卷位置创建index.html

在容器内部再次访问nginx主页

访问成功。也就是容器和宿主机目录完成了数据绑定。
ports
指定端口映射。以下格式都可以:
#完整语法
ports:
- target: 80
host_ip: 127.0.0.1
published: 8080
protocol: tcp
mode: host
- target: 80
host_ip: 127.0.0.1
published: 8000-9000
protocol: tcp
mode: host
#短语法
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
修改yml文件

执行命令 docker compose config解释配置
语法有问题会报错,没问题就会对yml解释
构建项目,查看容器和宿主机的映射端口,执行命令 docker port prj6-web-1

web端访问端口

expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
修改yml文件

检查语法和解释配置,执行命令 docker compose config
build
指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
• context:上下文路径。
• dockerfile:指定构建镜像的 Dockerfile 文件名。
• args:添加构建参数,这是只能在构建过程中访问的环境变量。
• labels:设置构建镜像的标签。
depends_on
设置依赖关系。
• docker compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
• docker compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中, docker compose up web 还将创建并启动 db 和 redis。
• docker compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
可以指定条件,healthy 需要配置 healthcheck 来完成
services:
web:
build: .
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
redis:
image: redis
db:
image: postgres
health check 样例
version: "3.8"
services:
web:
image: nginx:1.24.0
environment:
TEST: 1
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "bit@123"
volumes:
- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
healthcheck:
test: mysql --user=root --password='bit@123' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
修改yml文件

检查语法和解释配置,执行命令 docker compose config
然后构建项目

刚刚构建时,web容器已经创建了,但是mysql容器没有走到Healthy状态

当mysql走到Healthy状态后,web服务马上就走到了Started状态了
查看运行的容器

可以看到web服务是后启动的。
env_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
修改yml文件

并写好环境变量文件

检查语法和解释配置,执行命令 docker compose config

构建项目,进入容器查看环境变量

docker compose命令
命令官方文档
https://docs.docker.com/reference/cli/docker/compose/
| 命令 | 功能 |
|
docker compose build
|
构建服务
|
|
docker compose config
|
规范的格式来显示服务配置
|
|
docker compose cp
|
在本地系统和服务容器直接拷贝文 件
|
|
docker compose create
|
创建服务的容器
|
|
docker compose down
|
停止所有容器,并删除容器
|
|
docker compose events
|
从服务器获取实时事件
|
|
docker compose exec
|
在容器中执行命令
|
|
docker compose images
|
列出所有容器使用的镜像
|
|
docker compose kill
|
强制停止服务的容器
|
|
docker compose logs
|
显示日志
|
|
docker compose ls
|
显示所有项目
|
|
docker compose pause
|
暂停服务
|
|
docker compose port
|
列出所有的端口映射
|
|
docker compose ps
|
该命令可以列出项目中目前的所有 容器
|
|
docker compose pull
|
拉取服务镜像
|
|
docker compose push
|
推送服务镜像
|
|
docker compose restart
|
重启或者重启某个服务
|
|
docker compose rm
|
删除服务停止的容器
|
|
docker compose run
|
在指定服务容器上执行相关的命令
|
|
docker compose start
|
启动当前停止的某个容器
|
|
docker compose stop
|
停止当前运行的某个容器
|
|
docker compose top
|
显示运行的进程
|
|
docker compose
unpause
|
恢复服务
|
|
docker compose up
|
up
命令会构建,(重新)创建,启 动,链接一个服务
相关的容器。默 认情况下如果容器已经存在,将会 停
止并尝试重新创建他们。并使用 之前挂载的卷。--no-recreate
参数 可以让容器不被停止或者重新创 建,-d
表示后台运行
|
|
docker compose
version
|
查看版本
|
命令格式
对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的 服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服 务都会受到命令影响。 docker-compose 命令的基本的使用格式为
docker compose [OPTIONS] COMMAND [ARGS...]
常见选项
※※※-f, --file 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可 以多次指定
※※※-p, --project-name 指定项目名称,默认将使用所在目录名称作为项目名
执行命令 docker compose -f ./prj9/dockercompose.txt -p prj92 up -d
然后在查看构建的项目,执行命令 docker compose -p prj92 ps

-f选项是指定配置文件。如果没给-f,就会找当前目录下的配置文件
-d是指定构建的项目名称。如果没给-d,就会使用当前目录为项目名称
常见命令
up
该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服 务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。
语法
docker compose up [options] [SERVICE...]
参数
• -d 在后台运行服务容器, 推荐在生产环境下使用该选项
• --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用
• --no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用
1、构建项目,查看创建容器的环境变量
构建项目,执行命令 docker compose up -d
查看创建容器的环境变量,执行命令 docker container inspect prj1-web-1

2、修改yml文件的环境变量

3、然后使用强制重新创建容器,使用--force-recreate
执行命令 docker compose up -d --force-recreate
然后再次查看容器的环境变量

4、再次修改yml文件

5、然后再次构建项目 使用--no-recreate参数
执行命令 docker compose up -d --no-recreate
6、再次查看容器环境变量

环境变量依旧没变,说明构建并未重新读取配置文件创建容器
down
停止所有容器,并删除容器和网络
语法
docker compose down [options] [SERVICE...]
参数
-v, --volumes 删除容器同时删除目录映射
修改yml文件

构建项目,再清理项目

然后再次清理,加上-v参数

run
该命令可以在指定服务容器上执行相关的命令
语法
# 例如:启动一个 ubuntu 服务容器,并执行 ping docker.com 命令
# docker compose run ubuntu ping docker.com
docker compose run [options] SERVICE [COMMAND] [ARGS...]
参数
• -d 后台运行容器
• --name NAME 为容器指定一个名字
• --entrypoint CMD 覆盖默认的容器启动指令
• -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量
• -u, --user="" 指定运行容器的用户名或者 uid
• --rm 运行命令后自动删除容器
• -p, --publish=[] 映射容器端口到本地主机
创建web服务的容器
执行命令 docker compose run -d --name nginx1 web
查看运行的容器

再次创建web2服务的容器,并指定执行一条命令(请求百度)。
执行命令 docker compose run --name nginx2 web curl www.baidu.com

基本操作
1、编辑yml文件,配置服务拓扑和检查关系

2、检查语法和解释配置,执行命令 docker compose config
3、编辑yml文件,配置网络、nginx首页和存储卷和映射端口
version: "3.8"
services:
web:
image: nginx:1.24.0
environment:
TEST: 3
networks:
- mytestnetwork
volumes:
- ./nginxhome:/usr/share/nginx/html
ports:
- 8081:80
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 704756098
networks:
- mytestnetwork
volumes:
- ./mysqllib:/var/lib/mysql
healthcheck:
test: mysql -u root -p704756098 -e "select 1;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis::7
networks:
- mytestnetwork
healthcheck:10
redis:
image: redis:7
networks:
- mytestnetwork
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
networks:
mytestnetwork:
4、检查语法和解释配置,执行命令 docker compose config
5、然后在宿主机上创建nginx绑定卷的目录,并进入,编写nginx主页

5、构建和启动项目
执行命令 docker compose up -d

在web端访问nginx主页

查看创建网络关联的容器

查看mysql绑定卷目录

查看nginx主页绑定卷目录

6、清理项目
执行命令 docker compose down

部署自定义服务
服务拓扑

1、编写数据库脚本,初始化数据库
drop database if exists test;
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8mb4;
use `test`;
CREATE TABLE `users`(
`sno` int(11) DEFAULT NULL,
`sname` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO users (sno,sname) VALUES
(1,'pony'),
(2,'maxhou');
把这份数据库初始化脚本保存为init.sql文件
2、编写java应用
将步骤1的脚本,在本地建好。
在本地编写一个Maven项目,然后测试好能在本地访问。打成jar包

3、编写yml配置文件,也就是服务拓扑编写,进行容器编排
version: "3.8"
services:
web:
image: nginx:1.24.0
environment:
TEST: 3
volumes:
#配置反向代理。nginx会自动加载/etc/nginx/conf.d下的配置文件
- ./nginxconf/:/etc/nginx/conf.d
depends_on:
backend:
condition: service_started
ports:
- 8081:80
backend:
image: openjdk:8
#启动springboot应用
command: java -jar /app/testmymysql-0.0.1-SNAPSHOT.jar
volumes:
#将宿主机上的jar包共享给容器
- ./app/:/app/
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 704756098
volumes:
#mysql数据备份保存
- ./mysql/varlib/:/var/lib/mysql
#mysql启动会默认运行/docker-entrypoint-initdb.d/目录下的脚本文件,将数据库脚本放到宿主机中的绑定卷位置,就能初始化数据库
- ./mysql/initdb/:/docker-entrypoint-initdb.d/
healthcheck:
test: mysql -u root -p704756098 -e 'select 1;'
interval: 10s
timeout: 5s
retries: 10
反向代理的配置文件是./nginxconf/testsql.conf
内容如下
server {
listen 80;//监听80端口
access_log off;//关闭访问日志
location / {//location /匹配任何路径
proxy_pass http://backend:8080/user/; //代理到http://backend:8080/user/路径
}
}
凡是打到 nginx 80 端口的请求,全部静默地转给后端
backend:8080,并在前面统一加上/user/路径前缀
4、检查服务是否正常
构建启动项目,进行访问

5、项目清理
执行命令 docker compose down
部署WordPress
服务拓扑

1、编写配置文件
version: "3.8"
services:
wordpress:
image: wordpress
restart: always
depends_on:
db:
condition: service_healthy
ports:
- 8081:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: mywordpressuser
WORDPRESS_DB_PASSWORD: mywordpresspass
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wordpress:/var/www/html
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
MYSQL_USER: mywordpressuser
MYSQL_PASSWORD: mywordpresspass
volumes:
- ./mysqlvarlib:/var/lib/mysql
healthcheck:
test: mysql -u root -proot -e "select 1;"
interval: 10s
timeout: 5s
retries: 10
2、执行命令检查 vim docker-compose.yml
3、运行站点
执行命令 docker compose up -d
然后在web端访问8081端口访问主页

点击简体中文进行安装。

进行登录

登录成功

4、编写文章,测试是否正常
5、项目清理
执行命令 docker compose down
常见问题
1. up、run 和 start 之间有什么区别
通常,你想要 docker compose up. 用于 up 启动或重新启动 docker-compose.yml. 在默认的“附加”模式下,会看到来自所有容器的所有日志。在“分离”模式 ( -d) 中,启 动容器后 Compose 退出,但容器继续在后台运行。
该 docker compose run 命令用于运行“一次性”或“临时”任务。它需要您要运行的服 务名称,并且只为正在运行的服务所依赖的服务启动容器。用于 run 运行测试或执行 管理任务,例如从数据卷容器中删除或添加数据。该 run 命令的作用类似于 docker run -ti 它打开容器的交互式终端并返回与容器中进程的退出状态匹配的退出状态。 docker compose start 命令仅对重新启动先前创建但已停止的容器有用。它从不创 建新容器。
2. 如何在同一主机上运行 Compose 文件的多个副本
Compose 使用项目名称为项目的所有容器和其他资源创建唯一标识符。要运行项目的 多个副本,请使用-p 命令行选项 或 COMPOSE_PROJECT_NAME 环境变量设置自定 义项目名称。
3. 可以控制服务启动顺序吗?
可以控制启动顺序,通过依赖指定,并且可以配合 healthcheck 等健康检查成功以后 再启动。
更多推荐
所有评论(0)