使用client-go访问k8s集群

目录

环境准备:

  1. k8s客户端
  2. minikube模拟k8s集群
  3. go version = 1.25.0

理论支撑

正常来说,使用kubectl相关命令完全可以访问K8s集群,但是CLient-go可以在代码中操作和访问K8s集群。它模拟了K8s的API接口,因此可以达到这种效果。

实战

代码1:使用kubeconfig访问

kubeconfig是k8s客户端访问集群的一个钥匙🔑。正常来说,我们访问K8s集群都要使用这个文件kubeconfig。使用minikube启动集群后,自动会在下面目录生成一个config文件。

bash 复制代码
➜  .kube ls
cache  config
➜  .kube pwd
/Users/xty/.kube


➜  .kube cat config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /Users/xty/.minikube/ca.crt
    extensions:
    - extension:
        last-update: Sat, 27 Dec 2025 16:27:36 CST
        provider: minikube.sigs.k8s.io
        version: v1.37.0
      name: cluster_info
    server: https://localhost:64867
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        last-update: Sat, 27 Dec 2025 16:27:36 CST
        provider: minikube.sigs.k8s.io
        version: v1.37.0
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /Users/xty/.minikube/profiles/minikube/client.crt
    client-key: /Users/xty/.minikube/profiles/minikube/client.key

代码如下:

go 复制代码
package main
import (
	"context"
	"flag"
	"fmt"
	"path/filepath"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

func main() {

	// 加载 kubeconfig 配置
	var kubeconfig *string
	if home := homedir.HomeDir(); home != "" {
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "[可选] kubeconfig 绝对路径")
	} else {
		kubeconfig = flag.String("kubeconfig", "", "kubeconfig 绝对路径")
	}
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}

	// 可以看一下 Pods 里面有什么操作
	pods, err := clientset.CoreV1().Pods("default").List(context.Background(), metav1.ListOptions{})
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
	for _, pod := range pods.Items {
		fmt.Printf("Pod name %s\n", pod.Name)
	}
	// 继续
	deployment, err := clientset.AppsV1().Deployments("default").List(context.Background(), metav1.ListOptions{})
	for _, d := range deployment.Items {
		fmt.Printf("deployment name %s", d.Name)
	}
}

go run main.go
Pod name nginx-deployment-77bf8679f9-94d99
Pod name nginx-deployment-77bf8679f9-cdsbk
deployment name nginx-deployment%                                                                                                                                                   

可以发现确实访问到了集群中的信息。

代码2:使用InClusterConfig()方式

正常来说,直接通过集群的公网IP访问集群,权限太大了(方法1)。同时有些集群是没有公网IP的,为了保护自己的服务,不对外开放,这种方式相对于企业来说更合适。

那没有公网IP如何访问呢?

  • K8s在部署pod时候,会给它们注入Service Account配置文件,里面包括token和ca证书。
go 复制代码
"/var/run/secrets/kubernetes.io/serviceaccount/token"
"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
  • K8s会给Pod注入KUBENETS_SERVICE_HOST和KUBENETS_SERVICE_PORT变量
    如下图所示:

    看该函数也可以看到它读取相关文件:

实现代码如下:

go 复制代码
package main

import (
	"context"
	"fmt"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

func main() {
	// demo2 in cluster config
	config, err := rest.InClusterConfig()
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}

	// 可以看一下 Pods 里面有什么操作
	pods, err := clientset.CoreV1().Pods("default").List(context.Background(), metav1.ListOptions{})
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
	for _, pod := range pods.Items {
		fmt.Printf("Pod name %s\n", pod.Name)
	}

	// 继续
	deployment, err := clientset.AppsV1().Deployments("default").List(context.Background(), metav1.ListOptions{})
	for _, d := range deployment.Items {
		fmt.Printf("deployment name %s", d.Name)
	}
}

直接运行会报错:说没有pod list 权限

我们给他添加权限:

解释:

然后就有一个demo的权限绑定到改容器中!

最后再次部署执行就可以啦:

相关推荐
间彧1 天前
对比分析containerd vs CRI-O的性能差异和适用场景
kubernetes
间彧1 天前
边缘计算场景下,CRI-O相比containerd在资源节省方面有哪些具体的技术实现
kubernetes
是Judy咋!1 天前
基于kube-prometheus-release监控---k8s集群与业务服务
容器·kubernetes·prometheus
源代码•宸1 天前
goframe框架签到系统项目开发(实现总积分和积分明细接口、补签日期校验)
后端·golang·postman·web·dao·goframe·补签
叫致寒吧1 天前
K8S 概念
云原生·容器·kubernetes
羊羊羊i1 天前
通过Crossplane使用K8sYAML格式的API接口,创建虚拟云资源,同时利用ArgoCD达到GitOps效果
容器·kubernetes·argocd
YGGP1 天前
【Golang】LeetCode 2. 两数相加
开发语言·leetcode·golang
Yy_Yyyyy_zz1 天前
2025 技术年终总结|近七年 Golang 工程实践、AI 应用落地与技术创作回顾
开发语言·golang·ai编程
GrowingYi1 天前
Go语言的特性
开发语言·后端·golang