目录
环境准备:
- k8s客户端
- minikube模拟k8s集群
- 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的权限绑定到改容器中!

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