kubernetes二次开发-client go


准备工作

1. 检查k8s的版本

[root@k8s-node1 ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5", GitCommit:"aea7bbadd2fc0cd689de94a54e5b7b758869d691", GitTreeState:"clean", BuildDate:"2021-09-15T21:10:45Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5", GitCommit:"aea7bbadd2fc0cd689de94a54e5b7b758869d691", GitTreeState:"clean", BuildDate:"2021-09-15T21:04:16Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}

2. 选择和kuberntes适配的client-go版本
client-go的源码位置:https://github.com/kubernetes/client-go.git

ps:This repository is still a mirror of k8s.io/kubernetes/staging/src/client-go, the code development is still done in the staging area.
client-go是k8s.io/kubernetes/staging/src/client-go的一个镜像,该仓库下的代码开发工作仍旧是在staging下完成的

由于我们的Kubernetes版本为v1.21.5,所以适配的client-go版本也为v0.1.25,关于如何适配,官方这样描述:

  • If you are using Kubernetes versions >= v1.17.0, use a corresponding v0.x.y tag. For example, k8s.io/client-go@v0.20.4 corresponds to Kubernetes v1.20.4:
    go get k8s.io/client-go@v0.20.4
  • If you are using Kubernetes versions < v1.17.0, use a corresponding kubernetes-1.x.y tag. For example, k8s.io/client-go@kubernetes-1.16.3 corresponds to Kubernetes v1.16.3:
    go get k8s.io/client-go@kubernetes-1.16.3

3. 到kubernets集群中拿到kubeconfig文件

关于client-go的运行方式,它可以运行在集群内的pod内,也可也运行在集群外

  • 在集群内运行时,需要将应用打成镜像,部署到集群内;client-go在调用“rest.InClusterConfig() ”将使用pod内“/var/run/secrets/kubernetes.io/serviceaccount”目录下的token文件做集群内的访问认证,如下面是某个container中该目录下的内容:

  • 在集群外部运行时,需要使用到kubeconfig文件,它包含了集群初始化一个client的信息,该文件也被kubectl命令用作访问集群时的身份认证

这里我们选择在集群之外运行

Authenticating outside the cluster

This example shows you how to configure a client with client-go to authenticate to the Kubernetes API from an application running outside the Kubernetes cluster.

You can use your kubeconfig file that contains the context information of your cluster to initialize a client. The kubeconfig file is also used by the kubectl command to authenticate to the clusters.

登录到kuberntes集群,取得/root/.kube/config文件,将文件下载到本地的“C:\Users\Administrator.kube\”路径下。

点击查看代码
[root@k8s-node1 .kube]# cat config 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1ERXlNREF5TVRFME1Gb1hEVE15TURFeE9EQXlNVEUwTUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTGhYCkEyY1B3T0Y0R0R0bGN3RFY3UGVOUThYOUd2MnlkRGJCNnhYd2ZJdGtTcGM1Vk50R3E1Q0FyeUtnSDcrdVJnUUkKK2VSeXNaT3Z1eGhoRGR5dmhCSnFhcm54TEJ0dmlTVTViYjlBT3NIUmsveWdHN2ZLbkl1bVp6K1hvSHFGcjAwTQo5ZzNPMXJBeVZuaFFTbmVqcEl6T09nOXlmNDZTN2ZLZi92USt0OWJmSzUySmN1VVlQZHA0b1p2ek5HWlc3MGdnCjFFbGRQMDJZYk81T1hBbjhzK2l3MG1JWm50QU1CU0pMT2x1eUkrK08remF0YTEvTStXNlc2YXRoT1Eyd0EyR3QKVm56bFpaVXZIRmJkVlFBNThBN2JmRWs3M24yVzdNZmlYMHdYKzRDdHZoNGJpaUNldkRoc3FXOHp6S0dZam5tNAp5dWZ5MTRXM3IwUFluNk5zR2k4Q0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZHSE9saWdkVUdCUlhodGxsL2xqRzY3S0FSQk5NQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFDdEt5R0pkVVMxUGs0bCs0YldMSUJOaTFWejlzeHFLMURZNmJWdjRXU2JxQmUyWnc0cgo4Mm5URzVKR0hmcEg1dmZ5RlRJR3VKYzNGRnc1dG82VDQ4alhyKzZTTUIxMXZnVUs0Yjl1cWVLU1JHM3RGRVRuCllyNXorZHk4QUFuNHdPUlZpY1RsQlM3OTN3bzVqdnhTMGQ5Vy9tVVJXVEkwSGluQ0grdzBWMXVhT2ljeUxpQTIKQjBIM2dtRmZaNlhmYlZHT2k0TnZXMHdtdnRGUmdpUnJsaC9ndHZ2amtBTVpsb2pyWWhKampuZUl3S1Bla1djYQpzKzEzRnVJdTE5QU11cUdJRW9OQVJFRlZtU3ArSFE2d1RnRmt2MSthbWFJRnowcHlvVFNzQWFaNEYvVXdCT016CmFpTDArTXhqWnZ4bkdHcFVXMUxVZGVtcS9YNlZVOEtMdXRWagotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://lb.kubesphere.local:6443  
  name: cluster.local
contexts:
- context:
    cluster: cluster.local
    user: kubernetes-admin
  name: kubernetes-admin@cluster.local
current-context: kubernetes-admin@cluster.local
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJSURMWXUycmpjd0V3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TWpBeE1qQXdNakV4TkRCYUZ3MHlNekF4TWpBd01qRXhOREZhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXh5cTd6MHphN2U3bmhKVnEKNy95ODlza2QyWmpXTUJtdlFWaVdxbFQyT0RtNGpIV3lRbllRYXROVXZHeTZmb1Y5TWpNWnB2Y1RhZWUvZlZWNQo1RE9zSEFhWjhnRzRieWlYaW5EaXU5aGljZTVCbldnR0R0aytOUnY0SXd1aHNXd25CZEgzQVc3eTNtNTd6RmxkCnNHeG1yMzhFdERUd0lVa3ZLazROMTJLRHFoZFNMRWhmVVlTRmRVVHJSV0VCTEtCNkFURGVsYWZiUW1WYnZDbzgKM3ZMeWxSbTB6VWdFVGc3NUZ0NGFkRWVJMjY2RDJZZmYvQnd3Z2w0cDJvSFlKb1h5VSthMnlnK1JWZDJIVzZXcQpVMTJVd2ZlUEpCQ3habnJrZmFCek16ajduK1l3RlF4THFMOFBsN01kc3RDMHdJb3BmLzNOaVp1YWR2TFIwUDVaCkZEWTNHUUlEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JSaHpwWW9IVkJnVVY0YlpaZjVZeHV1eWdFUQpUVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBSzU1QVJ2K1crT1lYaGEzdXVhd2NrbGYzVjEwTkc4NndpRnNJCkU2ejBiamV5dVVuUGxtdTZ0ZEN3Z0VYZFl0TDV4RHp3NG43RXVWRkZuSVZZRFpwM21LYmFtU0tsYm05WmZNKzcKWmtDVFlkdnkwbUcxS2dyR0dRejA4QVVOcUw5ZkR4M1ZSYUw5cWhvd1ozWG81Ykd6MGc5U2lCZGV0NGpuMnBuZQo1eUR1SWh2TE9PbVo1Rm5JTGZGY1pQYjc0RGZqaldnSEc3OGt3KzI2YXRFSWRZVWQxMWhxNk9nSEphaVRsZnRkCnlSNWdsV3JnQWIwT2JlSXk3cFR1bVhteGd1a25JaFhxMUlOZElaZWVwa3l0a3gxZm53ZmxkcGExYTA4RFlCNzMKcVlKVWY3V0o3dERnWFAzUFpnNVNYZVlFZFhLZVNnY1lSc3EwODF4aFBRaE5qQVI0REE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBeHlxN3owemE3ZTduaEpWcTcveTg5c2tkMlpqV01CbXZRVmlXcWxUMk9EbTRqSFd5ClFuWVFhdE5Vdkd5NmZvVjlNak1acHZjVGFlZS9mVlY1NURPc0hBYVo4Z0c0YnlpWGluRGl1OWhpY2U1Qm5XZ0cKRHRrK05SdjRJd3Voc1d3bkJkSDNBVzd5M201N3pGbGRzR3htcjM4RXREVHdJVWt2S2s0TjEyS0RxaGRTTEVoZgpVWVNGZFVUclJXRUJMS0I2QVREZWxhZmJRbVZidkNvODN2THlsUm0welVnRVRnNzVGdDRhZEVlSTI2NkQyWWZmCi9Cd3dnbDRwMm9IWUpvWHlVK2EyeWcrUlZkMkhXNldxVTEyVXdmZVBKQkN4Wm5ya2ZhQnpNemo3bitZd0ZReEwKcUw4UGw3TWRzdEMwd0lvcGYvM05pWnVhZHZMUjBQNVpGRFkzR1FJREFRQUJBb0lCQUM5R1VYWVBSQmdlRVE1RAplVEtseHlTODhEenFMazBVaTZqeklqQWtJcDJOOWVSQk82TFM2MnF2NXZraXhkR3FWZUZJaDlvOTQzbkw3SVFQCmVmTlU0SkYyYjZ3bUJHVStPVm8vR1ZLRk5qamMyTzVIOXNnbmdNQ1Nkdis2anhMU0hTRWdpWVRwbFBSL1BSdHcKU3ZESmlrWTEzQ1A2UE5WcHphdzVBc2dSTmpkMURnRFc2a0ZkMTRGQ3pxaTdlVmRhLzdaVjltVXNrb1lRaEVtYwp2ZVgyTTJRaXhOQUQvTkorblZzaGlFZExqTU9RTXc3VjNMK1VueHpHNm1qQjlJbXB6RGp0VkluYmZGWW4yekZ6Cmt0c0ljdWtRZWFkd2o3d1ZUL2c2U1NrcURiaWFuR3Bma0tkaTJEK1cvT1FoNTBadzZKSHE4MWtXY2VVMG8zVHoKUlk2YkI1RUNnWUVBOTZ3ZDk2QTV1Y2dwcjZ6L0tyejI5a3pjOVo5RFB3bnFoN0JsUFdWc1RiQkUvZmE0ckNSLwpsSHBhL2RJWFZ4dmpncTdRd0tRREdFcnN1SlRzTnNMczVLUUswdnFxVEZ4d29Rd0ZodlZLbWFMdndJWDlmNTZQCk1SWDVIV1BkYUV3L0JzcnZwdGUySTFtTDIxNVJpTC9BL0VSMVFvR2Y3b2xzNU5oZ21Kcko4K3NDZ1lFQXpkMFoKQ3F5L242Y2syRVUxUFNVa0NJVk15ZWdQVGNjVGdlelFaTjZBb2JJYjIzVXdhSlFDMndFK3l5QmhmMSthdGVDRApkSkRpU0ZBWVFyemJRUFdRSXNYQThWRm5KRzNOeGp0ZkI4OGNLaW1TcUJ3NmNOVVJuYmo2YzVLYzAvMmNyWlcvClFISzJwVDNXTi9HbEdRb1FlN2VmNUFjNndCT1lXS014c0dHM05Bc0NnWUVBbGRxQkkwUEJ5YVBQZlNpNkZ6elEKWEVRemFUWWN0UGFsL2NWLzYvOEM0WnFtazljRTg3cjlxblBCdkZPeXBaVU5PaFBWNE1rYnlrWURKc2VNaUxHMgpMYjBIZzVJQkdrVFFMTkVlUXdNRlNTSXAyQjM2UEk1T2EwKzFNOUFwdGFKMGZBS3JzQkpTZE44SVhRbWJZWmRNCkNCYlBzQmJJRXNiNXFSazJrUDhPOUZNQ2dZRUFwbUtoLzcrNXJTY2huMjdvWmNBa0RJTDRtbVBtSXAzWlJYU0sKeGt3VHVSekVhUzZoYnBUYWJmbm1yN1EvT1B5amhZYXRtTVFWTUE4VVhMUlpuWG9jQWc3Rk1BWDBFRHh6U1ZucApKOTJjVFBPRzVqclNmU21vOEVwMm1ueVFKc0xmSkdsWXg1VXZ6QVJicEtHNUo3Qzd1OUtnOTJOa2Q2UWV5TjAxCnB2S0RhUnNDZ1lFQWdNVk8xa1JkTDJpU2ZLTEl3dSs4SFQydHlXMGp0Y2VDTmlJdEJqdlMwRFA4d2JjMGk3SXkKdFlLNHl1MGdEdEdNZUZ3WXpRa3pMaE1DbzNBSldUbHZjdTdJbVZoUG04bEtWdTRUYThIdFI3L3B1NUNGWnhKMQpEODE5RnlkM3Q3dm51S3grMnY1Q3VYQmlvMTlHZVRoTjB3RkxRSzRnYzlXZmNrUktLanFBQmdnPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
[root@k8s-node1 .kube]# 

注意:如果应用是部署在阿里云等设备上,需要添加端口放行规则,并且在本地的HOSTS文件中添加对于“lb.kubesphere.local”的映射规则,IP为自己的弹性公网IP

创建开发项目

在Goland中创建go module项目“K8s-client-go”,添加依赖:go get k8s.io/client-go@v0.21.5

点击查看代码
package main

import (
    "context"
    "flag"
    "fmt"
    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"
    "k8s.io/klog"
    "path/filepath"
)

func main() {
    var kubeConfig *string
    ctx := context.Background()
    //取得kubeconfig的路径
    if home := homedir.HomeDir();home!= ""{
       kubeConfig=flag.String("kubeConfig",filepath.Join(home,".kube","config"),"absolute path to the kubeconfig file")
    }else {
        kubeConfig=flag.String("kubeConfig","","absolute path to the kubeconfig file")
    }

    flag.Parse()
    config, err := clientcmd.BuildConfigFromFlags("", *kubeConfig)
    if err!=nil{
        klog.Fatal(err)
        return
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err!=nil{
        klog.Fatal(err)
        return
    }
    //获取namespaces信息
    namespaces := clientset.CoreV1().Namespaces()
    namespaceList, err := namespaces.List(ctx, metav1.ListOptions{})
    if err!=nil{
        klog.Fatal(err)
        return
    }
    for _, namespace := range namespaceList.Items {
       fmt.Println(namespace.Name)
    }

}

运行结果:

default
edu
his
his-devops98s4z
kube-node-lease
kube-public
kube-system
kubesphere-controls-system
kubesphere-devops-system
kubesphere-devops-worker
kubesphere-monitoring-federated
kubesphere-monitoring-system
kubesphere-system
mall

和kuberntes集群上的namespaces查询结果比较:

[root@k8s-node1 ~]# kubectl get namespace
NAME                              STATUS   AGE
default                           Active   4d6h
edu                               Active   4d1h
his                               Active   4d1h
his-devops98s4z                   Active   24h
kube-node-lease                   Active   4d6h
kube-public                       Active   4d6h
kube-system                       Active   4d6h
kubesphere-controls-system        Active   4d6h
kubesphere-devops-system          Active   29h
kubesphere-devops-worker          Active   29h
kubesphere-monitoring-federated   Active   4d6h
kubesphere-monitoring-system      Active   4d6h
kubesphere-system                 Active   4d6h
mall                              Active   4d1h

这里有一个需要说明的地方,我们在列举namespace时,使用的是“clientset.CoreV1().Namespaces()”,为什么是corev1不是appsv1,这是因为namespaces在api-resouces中定义的位置所决定的:

点击查看代码
[root@k8s-node1 ~]# kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod
podtemplates                                   v1                                     true         PodTemplate
replicationcontrollers            rc           v1                                     true         ReplicationController
resourcequotas                    quota        v1                                     true         ResourceQuota
secrets                                        v1                                     true         Secret
serviceaccounts                   sa           v1                                     true         ServiceAccount
services                          svc          v1                                     true         Service

上面的这些APIVERSION为v1的都是corev1下的资源,但是有些版本中该字段显示为空;它们在Kubernetes仓库中的地址:kubernetes\staging\src\k8s.io\client-go\kubernetes\typed\core\v1

有些时候,若不确定资源在何路径下,可以打印它的日志
namespace

[root@k8s-node1 ~]# kubectl get namespace -v=7 
I0124 17:23:07.560906  590266 loader.go:372] Config loaded from file:  /root/.kube/config
I0124 17:23:07.571697  590266 round_trippers.go:432] GET https://lb.kubesphere.local:6443/api/v1/namespaces?limit=500

daemonset

[root@k8s-node1 ~]#kubectl get daemonset -v=7
I0124 17:24:44.668978  592516 loader.go:372] Config loaded from file:  /root/.kube/config
I0124 17:24:44.679221  592516 round_trippers.go:432] GET https://lb.kubesphere.local:6443/apis/apps/v1/namespaces/default/daemonsets?limit=500

kubernetes的资源和仓库代码路径大致对应如下:

关于kubernetes的日志级别

--v=0   Generally useful for this to ALWAYS be visible to an operator.
--v=1   A reasonable default log level if you don’t want verbosity.
--v=2   Useful steady state information about the service and important log messages that may correlate to significant changes in the system. This is the recommended default log level for most systems.
--v=3   Extended information about changes.
--v=4   Debug level verbosity.
--v=6   Display requested resources.
--v=7   Display HTTP request headers.
--v=8   Display HTTP request contents

参考连接: