在Kubernetes集群中部署应用后,实时获取Pod和Service的运行状态是排查部署问题、保障服务可用性的核心需求。通过Golang结合client_go库,我们可以快速实现集群资源的监控能力,无需依赖第三方监控工具即可完成基础的状态采集工作。

环境准备与依赖安装
首先需要在项目中引入client_go相关依赖,client_go是Kubernetes官方提供的Golang客户端库,支持与集群API Server进行交互。在项目的go.mod文件中添加以下依赖:
module k8s-monitor
go 1.21
require (
k8s.io/client-go v0.28.0
k8s.io/apimachinery v0.28.0
)
安装依赖后,需要准备集群的kubeconfig文件,用于客户端认证连接集群。如果是集群内部署的应用,可以直接使用集群内部的Service Account进行认证,无需额外配置文件。
初始化Kubernetes客户端
连接集群的核心步骤是初始化clientset对象,根据运行环境不同分为集群外和集群内两种初始化方式。以下是集群外通过kubeconfig文件初始化的示例代码:
package main
import (
"flag"
"fmt"
"path/filepath"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
// 初始化Kubernetes客户端
func initClient() (*kubernetes.Clientset, error) {
var kubeconfig *string
// 如果指定了kubeconfig路径则使用指定路径,否则默认使用用户目录下的.kube/config
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "kubeconfig文件的绝对路径")
} else {
kubeconfig = flag.String("kubeconfig", "", "kubeconfig文件的绝对路径")
}
flag.Parse()
// 通过kubeconfig构建配置
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
return nil, fmt.Errorf("构建配置失败: %v", err)
}
// 创建clientset客户端
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("创建客户端失败: %v", err)
}
return clientset, nil
}
实时获取Pod状态
Pod是应用部署的最小单元,我们可以通过clientset的CoreV1()接口获取指定命名空间或者所有命名空间的Pod状态。以下代码实现了获取所有命名空间Pod基础状态的逻辑:
package main
import (
"context"
"fmt"
"time"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// 获取所有Pod的状态信息
func getPodStatus(clientset *kubernetes.Clientset) error {
// 设置超时上下文
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// 获取所有命名空间的Pod列表
pods, err := clientset.CoreV1().Pods("").List(ctx, metav1.ListOptions{})
if err != nil {
return fmt.Errorf("获取Pod列表失败: %v", err)
}
fmt.Println("当前集群Pod状态统计:")
// 遍历Pod输出关键信息
for _, pod := range pods.Items {
fmt.Printf("命名空间: %s, Pod名称: %s, 当前状态: %s, Pod IP: %sn",
pod.Namespace,
pod.Name,
pod.Status.Phase,
pod.Status.PodIP,
)
}
return nil
}
Pod的状态pod.Status.Phase常见取值包括Pending、Running、Succeeded、Failed、Unknown,我们可以根据这些取值判断Pod是否处于正常运行状态,其中Running表示Pod正常运行,Failed表示Pod运行失败。
实时获取Service状态
Service是应用对外暴露服务的入口,我们需要关注Service的类型、端口映射以及关联的Endpoints状态。以下是获取Service状态及对应Endpoints信息的代码:
package main
// 获取所有Service的状态及Endpoints信息
func getServiceStatus(clientset *kubernetes.Clientset) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// 获取所有命名空间的Service列表
services, err := clientset.CoreV1().Services("").List(ctx, metav1.ListOptions{})
if err != nil {
return fmt.Errorf("获取Service列表失败: %v", err)
}
fmt.Println("n当前集群Service状态统计:")
for _, svc := range services.Items {
// 获取Service对应的Endpoints
endpoints, err := clientset.CoreV1().Endpoints(svc.Namespace).Get(ctx, svc.Name, metav1.GetOptions{})
endpointReady := false
if err == nil {
// 判断Endpoints是否有就绪的后端
for _, subset := range endpoints.Subsets {
if len(subset.Addresses) > 0 {
endpointReady = true
break
}
}
}
fmt.Printf("命名空间: %s, Service名称: %s, 类型: %s, 端口: %v, 后端就绪: %vn",
svc.Namespace,
svc.Name,
svc.Spec.Type,
svc.Spec.Ports,
endpointReady,
)
}
return nil
}
Service的Endpoints状态可以反映后端Pod是否正常接入服务,如果Endpoints中没有就绪的地址,说明当前Service没有可用的后端实例,服务访问会出现异常。
主函数整合与定时监控实现
将上述功能整合到主函数中,并且通过定时循环实现实时状态监控的效果,代码如下:
package main
import (
"k8s.io/client-go/kubernetes"
"time"
)
func main() {
// 初始化客户端
clientset, err := initClient()
if err != nil {
panic(fmt.Sprintf("初始化客户端失败: %v", err))
}
// 每30秒执行一次状态采集
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
// 先执行一次采集
collectStatus(clientset)
// 定时循环采集
for range ticker.C {
collectStatus(clientset)
}
}
// 统一的采集入口函数
func collectStatus(clientset *kubernetes.Clientset) {
fmt.Printf("n===== %s 开始采集状态 =====n", time.Now().Format("2006-01-02 15:04:05"))
// 采集Pod状态
if err := getPodStatus(clientset); err != nil {
fmt.Printf("采集Pod状态失败: %vn", err)
}
// 采集Service状态
if err := getServiceStatus(clientset); err != nil {
fmt.Printf("采集Service状态失败: %vn", err)
}
fmt.Println("===== 状态采集结束 =====")
}
异常状态告警扩展
在获取状态的基础上,我们可以添加简单的异常判断逻辑,当Pod状态不是Running或者Service后端不可用时输出告警信息。例如可以在getPodStatus函数中添加如下判断:
// 在遍历Pod的循环中增加异常判断
if pod.Status.Phase != v1.PodRunning {
fmt.Printf("【告警】Pod %s/%s 状态异常,当前状态: %sn", pod.Namespace, pod.Name, pod.Status.Phase)
}
通过这种方式可以快速识别部署过程中的异常Pod和不可用的Service,结合钉钉、企业微信等通知渠道可以进一步实现自动化告警能力。
GolangKubernetesclient_goPod状态Service状态修改时间:2026-07-03 00:48:45