1 个稳定版本
1.0.0 | 2023年10月2日 |
---|
#1401 在 命令行工具
63KB
1.5K SLoC
Wheelsticks:Docker Compose 的零停机部署
Wheelsticks 是 Docker Compose 的一个扩展,有助于实现服务的零停机更新。
动机
Docker Compose 提供了简单的声明式编排容器化应用程序。
当使用 docker compose up
更新 Docker Compose 中的服务容器时,旧容器会在新容器启动之前被停止(stop-first
情况)
Old container Stop
┄┄┄┄───────────────────────┤
Start New container
├────────────────────────┄┄┄┄
这会导致服务中断,因为在某个时刻两个容器都不可用。
想象一下,如果我们能使得容器的生命周期重叠(start-first
情况)
Old container Stop
┄┄┄┄───────────────────────────────────────┤
Start New container
├────────────────────────────────────────┄┄┄┄
如果反向代理无缝地将流量从旧容器切换到新容器,那么就可以实现零停机部署。
实际上,Compose 规范定义了区分这两种情况的可选选项:stop-first
(默认)和start-first
。但是,对这个规范部分的支持是可选的,普通的 Docker Compose 总是应用stop-first
,而不考虑您的 Compose 文件中有什么。
然而,Wheelsticks 支持这两种选项。只需将 wheelsticks deploy
替换为 docker compose up
。无需更改任何其他 Docker 或 Docker Compose 工作流程。
安装
先决条件
- Docker 或 Podman
- Docker Compose
安装
请参阅 发行版 以获取预编译的可执行文件。
或者,使用 cargo install wheelsticks
从源代码构建。
Docker CLI 插件
可选地,可以将 Wheelsticks 配置为 Docker CLI 插件。这样,可以使用 docker deploy
代替 wheelsticks deploy
,这可能是某些人的首选。示例 设置
mkdir --parents ~/.docker/cli-plugins
ln --symbolic "$(which wheelsticks)" ~/.docker/cli-plugins/docker-deploy
使用
快速入门
对于在更新期间容器生命周期应重叠的服务,按照以下方式配置它们的更新顺序
# compose.yaml
services:
greet:
deploy:
update_config:
order: start-first # Most important line.
# …
请参考example/compose.yaml
以查看示例。它定义了一个名为greet
的服务,通过reverse-proxy
在localhost:8080上提供。
localhost:8080 ╭───────────────╮ ╭───────────────╮
──────────────────────┤ reverse-proxy ├────────┤ greet │
:80 │ (stop-first) │ :80 │ (start-first) │
╰───────────────╯ ╰───────────────╯
这种设计使得服务即使在更新期间也保持可用。您可以按照以下方式操作:
cd example
wheelsticks deploy --wait
curl localhost:8080 # … prints "Hi from A"
export GREET_VERSION=B
wheelsticks deploy --wait
curl localhost:8080 # … prints "Hi from B"
docker compose down
要查看上述部署的实际效果,请使用独立的shell会话运行以下命令:
while true; do curl --fail --max-time 0.2 localhost:8080; sleep 0.01s; done
服务更新的条件
默认情况下,只有当服务的服务配置哈希更改时,才会更新服务。此哈希是对Compose文件中除build
、deploy.replicas
、pull_policy
和scale
之外的所有服务字段进行计算的(请参阅源代码)。
请注意,服务配置哈希不依赖于容器镜像内容,而只是依赖于image
字段。因此,重新使用像latest
这样的标签不会导致更新。
使用--force-recreate
始终更新服务,无论配置哈希是否更改。
命令 | 效果 |
---|---|
wheelsticks deploy |
更新所有配置哈希更改的服务 |
wheelsticks deploy--dry-运行 |
不进行任何更新,但显示将发生哪些更改 |
wheelsticks deploy x |
如果服务的配置哈希更改,则更新服务x |
wheelsticks deploy--force-recreate |
始终更新所有服务 |
wheelsticks deploy--force-recreate x |
始终更新服务x |
docker compose config--hash'*' |
显示Compose文件的服务的配置哈希 |
服务更新过程
服务按字母顺序(更精确地说,按Unicode代码点字典顺序)更新。
对于每个服务,容器先停止后启动(stop-first
,默认),或者先启动后停止,然后对副本重复此操作。以下是对具有3个副本的服务的过程的视觉表示。
stop-first
情况
1. Stop old
┄┄┄┄───────────┤
2. Start new
├────────────────────────────────────────────┄┄┄┄
3. Stop old
┄┄┄┄───────────────────────────┤
4. Start new
├────────────────────────────┄┄┄┄
5. Stop old
┄┄┄┄───────────────────────────────────────────┤
6. Start new
├────────────┄┄┄┄
start-first
情况
1. Start new
├────────────────────────────────────────────────────┄┄┄┄
2. Stop old
┄┄┄┄───────────────────┤
3. Start new
├────────────────────────────────────┄┄┄┄
4. Stop old
┄┄┄┄───────────────────────────────────┤
5. Start new
├────────────────────┄┄┄┄
6. Stop old
┄┄┄┄───────────────────────────────────────────────────┤
Podman支持
通过传递--container-engine podman
来使用Podman而不是Docker。
由于目前缺少一些必需的功能,如服务配置哈希的计算(docker compose config --hash '*'
),因此不支持Podman Compose。
替代方案
适用于单节点环境的其他轻量级选项
命令行参数参考
wheelsticks-h
Zero-downtime deployments for Docker Compose
Usage: wheelsticks [OPTIONS] <COMMAND>
Commands:
deploy Create or update services
help Print this message or the help of the given subcommand(s)
Options:
--config <CONFIG> Location of client config files
-c, --context <CONTEXT> Name of the context to use to connect to the
daemon (overrides DOCKER_HOST env var and default
context set with "docker context use")
-D, --debug Enable debug mode [aliases: verbose]
-H, --host <HOST> Daemon socket to connect to
-l, --log-level <LOG_LEVEL> Set the logging level [possible values: debug,
info, warn, error, fatal]
--tls Use TLS; implied by --tlsverify
--tlscacert <TLSCACERT> Trust certs signed only by this CA
--tlscert <TLSCERT> Path to TLS certificate file
--tlskey <TLSKEY> Path to TLS key file
--tlsverify Use TLS and verify the remote
-h, --help Print help
-V, --version Print version
wheelsticks deploy-h
Create or update services
Usage: wheelsticks deploy [OPTIONS] [SERVICE_NAMES]...
Arguments:
[SERVICE_NAMES]...
Options:
--ansi <ANSI>
Control when to print ANSI control characters [possible values: never,
always, auto]
--compatibility
Run compose in backward compatibility mode
--dry-run
Execute command in dry run mode
--env-file <ENV_FILE>
Specify an alternate environment file
-f, --file <FILE>
Compose configuration files
--parallel <PARALLEL>
Control max parallelism, -1 for unlimited
--profile <PROFILE>
Specify a profile to enable
--progress <PROGRESS>
Set type of progress output [possible values: auto, tty, plain, quiet]
--project-directory <PROJECT_DIRECTORY>
Specify an alternate working directory (default: the path of the,
first specified, Compose file)
-p, --project-name <PROJECT_NAME>
Project name
--build
Build images before starting containers
-d, --detach
This has no effect as detached mode is always on; for migration only
--force-recreate
Recreate containers even if their configuration hasn't changed
--no-build
Don't build an image, even if it's missing
--no-start
Don't start the services after creating them
--pull <PULL>
Pull image before running [possible values: always, missing, never]
--quiet-pull
Pull without printing progress information
--remove-orphans
Remove containers for services not defined in the Compose file
-V, --renew-anon-volumes
Recreate anonymous volumes instead of retrieving data from the
previous containers
-t, --timeout <TIMEOUT>
Use this timeout in seconds for container shutdown when containers are
already running
--wait
Wait for services to be running|healthy
--wait-timeout <WAIT_TIMEOUT>
timeout in seconds waiting for application to be running|healthy
--compose-engine <COMPOSE_ENGINE>
Compose engine to use; Podman Compose is not supported due to missing
features [default: "docker compose"] [possible values: docker-compose,
"docker compose"]
--container-engine <CONTAINER_ENGINE>
Container engine to use [default: docker] [possible values: docker,
podman]
-h, --help
Print help (see more with '--help')
依赖
~3–13MB
~158K SLoC