Pod中使用自定义服务账号调用自定义资源

embedded/2024/10/18 9:16:46/

一、背景

1、从开发角度

(1)服务通过容器化部署的方式运行在云环境的Pod中,然而在 Kubernetes 中,Pod 中的服务不能直接通过 client-go 访问 Kubernetes 资源,而是需要通过 Kubernetes API Server 来进行访问。client-go 库实际上是通过与 Kubernetes API Server 的交互来完成对 Kubernetes 资源的操作。

(2)在使用 client-go 时,通常需要提供 Kubernetes API Server 的地址认证信息(如服务账号的凭证),以及所需的 API 访问权限(通过 RBAC 角色授权)。这些信息将帮助 client-go 库正确地建立与 Kubernetes API Server 的连接,并确保操作的安全性和正确性。

2、从调库角度

(1)在使用 Kubernetes API 客户端——client-go 的过程中,我们通常需要获取 *rest.Config 配置对象来与 Kubernetes API 服务器进行交互。

(2)通常有四种获取 *rest.Config 的方法

  • 使用 kubeconfig 文件

    • kubeconfig 文件是一个 YAML 文件,用于指定 Kubernetes 集群的访问凭证、上下文和集群信息等。

  • 使用 Kubernetes 集群内的 Service Account

    • 在 Kubernetes 中,每个 Namespace 都有一个默认的 Service Account。ServiceAccount仅局限它所在的namespace,每个namespace创建时都会自动创建一个default service account。

    • ServiceAccount是给运行在Pod的程序使用的身份认证,Pod容器的进程需要访问API Server时用的就是ServiceAccount账户。

    • 创建Pod时,如果没有指定Service Account,Pod则会使用default Service Account。

  • 直接指定 API Server 的地址和认证信息

    • 我们可以直接指定 API Server 的地址和认证信息来获取 *rest.Config 对象。直接将api地址和认证token配置到代码中,但实际开发中一般不用。

  • 从环境变量、默认配置文件等多个来源获取配置信息

    • `genericclioptions.NewConfigFlags()` 方法可以从环境变量、命令行参数、默认配置文件等多个来源中获取 Kubernetes 集群的配置信息,并生成对应的 *rest.Config 对象。

二、在pod中调用自定义资源

1、pod绑定服务账号

(1)创建serviceAccount

apiVersion: v1
kind: ServiceAccount
metadata:name: test-sanamespace: test

(2)创建相关的角色/rbac

  • Role 只能用来给某个特定 namespace 中的资源作鉴权,对多 namespace 和集群级的资源或者是非资源类的 API(如 /healthz)使用 ClusterRole

  • ClusterRole用于所有namespace下的资源,例如需要具备操作 CRD(CustomResourceDefinition) 相关权限,CRD 存在于所有 namespace 下

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: my-cluster
rules:- apiGroups: [""]resources: ["nodes"]verbs: ["get","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: my-bind
subjects:- kind: ServiceAccountname: test-sanamespace: test
roleRef:kind: ClusterRolename: my-clusterapiGroup: rbac.authorization.k8s.io

(3)在pod中绑定对应的serviceAccount

  • serviceAccount所需要的证书会被mount到 :  /var/run/secrets/kubernetes.io/serviceaccount

 
apiVersion: v1
kind: Pod
metadata:name: testpodnamespace: testlabels:app: test
spec:containers:- name: appimage: xxxxserviceAccountName: test-sa

(4)client-go 中调用

config,err := rest.InClusterConfig()
if err!=nil {panic(err)
}
client,err := kubernetes.NewForConfig(config)
if err!=nil {panic(err)
}

2、client-go中操作自定义资源

(1)DynamicClient客户端(推荐)

  • DynamicClient客户端是一种动态客户端,可以对任意的Kubernetes资源进行RESTful操作,包括CRD资源。

  • 代码示例

func TestDynamicClient(t *testing.T) {config,err := rest.InClusterConfig()if err!=nil {panic(err)}if err != nil {panic(err)}dynamicClient, err := dynamic.NewForConfig(config)if err != nil {panic(err)}gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}//用于设置请求的资源组,资源版本,资源名称即命名空间;List函数用于获取Pod列表unstructObj, err := dynamicClient.Resource(gvr).Namespace(corev1.NamespaceDefault).List(context.Background(), metav1.ListOptions{Limit: 500})if err != nil {panic(err)}podList := &corev1.PodList{}//通过runtime的函数将unstructured.UnstructuredList转换为PodListerr = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(), podList)if err != nil {panic(err)}for _, d := range podList.Items {fmt.Printf("NAMESPACE:%v \t NAME:%v \t STATU:%v\n", d.Namespace, d.Name, d.Status.Phase)}
}
  • DynamicClient如何操作CRD资源

    • 代码示例:

      • func TestDynamicClient(t *testing.T) {config,err := rest.InClusterConfig()if err!=nil {panic(err)}if err != nil {panic(err)}dynamicClient, err := dynamic.NewForConfig(config)if err != nil {panic(err)}// 定义要操作的 CRD 资源的 Group 和 Versiongroup := "example.com"version := "v1"plural := "foos"// 创建一个自定义资源对象foo := &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": fmt.Sprintf("%s/%s", group, version),"kind":       "Foo","metadata": map[string]interface{}{"name": "example-foo",},"spec": map[string]interface{}{"message": "Hello, CRD!",},},}// 指定要操作的资源的 Group、Version 和 Resourceresource := schema.GroupVersionResource{Group: group, Version: version, Resource: plural}// 创建 Foo 资源created, err := dynamicClient.Resource(resource).Namespace("default").Create(context.TODO(), foo, metav1.CreateOptions{})if err != nil {fmt.Printf("Error creating foo: %s\n", err.Error())panic(err)}fmt.Printf("Created foo: %v\n", created)
        }

(2)Typed Clients客户端

  • 它们是针对 Kubernetes API 中定义的具体资源类型的客户端,如 Pods、Services 等。这些客户端通常是类型安全的,可以享受静态类型语言的一些好处。

  • 代码示例

func TestTypedClient(t *testing.T) {config,err := rest.InClusterConfig()if err!=nil {panic(err)}if err != nil {panic(err)}client, err := kubernetes.NewForConfig(config)if err != nil {panic(err)}namespace := "myns"deploy,err := client.AppsV1().Deployments(namespace).Get("test",metav1.GetOptions{})if err != nil {panic(err)}
}
  • CRD 如何使用 Typed Client

    • 对于 CRD,如果想通过 Client-Go Typed Client 的方式来操作的话,那么第一步,是得我们先定义 CRD 的 Go 数据结构

    • 通过 Kubernetes 的官方工具:Code Generator 来生成可以直接使用的 ClientSet(可以以 Typed Client 和 API Server 交互的 Client) 

    • 参考

      • Kubernetes CRD 系列(三):Client-Go 的使用_client-go gvk创建资源-CSDN博客

      • Extend the Kubernetes API with CustomResourceDefinition

      • CRDs and Custom Kubernetes Controllers in Rancher 2.0

      • How to generate client codes for Kubernetes Custom Resource Definitions (CRD)


http://www.ppmy.cn/embedded/48581.html

相关文章

数据结构——队列(Queue)详解

1.队列(Queue) 1.1概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的性质 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出…

SQL 窗口函数

1.窗口函数之排序函数 RANK, DENSE_RANK, ROW_NUMBER RANK函数 计算排序时,如果存在相同位次的记录,则会跳过之后的位次 有 3 条记录排在第 1 位时: 1 位、1 位、1 位、4 位…DENSE_RANK函数 同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次 有 3 条记录排在…

Prometheus+Grafana监控MySQL

一、准备 grafana服务器:192.168.48.136Prometheus服务器:192.168.48.136被监控服务器:192.168.48.134、192.168.48.135查看时间是否同步 二、安装prometheus server 【2.1】安装 # 解压安装包 tar -zxvf prometheus-2.52.0.linux-amd64.t…

数据结构--第八章--图

一、图 邻接矩阵缺点:浪费空间,浪费时间 二、生成树和最小生成树 普里姆算法—prim 生成树不唯一,权值最小的树称为最小生成树 任何一个带权无向连通图的最小生成树有可能不唯一 2.克鲁斯卡尔算法—Kruskal 稠密图G的最小生成树—prim算法…

Leetcode498. 对角线遍历

Every day a Leetcode 题目来源:498. 对角线遍历 解法1:模拟 根据题目要求,矩阵按照对角线进行遍历。设矩阵的行数为 m,矩阵的列数为 n,我们仔细观察对角线遍历的规律可以得到如下信息: 一共有 mn−1 条…

Shell编程之免交互

一、Here Document免交互 1.1 Here Document概述 使用I/O重定向的方式将命令列表提供给交互式程序或命令,比如ftp、passwd、sudo、ssh、cat或read命令。 是标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直…

编程猫少儿编程:探索其独特的学习路径与教学方法

编程猫少儿编程:探索其独特的学习路径与教学方法 在数字化浪潮席卷而来的今天,编程已成为一项重要的技能。对于孩子们来说,早期接触并学习编程,不仅能够培养他们的逻辑思维和解决问题的能力,还能为未来的职业发展打下…

Day23:LeedCode 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树

669. 修剪二叉搜索树 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代…