
Uncloud Compose 扩展完全指南x-ports、x-caddy、x-pre_deploy 等专有特性的实战与源码解析【免费下载链接】uncloudA lightweight tool for deploying and managing containerised applications across a network of Docker hosts. Bridging the gap between Docker and Kubernetes ✨项目地址: https://gitcode.com/GitHub_Trending/unc/uncloudUncloud 在标准 Compose 规范之上提供了一组以x-开头的专有扩展让你可以直接在 Compose 文件中声明集群上下文、端口发布、自定义反向代理、机器放置约束、部署前钩子与命令行密钥等 Uncloud 独有能力。本文以官方扩展参考文档为主体结合仓库中pkg/client/compose与pkg/api的实现源码逐一讲解每个扩展的语法、默认值、底层行为与常见误区读完即可在自己的compose.yaml中熟练使用全部六类扩展。为什么需要 Uncloud 专有扩展标准 Compose 规范面向单机docker compose场景设计而 Uncloud 是跨多台 Docker 主机的轻量容器编排工具服务需要决定部署到哪台机器如何通过集群内 Caddy 反向代理暴露如何滚动更新前执行一次性任务。这些能力超出了 Compose 规范的定义范围因此 Uncloud 在保留标准特性的同时通过x-前缀扩展补齐了集群场景的缺口。这些扩展与标准特性的关系可以对照 Compose 支持矩阵 理解例如标准ports仅支持mode: host受限于端口映射能力HTTP/HTTPS 发布需要改用x-ports标准deploy.placement不支持需要改用x-machinesdepends_on的service_completed_successfully条件不支持需要改用x-pre_deploy。支持矩阵中对每个扩展的定位如下扩展键定位x-context集群上下文覆盖x-caddy自定义 Caddy 配置x-machines机器放置约束x-ports服务端口发布x-pre_deploy部署前钩子命令此外还有一类作用于顶层secrets的x-command扩展用于通过本地命令解析密钥值。下面逐一展开。x-context把 Compose 文件绑定到指定集群x-context用于为所有使用该 Compose 文件的命令如deploy、build、logs固定集群上下文。当同时管理多个集群时这能确保 Compose 文件永远部署到正确的集群无需每次手动执行uc ctx切换或传递--context参数。它是顶层键不是服务级属性x-context: prod services: web: image: nginx优先级规则--context和--connect命令行标志优先于x-context如果两者都未指定则使用 Uncloud 配置--uncloud-config指向的配置文件中的当前上下文。从源码看context.go 定义了ContextExtensionKey x-context并通过ClusterContext函数从项目顶层扩展中提取字符串值取不到时返回空串。这意味着x-context必须出现在 Compose 文件的顶层写在某个services节点内部不会被识别。:::warning 共享文件时的注意事项 如果多人共享同一个 Compose 文件请确保所有人 Uncloud 配置中的目标集群都使用相同的上下文名否则同一份文件在不同人手中可能指向不同集群。 :::x-ports发布 HTTP/HTTPS 与 TCP/UDP 端口x-ports用于把服务的端口暴露到集群外部HTTP/HTTPS 端口通过 Caddy 反向代理发布TCP/UDP 端口则以 host 模式直接绑定到主机网卡services: web: image: nginx x-ports: - 80/https - example.com:80/https - 8080:80/tcphost两种端口模式的语法Ingress 模式HTTP/HTTPS经由 Caddy格式为[hostname:]container_port[/protocol]hostname可选访问服务的域名省略时若集群保留了域名则使用service-name.cluster-domain。container_port容器内监听流量的端口。protocol可选http或https默认https。Host 模式TCP/UDP直绑主机格式为[host_ip|host_prefix:]host_port:container_port[/protocol]hosthost_ip/host_prefix可选绑定的主机 IP也支持 CIDR 前缀将绑定该前缀包含的所有主机 IP省略则绑定所有网卡。host_port主机上绑定的端口。container_port容器内监听端口。protocol可选tcp或udp默认tcp。常用取值示例端口值说明8000/http通过 Caddy 以 HTTP 发布 8000 端口主机名为service-name.cluster-domainapp.example.com:8080/https通过 Caddy 以 HTTPS 发布 8080 端口主机名为app.example.com127.0.0.1:5432:5432host仅回环接口上把 TCP 5432 绑到主机 543253:5353/udphost所有网卡上把 UDP 5353 绑到主机 53192.168.76.0/24:5432:5432/tcphost将 TCP 5432 绑定到192.168.76.0/24内每个主机 IP 的 5432 端口同一端口可以用多个主机名发布多域名指向同一服务不同端口也可以绑定不同主机名详见 Publishing services。底层解析与校验x-ports的解析入口是 port.go 中的transformServicesPortsExtension它会同时检查标准ports与x-ports若两者同时出现则直接报错cannot specify both ports and x-ports directives, use only one。随后transformPortsExtension逐条调用api.ParsePortSpec完成字符串解析。端口字符串的完整校验逻辑位于 pkg/api/port.go 的PortSpec.Validate值得注意的规则包括Ingress 模式下不允许出现 host IP / 前缀hostname 仅对http/https协议有效且必须包含至少一个点validateHostname要求是合法域名。Host 模式下必须指定 published port只支持tcp/udp协议不允许 hostnamehost IP 与 host 前缀互斥。解析器对 IPv6 地址要求用方括号包裹如[2001:db8::1]:5432:5432/tcphost带 CIDR 的前缀写法如[2001:db8::]/64也受支持。:::warning 安全提示 不要发布仅集群内部使用的服务如数据库。集群内服务可以凭 DNS 名service-name或service-name.internal直接互访无需发布端口。 :::x-caddy自定义 Caddy 反向代理配置当x-ports的自动生成配置无法满足路由需求时可以用x-caddy为服务提供自定义 Caddyfile 配置services: web: image: nginx x-caddy: | example.com { reverse_proxy {{upstreams 80}} }x-caddy支持两种写法直接内联 Caddyfile 内容如上或指定一个 Caddyfile 文件路径x-caddy: ./Caddyfile路径相对于 Compose 文件所在目录。源码 caddy.go 中的Caddy.DecodeMapstructure同时接受字符串与{config: ...}对象两种形态transformServicesCaddyExtension 会判断配置是单行路径还是多行内联内容若是路径则读取文件内容替换之。模板能力x-caddy配置会作为 Go 模板渲染因此可以插入动态值模板说明{{upstreams [service-name] [port]}}当前或指定服务、指定端口的健康容器 IP 列表空格分隔{{.Name}}该配置所属的服务名{{.Upstreams}}所有服务名到其健康容器 IP 的映射模板在服务容器启动/停止或健康状态变化时自动重新渲染并触发 Caddy 热加载。例如reverse_proxy {{upstreams 8000}}会被渲染为reverse_proxy 10.210.1.3:8000 10.210.2.5:8000借助handle_path还能实现一域名多服务/api/*转发到api服务、其余转发到web服务等高级场景完整的模板示例与常见用例参见 Publishing services。与 x-ports 的互斥规则从 service.go 的validateServicesExtensions可以看出一个重要约束同一服务不能同时使用x-caddy与x-ports中的 ingresshttp/https端口因为 Caddy 配置会由 ingress 端口自动生成二者语义冲突但 host 模式的tcp/udp端口可以放心与x-caddy搭配。此外不同服务的自定义 Caddy 配置不得冲突各服务必须使用唯一主机名Uncloud 会通过caddy adapt检测冲突或非法配置并跳过同时把错误信息以注释形式写进生成的 Caddyfile——可用uc caddy config查看完整生成结果进行调试。x-machines约束服务的部署机器x-machines用于把服务限定在指定的机器集合内运行。当服务配置了多个副本时Uncloud 会自动把副本分散到这些机器上services: web: image: nginx x-machines: - machine-1 - machine-2 # 单台机器的短语法 # x-machines: machine-1它替代了标准deploy.placementUncloud 明确不支持 placement并在校验时提示改用x-machines见 service.go。从源码看machines.go 的MachinesSource.DecodeMapstructure异常宽容地支持多种写法单个字符串x-machines: machine-1逗号分隔字符串x-machines: machine-1,machine-2字符串数组x-machines: [machine-1, machine-2]YAML 解析产生的接口数组也会逐项校验类型所有写法都会经过validateMachineNames去空格并拒绝空值。最终在 service.go 的 ServiceSpecFromCompose 中被映射为spec.Placement.Machines交给调度器做机器级放置决策。x-pre_deploy部署前的单次命令钩子x-pre_deploy用于在滚动发布服务容器之前先在一个独立容器中执行一次性命令并等待其成功结束。典型场景包括数据库迁移、静态资源上传、缓存失效等需要在每次部署前完成的准备工作services: web: build: . x-pre_deploy: command: python manage.py migrate environment: LOG_LEVEL: DEBUG timeout: 10m钩子容器复用服务的镜像并继承其环境变量、卷、放置约束与计算资源命令失败或超时默认 5 分钟则部署立即终止。属性一览属性类型默认值说明commandstring / list必填钩子容器中运行的命令格式与服务级command一致environmentmap / list of KEYVALUE-额外环境变量覆盖或扩展服务的environmentprivilegedbool服务原值覆盖服务的特权模式timeoutduration5m命令完成前的最长等待时间超时则杀掉如1m30s、30m、1huserstring服务原值以指定用户运行user、UID、user:group或UID:GID钩子容器还会被自动注入环境变量UNCLOUD_HOOK_PRE_DEPLOYtrue方便在共享的入口脚本中区分钩子执行与常规服务容器执行。源码层面predeploy.go 定义了PreDeployHook结构体Validate强制要求command非空在 service.go 中钩子被转换为api.PreDeployHook并挂到服务规格上timeout会被解析为time.DurationCompose 的 duration 类型支持5m、1h30m等人类可读写法。执行流程与失败处理uc deploy的执行顺序是构建并推送新镜像若从源码构建→ 运行钩子容器并等待 → 正常滚动更新。钩子运行在服务将要部署的某台机器上能像服务容器一样访问其他服务、连接数据库、读写共享卷但除共享卷外的文件系统变更不会保留。完整流程与示意图见 Pre-deploy hooks。失败处理要点非零退出码部署立即停止不创建/替换任何服务容器uc deploy打印失败钩子容器最近 10 行日志可用环境变量UNCLOUD_FAILED_CONTAINER_LOGS_TAIL调整行数或设为all打印全部容器保留供uc logs、uc inspect、uc ps排查。超时默认 5 分钟超时后杀掉容器并使部署失败耗时任务大型迁移、数据上传应显式调大timeout。幂等性钩子应在钩子成功之后、部署因别的原因失败并重试时也能安全重复执行多数迁移工具天然满足。注意command会替换镜像的CMD但ENTRYPOINT仍然生效——如果镜像定义了 entrypoint钩子命令会作为其参数传入如需改变可用服务级entrypoint对钩子容器与常规容器同时生效。复杂多任务可包在sh -c cmd1 cmd2中或使用镜像内置脚本脚本需随镜像分发且失败时以非零码退出。secrets.*.x-command用本地命令解析密钥顶层secrets段中的x-command扩展允许通过在本地运行一条命令、取其标准输出的方式解析密钥值。先在secrets中定义密钥再以secret://name形式在服务的environment中引用services: api: image: myapp environment: DB_PASSWORD: secret://db_password secrets: db_password: # 通过本地执行该命令从 1Password 读取密钥值。 x-command: op read op://prod/myapp/db_password从源码看secret.go 定义了SecretRefPrefix secret://与SecretCommandExtensionKey x-command。x-command本质上是内置exec密钥驱动的短语法等价于driver: exec加driver_opts.commandvalidateSecrets会拒绝同时声明file/environment的混合写法也只接受exec这一个驱动。密钥解析的底层行为secretValue / runSecretCommand命令在工作目录Compose 文件所在目录下、以解析后的项目环境变量直接执行不经过 shell需要管道等 shell 特性时请显式写成sh -c ...。命令的 stdin 与 stderr 连接到当前终端因此支持交互式认证提示如 1Password 的解锁stdout 作为密钥值返回。输出末尾的单个换行\n或\r\n会被剥离其余空白原样保留。命令有1 分钟超时常量secretCommandTimeout超时即终止并报错。同一密钥即使被多个服务引用也只会解析一次未被引用的密钥不会被解析。除x-command外密钥也支持来自环境变量或文件secrets相关细节见 Secrets。注意 Uncloud 对标准secrets的支持有限制仅支持在environment中引用不支持文件挂载见支持矩阵。扩展组合与校验规则速查在同一个 Compose 文件中组合多个扩展时请牢记以下由源码确认的规则ports与x-ports互斥同一服务只能使用其中一个port.go。x-caddy与 ingress 端口互斥x-caddy与x-ports中的 http/https 端口不能同时出现host 模式的 tcp/udp 端口不冲突service.go。x-machines替代 placement标准deploy.placement不支持使用x-machines。x-context是顶层键写在服务节点内不会被识别命令行标志优先于它。x-pre_deploy的command必填缺失会在校验阶段直接报错。所有x-扩展键在解析后会转换为 Uncloud 内部规格ServiceSpecFromCompose因此它们同样会被部署调度、Caddy 配置生成与滚动更新等完整链路所使用。掌握这六类扩展你就能在单一 Compose 文件中完整描述一个 Uncloud 服务从部署到哪到如何暴露更新前做什么的全部集群语义让 Compose 文件成为真正可移植、可复现的部署清单。【免费下载链接】uncloudA lightweight tool for deploying and managing containerised applications across a network of Docker hosts. Bridging the gap between Docker and Kubernetes ✨项目地址: https://gitcode.com/GitHub_Trending/unc/uncloud创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考