Terraform创建Docker Swarm服务未部署至Worker节点求助
我之前碰到过类似的Swarm调度异常问题,咱们一步步来拆解和解决:
首先看你提供的Terraform代码,最直观的问题是没有显式配置服务的副本模式与数量(虽然你提到设置了2个副本,但代码里没体现)。先把这个补上,因为默认情况下Terraform的docker_service可能不会自动应用你预期的副本数,甚至会影响Swarm的调度逻辑:
在docker_service.jenkins_service资源里添加mode块:
resource "docker_service" "jenkins_service" { name = var.project_name # 新增:明确指定副本模式与数量 mode { replicated { replicas = 2 } } task_spec { # 原有的container_spec、networks内容... } # 原有的endpoint_spec内容... }
接下来,核心问题大概率出在**/var/run/docker.sock的bind挂载**上:手动创建服务时Swarm会正常调度,但Terraform的Docker Provider在处理这种宿主路径挂载时,可能隐式触发了Swarm调度器的"就近原则"——因为请求是从Master节点发起的,调度器会优先把任务分配到本地节点。解决这个问题需要显式配置调度约束,打破这种默认行为:
在task_spec里添加placement块,明确允许任务调度到Worker节点:
task_spec { # 原有的container_spec、networks内容... # 新增:配置调度策略,允许调度到所有可用节点 placement { constraints = [ # 可选:强制只调度到Worker节点 # "node.role != manager" # 或者更灵活:给所有可运行Jenkins的节点加标签(比如docker node update --label-add jenkins-enabled=true <node-name>) # "node.labels.jenkins-enabled == true" ] } }
另外,建议你对比手动创建的服务和Terraform创建的服务的配置差异,用以下命令查细节:
# 查看手动创建的服务配置 docker service inspect <手动服务名> # 查看Terraform创建的服务配置 docker service inspect <Terraform创建的服务名>
重点对比Spec.TaskSpec.Placement和Spec.Mode部分,如果发现Terraform创建的服务多了node.role == manager这类约束,那就是问题根源,需要用上面的placement块覆盖这个配置。
最后别忘了确认你的Worker节点状态正常:
docker node ls
确保Worker节点的STATUS是Ready,没有被隔离或标记为不可用。
内容的提问来源于stack exchange,提问作者Senthil Nathan Manoharan

