当我们开发一个程序,需要访问k8s集群中的pod、deployment等资源时,会使用k8s.io/client-go模块,在使用这个模块时,我们要有如下几步:
1.获取config对象
clientcmd.BuildConfigFromFlags 根据config路径获取config
rest.InClusterConfig 直接使用pod中自带的token等内容
2.获取k8s client
3.使用k8s client获取k8s资源
package main
import (
"context"
"fmt"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"os"
"path/filepath"
)
func main() {
kubeConfig, err := CreateKubeConfig()
if err != nil {
panic(err)
}
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
panic(err)
}
//获取pod资源
kubeClient.CoreV1().Pods("").List(context.Background(),v1.ListOptions{})
}
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func CreateKubeConfig() (*rest.Config, error) {
kubeConfigPath := ""
if home := homedir.HomeDir(); home != "" {
kubeConfigPath = filepath.Join(home, ".kube", "config")
}
fileExist, err := PathExists(kubeConfigPath)
if err != nil {
return nil, fmt.Errorf("justify kubeConfigPath exist err,err:%v", err)
}
//.kube/config文件存在,就使用文件
//这里主要是本地测试
if fileExist {
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
if err != nil {
return nil, err
}
return config, nil
} else {
//当程序以pod方式运行时,就直接走这里的逻辑
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
return config, nil
}
}下面我们主要介绍下InClusterConfig
1.创建serviceAccount
要想操作k8s的相关资源,需要给某个serviceAccount授权
如上:我们要操作pod资源,就要创建如下资源
创建如下资源后,opPodServiceAccount这个serviceAccout就有操作pod的权限了
apiVersionrbac.authorization.k8s.io/v1
kindClusterRole
metadata
creationTimestampnull
nameopPodClusterRole
rules
apiGroups
""
resources
pods
verbs
list
watch
---
apiVersionrbac.authorization.k8s.io/v1
kindClusterRoleBinding
metadata
nameopPodClusterRoleBinding
roleRef
apiGrouprbac.authorization.k8s.io
kindClusterRole
nameopPodClusterRole
subjects
kindServiceAccount
nameopPodServiceAccount
namespacedefault
---
apiVersionv1
kindServiceAccount
metadata
nameopPodServiceAccount
namespacedefault2.指定运行程序的pod使用上面的ServiceAccount
serviceAccount: live-media-watch-pod
apiVersionapps/v1
kindDeployment
metadata
labels
operatorlive-media-watch-pod
namelive-media-watch-pod
namespacebixin-system
spec
replicas1
selector
matchLabels
operatorlive-media-watch-pod
strategy
rollingUpdate
maxSurge100%
maxUnavailable0
typeRollingUpdate
template
metadata
creationTimestampnull
labels
operatorlive-media-watch-pod
spec
containers
image******.**.com/k8s/live-media-watch-pod202201211654
imagePullPolicyIfNotPresent
livenessProbe
failureThreshold10
httpGet
pathhealthz
port8080
schemeHTTP
initialDelaySeconds30
periodSeconds5
successThreshold1
timeoutSeconds3
namelive-media-watch-pod
readinessProbe
failureThreshold10
httpGet
pathhealthz
port8080
schemeHTTP
initialDelaySeconds30
periodSeconds5
successThreshold1
timeoutSeconds3
serviceAccountlive-media-watch-pod这样之后,我们查看pod的yaml,会看到pod自动就多了一个volums,来自live-media-watch-pod-token-fhvk2 secret。
而且该secret挂载在了/var/run/secrets/kubernetes.io/serviceaccount路径下。
apiVersionv1
kindPod
metadata
annotations
kubernetes.io/pspack.privileged
creationTimestamp"2022-01-21T08:57:44Z"
generateNamelive-media-watch-pod-6f688c8b98-
labels
operatorlive-media-watch-pod
pod-template-hash6f688c8b98
namelive-media-watch-pod-6f688c8b98-w9txp
namespacebixin-system
ownerReferences
apiVersionapps/v1
blockOwnerDeletiontrue
controllertrue
kindReplicaSet
namelive-media-watch-pod-6f688c8b98
uid79843c47-296c-4bbb-8ff3-82d7fe74719b
resourceVersion"83659547"
uid23ef3ff1-bef6-4d7d-9e75-faea932f7919
spec
containers
image**.**.com/k8s/live-media-watch-pod202201211654
imagePullPolicyIfNotPresent
livenessProbe
failureThreshold10
httpGet
pathhealthz
port8080
schemeHTTP
initialDelaySeconds30
periodSeconds5
successThreshold1
timeoutSeconds3
namelive-media-watch-pod
readinessProbe
failureThreshold10
httpGet
pathhealthz
port8080
schemeHTTP
initialDelaySeconds30
periodSeconds5
successThreshold1
timeoutSeconds3
volumeMounts
mountPath/var/run/secrets/kubernetes.io/serviceaccount
namelive-media-watch-pod-token-fhvk2
readOnlytrue
serviceAccountlive-media-watch-pod
serviceAccountNamelive-media-watch-pod
volumes
namelive-media-watch-pod-token-fhvk2
secret
defaultMode420
secretNamelive-media-watch-pod-token-fhvk2进到pod中查看
3.查看InClusterConfig源码
也是从/var/run/secrets/kubernetes.io/serviceaccount这个路径中获取token

实际上k8s中也有一个默认的serviceAccount:default,同样挂载在pod中的上述路径下,只是这个默认的serviceAccount权限很小,所以才会需要创建自定义的serviceAccount
apiVersionv1
kindPod
metadata
namelive-media-agent-cpu-6kzfc
namespaceops
spec
containers
image**.*.com/ops/live-media-agent202201221010
imagePullPolicyIfNotPresent
namelive-media-agent-cpu
volumeMounts
mountPath/data/config
namevol1
mountPath/var/run/secrets/kubernetes.io/serviceaccount
namedefault-token-5jqzn
readOnlytrue
serviceAccountdefault
serviceAccountNamedefault
volumes
namedefault-token-5jqzn
secret
defaultMode420
secretNamedefault-token-5jqzn










