Docker Swarm中Gitea配置global模式仅运行1副本问题排查
问题根因定位
集群内其他global模式服务可正常达到2/2副本状态,说明Swarm集群节点状态、核心调度逻辑无异常,问题出在Gitea服务的独立配置上,按触发概率从高到低排序如下:
- 核心触发原因:固定hostname配置引发DNS唯一性校验冲突
配置中为Gitea服务设置了全局固定的hostname: git.localdomain参数。Docker Swarm内置DNS要求所有接入同一overlay网络的容器必须拥有集群范围内唯一的主机名,避免DNS解析出现多IP指向冲突。当global模式服务配置了统一的固定hostname后,第一个节点的实例启动成功后,调度器会直接拦截其他节点的实例调度请求——后续实例使用相同hostname注册到DNS时会触发唯一性校验失败,最终全局仅保留1个运行副本。 - 次要可能原因:私有镜像仓库使用回环地址导致跨节点拉取失败
配置中使用的镜像地址为127.0.0.1:5000/custom_gitea:92,其中127.0.0.1为节点本地回环地址。如果私有镜像仓库仅部署在其中一个节点,另一个节点访问该地址时会指向自身的5000端口,无法拉取到Gitea镜像,对应节点的副本会启动失败。可在管理节点执行以下命令查看副本调度详情确认:
若未运行副本的节点对应状态为docker service ps <你的gitea服务名称> --no-truncErrImagePull即可判定为该原因。 - 低概率原因:绑定挂载路径跨节点不一致
配置中定义了多个主机路径绑定挂载,其中/data/gitea/app.ini为文件类型挂载。如果第二个节点上该路径不存在,Docker会默认创建同名目录替代,导致Gitea启动时读取配置失败、副本反复崩溃。但该场景下副本会被正常调度到对应节点,仅状态为异常重启,和当前“仅存在1个运行副本、无其他异常副本记录”的状态匹配度较低。
修复方案
- 优先删除Gitea服务配置中的
hostname: git.localdomain字段,重新部署服务。Swarm会自动为每个节点上的Gitea实例分配全局唯一hostname,服务内部可直接通过服务名gitea完成通信,无需为容器配置固定hostname。 - 若必须保留固定hostname配置,将镜像仓库地址修改为所有集群节点均可访问的内网非回环地址,提前在所有节点配置私有仓库信任规则,确保所有节点可正常拉取目标镜像。
- 提前在所有集群节点上创建绑定挂载所需的
/data/gitea目录及对应的app.ini配置文件,保证路径、权限、文件内容一致,避免挂载异常。
附问题对应的Gitea服务Compose配置片段:
... gitea: image: 127.0.0.1:5000/custom_gitea:92 restart: always hostname: git.localdomain build: /data/gitea/custom # ports: # - 4000:4000 # - 222:22 environment: USER: git USER_UID: 1000 USER_GID: 1000 GITEA__database__DB_TYPE: postgres GITEA__database__HOST: db:5432 GITEA__database__NAME: gitea GITEA__database__USER: gitea GITEA__database__PASSWD: gitea GITEA__security__INSTALL_LOCK: "true" GITEA__security__SECRET_KEY: XQolFkmSxJWhxkZrkrGbPDbVrEwiZshnzPOY volumes: - /data/gitea:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - /data/gitea/app.ini:/data/gitea/conf/app.ini deploy: mode: global depends_on: - db - openldap - openldap_admin networks: - vcc ...
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

