首页
/ Dokku Docker Local Scheduler 深度指南:默认调度器原理、并行部署与资源限制配置

Dokku Docker Local Scheduler 深度指南:默认调度器原理、并行部署与资源限制配置

2026-09-09 21:16:19作者:牧宁李

本文以 Dokku 的 scheduler-docker-local 插件为核心,系统讲解 Dokku 在单机 Docker 环境下管理应用生命周期的默认调度器:从调度器切换、amd64/arm64 跨架构部署、init 进程注入、进程级并行调度,到 scheduler-docker-local:report 报告命令与资源限制属性的完整用法。读完本文,你将能够熟练配置单机调度行为、诊断部署并行度瓶颈,并在需要时通过 app.json 精细控制每个进程类型的启动并发度。

调度器概览:Dokku 的默认单机调度器

scheduler-docker-local 是 Dokku 内置的调度器插件(位于 plugins/scheduler-docker-local),负责在单台服务器上使用 Docker 直接管理应用容器的完整生命周期。与所有调度器一样,它以应用为单位进行设置——Dokku 通过 scheduler:set 命令为每个应用指定使用哪个调度器。

该插件是 Dokku 的默认调度器。若要显式将某个应用切回 docker-local(例如应用此前被配置为其他调度器,如 scheduler-k3s),可执行:

dokku scheduler:set node-js-app selected docker-local

由于 docker-local 本就是默认值,selected 属性置空同样是恢复默认调度器的合法方式:

dokku scheduler:set node-js-app selected

也就是说,dokku scheduler:set <app> selected(不带值)即可把应用调度器重置回 docker-local。

该插件包含两个核心子命令(自 0.12.12 起新增):

scheduler-docker-local:report [<app>] [<flag>]              # Displays a scheduler-docker-local report for one or more apps
scheduler-docker-local:set [<app>|--global] <key> (<value>) # Set or clear a scheduler-docker-local property for an app or globally

从源码看,set 子命令对属性键做了白名单校验:只接受 init-processparallel-schedule-count 两个键,传入其他键会直接报错;当带值写入时通过 fn-plugin-property-write 落盘,无值(空值)时则执行 fn-plugin-property-delete 完成清除(见 plugins/scheduler-docker-local/subcommands/set)。

在 arm64 主机上部署 amd64 镜像

自 0.33.0 起支持。

目前许多 buildpack 类构建器只产出 amd64 架构的镜像。scheduler-docker-local 会在每次部署时自动检测镜像架构:如果镜像架构为 amd64 而当前主机不是 amd64(即 arm64 部署目标),则自动为容器追加 --platform=linux/amd64 参数,使其能够借助 Docker 的模拟层在 arm64 主机上运行。

对应实现在容器启动逻辑 plugins/scheduler-docker-local/bin/scheduler-deploy-process-container 中:

local DOKKU_IMAGE_ARCHITECTURE="$("$DOCKER_BIN" image inspect --format '{{.Architecture}}' "$IMAGE")"
if [[ "$DOKKU_IMAGE_ARCHITECTURE" == "amd64" ]] && [[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]]; then
  dokku_log_warn "Detected linux/amd64 image, forcing --platform=linux/amd64"
  DOCKER_ARGS+=" --platform=linux/amd64"
fi

即:通过 docker image inspect 读取镜像的 Architecture,与主机架构(dpkg --print-architecture)比对后自动注入平台参数,全程无需人工干预。需要注意的是,该能力依赖 Docker 在目标主机上的跨架构运行支持(如 binfmt/qemu),且模拟运行在性能上会有一定开销。

控制 init 进程注入(init-process 属性)

默认情况下,scheduler-docker-local 在启动应用容器时通过 Docker 的 --init 标志注入一个 init 进程(用于回收僵尸进程)。但对于某些应用——例如镜像内部本身已使用 S6 作为 init 的容器——额外的 init 进程注入可能反而导致进程启动异常。

此时可为应用显式关闭 init 注入:

dokku scheduler-docker-local:set node-js-app init-process false

如需重新启用,将 init-process 置空即可(空值会删除该属性,恢复默认行为):

dokku scheduler-docker-local:set node-js-app init-process

默认值也可以通过 --global 标志在全局范围配置,应用级取值优先于全局值

# 全局关闭 init 进程注入
dokku scheduler-docker-local:set --global init-process false

# 清除全局值,恢复默认(true
dokku scheduler-docker-local:set --global init-process

一个重要的自动特判:当既没有应用级值、也没有全局值时,凡是带有 org.opencontainers.image.vendor=linuxserver.io 标签的镜像,init 注入会被强制关闭,无需任何手动配置。这是因为 linuxserver.io 的镜像统一使用 s6-overlay 作为 init。该逻辑在 plugins/scheduler-docker-local/bin/scheduler-deploy-process 中体现:

INJECT_INIT_FLAG="$(fn-scheduler-docker-local-init-process "$APP")"
if [[ -z "$INJECT_INIT_FLAG" ]]; then
  INJECT_INIT_FLAG="$(fn-plugin-property-get-default "scheduler-docker-local" "--global" "init-process" "")"
fi
if [[ -z "$INJECT_INIT_FLAG" ]]; then
  image_vendor="$("$DOCKER_BIN" image inspect --format '{{ index .Config.Labels "org.opencontainers.image.vendor" }}' "$IMAGE")"
  if [[ "$image_vendor" == "linuxserver.io" ]]; then
    INJECT_INIT_FLAG="false"
  else
    INJECT_INIT_FLAG="true"
  fi
fi

最终,--init 参数在容器创建时按 INJECT_INIT_FLAG 决定是否追加(见 plugins/scheduler-docker-local/bin/scheduler-deploy-process-container)。

并行部署多个进程类型(parallel-schedule-count 属性)

自 0.25.5 起支持。

默认情况下,Dokku 按顺序逐个部署应用的进程类型,且 web 进程总是最先被部署。通过设置 parallel-schedule-count 属性(默认值为 1)可以提升并行度——该值表示一次最多可并行调度多少个进程类型(web 进程除外)。

# 将并行度从每次 1 个进程类型提升到 4 个进程类型
dokku scheduler-docker-local:set node-js-app parallel-schedule-count 4

恢复默认(逐个部署):

dokku scheduler-docker-local:set node-js-app parallel-schedule-count

同样支持全局配置,应用级优先于全局:

dokku scheduler-docker-local:set --global parallel-schedule-count 4
dokku scheduler-docker-local:set --global parallel-schedule-count

并行调度的失败语义

若并行度提高后某个进程类型调度失败,则:

  • 已在执行中的进程类型会继续处理完毕;
  • 尚未开始调度的进程类型会被跳过;
  • 部署最终以失败收尾。

另外,容器调度的输出按接收顺序显示,因此当存在 stderr 输出时,展示顺序可能与实际调度顺序不一致,属正常现象。

性能注意事项

提高 parallel-schedule-count 会显著增加主机 CPU 占用,因为多个应用容器及其进程会同时启动。不建议把该值设置得高于主机的 CPU 核数,请根据服务器实际负载谨慎取值,以免压垮宿主机。

从实现层面看,scheduler-deploy 触发器把除 web 之外的所有进程类型写入临时文件,随后用 GNU parallel 工具以 --jobs 指定并行度执行(--halt soon,fail=1 表示任一失败即尽快终止);web 进程则始终被单独、首先处理(见 plugins/scheduler-docker-local/scheduler-deploy)。

进程内部的并行度提升(app.json max_parallel)

自 0.26.0 起支持。

parallel-schedule-count 控制的是不同进程类型之间的并行度;而默认情况下,同一个进程类型内部的多个实例仍然是逐个部署的。若要提升某进程类型内部实例的启动并行度,可在应用的 app.json 中为对应进程类型设置 formation 键下的 max_parallel

{
  "formation": {
    "web": {
      "max_parallel": 1
    },
    "worker": {
      "max_parallel": 4
    }
  }
}
  • 省略或删除某个进程类型的 max_parallel 条目,该进程类型将恢复为一次启动 1 个实例;
  • 该机制可以与 parallel-schedule-count 组合使用,进一步加速部署;
  • 与上文相同的性能提醒同样适用:max_parallel 越大,容器启动期间宿主机 CPU 占用越高,不建议超过 CPU 核数。

源码侧,max_parallelplugins/app-json/appjson.goformation 结构体定义的字段(MaxParallel *int),部署时通过 app-json-process-deploy-parallelism 触发器读取并传递给容器部署流程(见 plugins/scheduler-docker-local/bin/scheduler-deploy-process)。

关于 app.json 的存放位置与自定义路径,可参考 deployment-tasks 文档

查看调度器配置报告(scheduler-docker-local:report)

使用 scheduler-docker-local:report 命令可以查看应用当前的调度器配置报告:

dokku scheduler-docker-local:report

输出示例:

=====> node-js-app scheduler-docker-local information
       Scheduler docker local computed init process:          true
       Scheduler docker local computed parallel schedule count:1
       Scheduler docker local global init process:            true
       Scheduler docker local global parallel schedule count: 1
       Scheduler docker local init process:
       Scheduler docker local parallel schedule count:

也支持针对单个应用查看:

dokku scheduler-docker-local:report node-js-app

还可以通过 flag 只输出某一项的具体值,便于脚本化取值:

dokku scheduler-docker-local:report node-js-app --scheduler-docker-local-computed-init-process

使用 --global 时只报告全局键:

dokku scheduler-docker-local:report --global

全部可用的报告键

含义
--scheduler-docker-local-init-process 应用级 init-process 原始值(未设置时为空)
--scheduler-docker-local-computed-init-process 生效的 init-process 值:应用级优先,其次全局值,最后默认 true
--scheduler-docker-local-global-init-process 全局 init-process 值(默认 true
--scheduler-docker-local-parallel-schedule-count 应用级 parallel-schedule-count 原始值(未设置时为空)
--scheduler-docker-local-computed-parallel-schedule-count 生效的并行度:应用级优先,其次全局值,最后默认 1
--scheduler-docker-local-global-parallel-schedule-count 全局并行度值(默认 1

报告还支持 JSON 输出,便于外部工具区分"应用显式设置的值"与"回退到默认值":

dokku scheduler-docker-local:report node-js-app --format json

报告功能的实现位于 plugins/scheduler-docker-local/report.goReportSingleApp 为不同作用域(--global 与普通应用)注册不同的报告 flag 集合,而 reportComputedInitProcess 等计算函数严格遵循"应用级 → 全局级 → 默认值"的三级回退逻辑(如 reportComputedInitProcess 在两层取值均为空时返回 "true")。Shell 侧对应的取值函数(fn-scheduler-docker-local-*)定义于 plugins/scheduler-docker-local/internal-functions,两者逻辑保持一致。

调度器接口与能力范围

scheduler-docker-local 通过 plugn 触发器机制与 Dokku 核心集成,在单机 Docker 上实现了以下功能:

  • apps:clone
  • apps:destroy
  • apps:rename
  • deploy
  • enter
  • logs
  • ps:inspect
  • ps:stop
  • run

对应到插件目录下的触发器脚本,包括 scheduler-deployscheduler-enterscheduler-inspectscheduler-logsscheduler-runscheduler-stopscheduler-app-statusscheduler-register-retiredscheduler-retirescheduler-is-deployed 等,构成了完整的容器生命周期管理链。

日志支持

logs 命令的应用日志直接通过 docker CLI 从运行中的容器获取。由于容器被销毁后日志即丢失,如需跨部署持久化日志,建议使用 Dokku 的 vector 日志集成,将日志发送到其他服务或第三方日志平台。

支持的资源管理属性

docker-local 调度器支持少量资源 limits(限制)与 reservations(预留)属性,通过 Dokku 的资源管理能力作用于 Docker 运行参数:

资源限制(Resource Limits)

属性 Docker 选项 说明
cpu --cpus 进程可访问的 CPU 数量(核数)
memory --memory 内存限制,须带后缀:b(字节)、k(千字节)、m(兆字节)、g(吉字节),默认单位为 m
memory-swap --memory-swap 内存+交换区限制,后缀规则同上
nvidia-gpus --gpus 进程可访问的 NVIDIA GPU 数量

资源预留(Resource Reservations)

属性 Docker 选项 说明
memory --memory-reservation 内存软性预留,后缀规则同上,默认单位为 m

上述属性均映射到 Docker Runtime Options 文档中对应的资源约束语义,实际生效参数由 Docker 守护进程执行。

属性一览(Settable properties)

scheduler-docker-local 支持设置的全部属性汇总如下:

属性 作用域 默认值 报告 flag 描述
init-process 应用 + 全局 true --scheduler-docker-local-init-process--scheduler-docker-local-global-init-process--scheduler-docker-local-computed-init-process true 时以 Docker 的 --init 标志运行容器(回收僵尸进程);linuxserver.io 镜像自动豁免
parallel-schedule-count 应用 + 全局 1 --scheduler-docker-local-parallel-schedule-count--scheduler-docker-local-global-parallel-schedule-count--scheduler-docker-local-computed-parallel-schedule-count 一次部署中并行调度的最大容器数(web 进程除外)

两条属性均支持"应用级优先、全局级兜底、内置默认值最后兜底"的三级取值链,且都能通过置空值的方式清除恢复默认,配合 --format json 报告可以清晰审计每个应用实际生效的调度配置。对于大多数单机部署场景,保持默认值即可;只有在跨架构部署、自定义 init 或追求更快的大规模并发启动时,才需要调整上述配置。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
396
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
527