You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Stack部署报错:网络名称不符合DNS组件规范问题排查

问题描述

执行docker stack deploy -c docker-compose.yaml mynetwork时出现错误,创建网络mynetwork_失败,提示名称需为有效的DNS名称组件。使用Docker Secrets管理network_name等变量时触发该错误,不使用Secrets则正常;已尝试重启Docker、清理所有容器、网络、服务及镜像,问题仍未解决。

项目结构

项目包含.scripts目录(内含schema.sql和data.sql)、docker-compose.yaml配置文件、部署脚本文件。

docker-compose.yaml配置

version: "3.3"
services:
  database:
    image: mysql:8
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_USER: ${mysql_user}
      MYSQL_PASSWORD: ${mysql_password}
      MYSQL_ROOT_PASSWORD: ${mysql_root_password}
    ports:
      - "6033:3306"
    networks:
      - ${network_name}
    volumes:
      - dbdata:/var/lib/mysql
      - "./.scripts/schema.sql:/docker-entrypoint-initdb.d/1.sql"
      - "./.scripts/data.sql:/docker-entrypoint-initdb.d/2.sql"
    secrets:
      - mysql_user
      - mysql_password
      - mysql_root_password
      - container_name
      - network_name

secrets:
  mysql_user:
    file: /run/secrets/mysql_user
  mysql_password:
    file: /run/secrets/mysql_password
  mysql_root_password:
    file: /run/secrets/mysql_root_password
  network_name:
    file: /run/secrets/network_name

networks:
  ${network_name}:
    driver: bridge

部署脚本

#!/bin/bash

# Leave current swarm
docker swarm leave --force

# Initialize the host as a Swarm manager
docker swarm init

# Create the secrets
echo "server_user" | docker secret create mysql_user -
echo "server_password" | docker secret create mysql_password -
echo "a1128f69-e6f7-4e93-a2df-3d4db6030abc" | docker secret create mysql_root_password -
echo "template_network" | docker secret create network_name -

# Deploy the stack using the secrets
docker stack deploy -c docker-compose.yaml mynetwork

错误日志

Node left the swarm.
Swarm initialized: current node (y46rjvlu57bibyhgwk7nthykw) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-161prfq442ha035laq1plnv1o2qfqs026dmg6aslpd4kao7o0i-bnwc5zxiwt3ctmfbxfoszbick 192.168.65.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

l3nrkqhy7ygtrb05x7c5rvavu
xrhp70n50waaas1hqha8fk2j2
wj1y8runsi8vydpzc09hp9bmp
u5b6suutp7tkt4lqd5i90bgif
Creating network mynetwork_
failed to create network mynetwork_: Error response from daemon: rpc error: code = InvalidArgument desc = name must be valid as a DNS name component

解决方案

核心原因

Docker Secrets无法用于解析docker-compose.yaml中的顶层配置变量(如网络、服务名称)。Secrets的作用域仅局限于容器内部运行时,部署阶段Docker无法从Secrets读取network_name的值,导致变量未被替换,最终尝试创建名称为mynetwork_(栈名+下划线)的无效网络。

修复步骤

  1. 改用环境变量传递网络名称:将network_name从Secrets移到部署脚本的环境变量中,部署时传递给docker stack deploy。修改部署脚本:

    #!/bin/bash
    
    # Leave current swarm
    docker swarm leave --force
    
    # Initialize the host as a Swarm manager
    docker swarm init
    
    # 定义网络名称变量
    export network_name="template_network"
    
    # Create the secrets(移除network_name相关的secret创建)
    echo "server_user" | docker secret create mysql_user -
    echo "server_password" | docker secret create mysql_password -
    echo "a1128f69-e6f7-4e93-a2df-3d4db6030abc" | docker secret create mysql_root_password -
    
    # Deploy the stack,通过环境变量传递network_name
    docker stack deploy -c docker-compose.yaml mynetwork
    
  2. 调整docker-compose.yaml:移除secrets中的network_name配置,确保networks和services中的${network_name}能被环境变量正确解析:

    version: "3.3"
    services:
      database:
        image: mysql:8
        command: --default-authentication-plugin=mysql_native_password
        environment:
          MYSQL_USER: ${mysql_user}
          MYSQL_PASSWORD: ${mysql_password}
          MYSQL_ROOT_PASSWORD: ${mysql_root_password}
        ports:
          - "6033:3306"
        networks:
          - ${network_name}
        volumes:
          - dbdata:/var/lib/mysql
          - "./.scripts/schema.sql:/docker-entrypoint-initdb.d/1.sql"
          - "./.scripts/data.sql:/docker-entrypoint-initdb.d/2.sql"
        secrets:
          - mysql_user
          - mysql_password
          - mysql_root_password
    
    secrets:
      mysql_user:
        file: /run/secrets/mysql_user
      mysql_password:
        file: /run/secrets/mysql_password
      mysql_root_password:
        file: /run/secrets/mysql_root_password
    
    networks:
      ${network_name}:
        driver: bridge
    
  3. 验证部署:重新执行部署脚本,此时network_name会被环境变量正确替换,Docker将创建名为mynetwork_template_network的合法网络(栈名+网络名)。

优化建议

  • 区分配置层级:顶层配置(如网络、服务名称、卷名称)使用环境变量传递,容器运行时敏感数据(如密码、用户名)使用Docker Secrets。
  • 避免冗余配置:无需在容器secrets字段添加network_name,它不属于容器运行时需要的敏感数据。
  • 添加状态检查:部署前可增加Swarm状态检查,避免重复执行swarm init导致异常。

内容的提问来源于stack exchange,提问作者HopefulSplash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:56:09