如何通过Docker Golang SDK在Swarm集群所有节点搜索指定名称容器
使用Docker Golang SDK在Swarm集群全节点搜索指定容器
核心思路
Swarm集群中,默认Docker客户端仅连接manager节点,只能直接查询manager上的容器。要遍历所有节点搜索目标容器,需先获取集群所有可用节点,再逐个连接节点执行容器查询操作。
具体实现步骤
获取集群可用节点列表
通过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) } }逐个节点查询目标容器
对每个可用节点,创建连接该节点的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
相关产品推荐
相关产品推荐

