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

如何通过Docker Golang SDK在Swarm集群所有节点搜索指定名称容器

使用Docker Golang SDK在Swarm集群全节点搜索指定容器

核心思路

Swarm集群中,默认Docker客户端仅连接manager节点,只能直接查询manager上的容器。要遍历所有节点搜索目标容器,需先获取集群所有可用节点,再逐个连接节点执行容器查询操作。

具体实现步骤

  1. 获取集群可用节点列表
    通过SDK的NodeList方法拉取集群节点,过滤出处于Ready状态的节点(跳过不可用节点减少无效查询):

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    // 初始化连接Swarm manager的客户端
    client, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }
    defer client.Close()
    
    // 获取集群所有节点
    nodes, err := client.NodeList(ctx, types.NodeListOptions{})
    if err != nil {
        panic(err)
    }
    
    // 筛选Ready状态的节点
    var readyNodes []types.Node
    for _, node := range nodes {
        if node.Status.State == types.NodeStateReady {
            readyNodes = append(readyNodes, node)
        }
    }
    
  2. 逐个节点查询目标容器
    对每个可用节点,创建连接该节点的Docker客户端(节点地址从Status.Addr字段获取),再通过过滤器匹配容器名称:

    targetContainerName := "your-target-container"
    var foundContainers []types.Container
    
    // 并发查询提升效率
    var wg sync.WaitGroup
    var mu sync.Mutex
    
    for _, node := range readyNodes {
        wg.Add(1)
        go func(n types.Node) {
            defer wg.Done()
    
            // 构建节点的Docker客户端配置(替换为你的TLS证书路径)
            nodeHost := fmt.Sprintf("tcp://%s:2376", n.Status.Addr)
            nodeClient, err := client.NewClientWithOpts(client.WithHost(nodeHost), client.WithTLSClientConfig(
                "./cert.pem", "./key.pem", "./ca.pem",
            ))
            if err != nil {
                fmt.Printf("连接节点%s失败: %v\n", n.ID, err)
                return
            }
            defer nodeClient.Close()
    
            // 构建容器名称过滤器:精确匹配用^/container-name$,模糊匹配直接写名称
            filter := filters.NewArgs()
            filter.Add("name", fmt.Sprintf("^/%s$", targetContainerName))
    
            // 查询节点上的容器(All: true 包含已停止的容器)
            containers, err := nodeClient.ContainerList(ctx, types.ContainerListOptions{
                Filters: filter,
                All:     true,
            })
            if err != nil {
                fmt.Printf("查询节点%s容器失败: %v\n", n.ID, err)
                return
            }
    
            // 线程安全收集结果
            mu.Lock()
            foundContainers = append(foundContainers, containers...)
            mu.Unlock()
        }(node)
    }
    
    wg.Wait()
    
    // 输出查询结果
    fmt.Printf("找到%d个匹配容器:\n", len(foundContainers))
    for _, c := range foundContainers {
        fmt.Printf("容器ID: %s, 所属节点: %s\n", c.ID[:12], c.NodeID)
    }
    

关键注意事项

  • TLS证书配置:如果集群节点Docker API启用了TLS,必须携带对应证书才能成功连接,否则会出现权限错误。
  • 并发与线程安全:用goroutine+WaitGroup实现并发查询,避免串行查询耗时过长;用互斥锁保证结果收集的线程安全。
  • 容器名称匹配规则:Docker API返回的容器名称带前缀/,精确匹配时需加上^/和$,模糊匹配直接输入名称即可。
  • 节点网络可达性:确保manager节点能访问目标节点的2376端口(Docker API默认端口),部分节点的Status.Addr可能是内部IP,需确认网络连通性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:44:59