K8s client-go
Contents
client-go 是负责与 Kubernetes APIServer 服务进行交互的客户端库,利用 Client-Go 与 Kubernetes APIServer 进行的交互访问,来对 Kubernetes 中的各类资源对象进行管理操作,包括内置的资源对象及 CRD
client-go 客户端
Client-Go 共提供了 4 种与 Kubernetes APIServer 交互的客户端
- RESTClient:最基础的客户端,主要是对 HTTP 请求进行了封装,支持 Json 和 Protobuf 格式的数据。
- DiscoveryClient:发现客户端,负责发现 APIServer 支持的资源组、资源版本和资源信息的。
- ClientSet:负责操作 Kubernetes 内置的资源对象,例如:Pod、Service等。
- DynamicClient:动态客户端,可以对任意的 Kubernetes 资源对象进行通用操作,包括 CRD。
基本使用
参考 API文档 的 group 和 apiVersion 等信息
创建 admin ServiceAccount
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: admin
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
查看 token
$ kubectl describe sa admin -n kube-system
Name: admin
Namespace: kube-system
Tokens: admin-token-nzxlb
$ kubectl describe secret admin-token-nzxlb -n kube-system
建立连接
先使用反代的方式,在 master 节点执行
$ kubectl proxy --address='0.0.0.0' --accept-hosts='^*$' --port=8009
安装客户端库 (版本要对应 Github),连接 API Server
var K8sClient *kubernetes.Clientset
func init() {
config := &rest.Config{
Host: "ip:8009",
BearerToken: "",
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatalln(err)
}
K8sClient = client
}
示例:获取资源列表
ctx := context.Background()
// 查询 kube-system 命名空间下的 service
svs, _ := K8sClient.CoreV1().Services("kube-system").List(ctx, v1.ListOptions{})
// 查询 kube-system 命名空间下的 deployment
deps, _ := K8sClient.AppsV1().Deployments("kube-system").List(ctx, v1.ListOptions{})
示例:获取资源详情
ctx := context.Background()
// 获取名称为 ngx 的 deployment 资源
dep, _ := K8sClient.AppsV1().Deployments(namespace).Get(ctx, "ngx", metav1.GetOptions{})
dep.Name // 名称
dep.Namespace // 命名空间
dep.Status.Replicas // 副本数量
dep.CreationTimestamp // 创建时间
dep.Spec.Template.Spec.Containers[0].Image // 第一个镜像名称
示例:获取 deployment 的关联 pod
最简单的方式,利用 Deployment 的 MatchLabels 去匹配 pod 的 labels
type PodModel struct {
Name string // pod名称
NodeName string // 节点
Images string // 镜像名称
CreatedAt string // 创建时间
}
// 拼接labels字符串
func GetLabels(labels map[string]string) string {
var labelStr strings.Builder
for k, v := range labels {
if labelStr.Len() != 0 {
labelStr.WriteString(",")
}
labelStr.WriteString(fmt.Sprintf("%s=%s", k, v))
}
return labelStr.String()
}
// 根据deployment获取关联的pods集合
func GetPodsByDep(namespace string, dep *v1.Deployment) (pods []*PodModel) {
ctx := context.Background()
// 通过LabelSelector去匹配对应的pods
listOpt := metav1.ListOptions{
LabelSelector: GetLabels(dep.Spec.Selector.MatchLabels),
}
podList, _ := K8sClient.CoreV1().Pods(namespace).List(ctx, listOpt)
pods = make([]*PodModel, len(podList.Items))
for i, pod := range podList.Items {
pods[i] = &PodModel{
Name: pod.Name,
NodeName: pod.Spec.NodeName,
Images: GetPodImages(pod.Spec.Containers),
CreatedAt: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
}
}
return
}
dep, _ := K8sClient.AppsV1().Deployments(namespace).Get(context.Background(), "ngx", metav1.GetOptions{})
Pods = GetPodsByDep("default", dep)
示例:修改 deployment 副本数量
// 获取 deployment 副本数量
scale, _ := K8sClient.AppsV1().Deployments("default").GetScale(ctx, "ngx", v1.GetOptions{})
// 修改副本数量
scale.Spec.Replicas++
K8sClient.AppsV1().Deployments("default").UpdateScale(ctx, "ngx", scale, v1.UpdateOptions{})
示例:创建资源
根据 yaml 创建一个 nginx deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myngx
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginxtest
image: nginx:1.18-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
ngxDep := &appV1.Deployment{}
// 读取yaml内容
b, _ := os.ReadFile("nginx.yaml")
ngxJson, _ := yaml.ToJSON(b)
json.Unmarshal(ngxJson, ngxDep)
dep, _ := K8sClient.AppsV1().Deployments("default").Create(context.Background(), ngxDep, v1.CreateOptions{})