K8S中为什么需要Unstructured对象

2024-08-23 20:58

本文主要是介绍K8S中为什么需要Unstructured对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

熟悉client-go的同学都知道,不止有DeploymentPod这些结构化对象,也提供了unstructured.Unstructured对象,那么为什么需要非结构对象?

Structured vs Unstructured

结构化对象是指可以用Go Struct表示的对象,比如Deployment在k8s.io/api/apps/v1定义

type Deployment struct {metav1.TypeMeta `json:",inline"`// Standard object's metadata.// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata// +optionalmetav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`...
}

我们可以直接通过appsv1.Deployment来安全地定义Deployment的各个字段,通常创建过程如下:

clientset, err := kubernetes.NewForConfig(config)deployment := &appsv1.Deployment{}
deployment.Name = "example"
deployment.Spec = appsv1.DeploymentSpec{...
}clientset.AppsV1().Deployments(apiv1.NamespaceDefault).Create(deployment)

而对于Unstructured定义在k8s.io/apimachinery/pkg/apis/meta/v1/unstructured

type Unstructured struct {// Object is a JSON compatible map with string, float, int, bool, []interface{}, or// map[string]interface{}// children.Object map[string]interface{}
}

通过定义map[string]interface{}可以来表示任意的JSON/YAML对象,而不需要引用Go Struct。可以通过Dynamic client来创建非结构化对象,以下是使用Unstructured创建Deployment的样例。

client, _ := dynamic.NewForConfig(config)
deploymentRes := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}deployment := &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": "apps/v1","kind":       "Deployment","metadata": map[string]interface{}{"name": "demo-deployment",},"spec": map[string]interface{}{"replicas": 2,...}}
}client.Resource(deploymentRes).Namespace(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})

Why

那么什么情况下需要使用到Unstructured对象呢,结构化对象有着安全地类型校验,通过clientset可以方便地增删改查。而非结构化对象只能手动设置GVR、通过map[string]interface{}设置各个字段。

假想你作为一个Paas平台的开发者,需要为每个用户传入的YAML/JSON资源添加label,比如添加user信息creator=xxx。如果用户只能创建Deployment,那么我们可以将资源解析成appsv1.Deployment{}对象,再添加label。但是通常会传入多种资源,不仅有内置的DeploymentService等,也可能会包含自定义资源。由于不确定资源类型,我们只能通过Unstructured对象来解析。

const manifest = `
apiVersion: apps/v1
kind: Deployment
metadata:name: example
spec:...
`
// convert yaml to unstructured
obj := &unstructured.Unstructured{}
dec := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
dec.Decode([]byte(manifest), nil, obj)// add label
labels := obj.GetLabels()
labels["creator"]="userxxx"// set label
obj.SetLabels(labels)dynamicClient.Resource().Namespace(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})

当实现对多种资源的通用处理(上面的示例),或者运行时才能确定的对象(例如根据配置监听不同对象),又或者不愿引入额外的依赖(处理大量的CRD),可以使用Unstructured对象来处理以上情况。

How

不管是结构化对象还是非结构化,最终会调用k8s的Rest API,例如Create Deployment

POST /apis/apps/v1/namespaces/{namespace}/deployments/{name}

K8s中GVR(GroupVersionResource)可以唯一表征资源对象,用来组成Rest API, 如上Group为apps、Version为v1、Resource是deploymentsGVK(GroupVersionKind)可以来标识类型(如Deployment)。Resource与Kind的对应关系可以通过kubectl api-resources查看。

~ kubectl api-resources --api-group apps
NAME                  SHORTNAMES   APIVERSION   NAMESPACED   KIND
controllerrevisions                apps/v1      true         ControllerRevision
daemonsets            ds           apps/v1      true         DaemonSet
deployments           deploy       apps/v1      true         Deployment
replicasets           rs           apps/v1      true         ReplicaSet
statefulsets          sts          apps/v1      true         StatefulSet

对于结构化对象,使用clientset可以获取到GVR,最后调用restClient组成到Rest API

clientset.AppsV1().Deployments(namespace).Create(deployment)// Create takes the representation of a deployment and creates it.  Returns the server's representation of the deployment, and an error, if there is any.
func (c *deployments) Create(ctx context.Context, deployment *v1.Deployment, opts metav1.CreateOptions) (result *v1.Deployment, err error) {result = &v1.Deployment{}err = c.client.Post().Namespace(c.ns).Resource("deployments"). // Resource设置VersionedParams(&opts, scheme.ParameterCodec).Body(deployment).Do(ctx).Into(result)return
}

对于非结构化对象,需要用户手动填充GVR,如果只知道GVK可以通过restMapping获取

deploymentRes := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}dynamicClient.Resource().Namespace(namespace).Create()// Create具体实现
func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Unstructured, opts metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)name := ""if len(subresources) > 0 {accessor, err := meta.Accessor(obj)name = accessor.GetName()}// 调用restClientresult := c.client.client.Post().AbsPath(append(c.makeURLSegments(name), subresources...)...).Body(outBytes).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx)// ...
}

总结

本文描述Unstructured对象在K8s中的使用场景、使用方式,与Structured对象的对比,以及相关代码解析。

引用

  • https://kubernetes.io/zh/docs/reference/using-api/api-concepts/

这篇关于K8S中为什么需要Unstructured对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100476

相关文章

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

PHP7扩展开发之对象方式使用lib库

前言 上一篇文章,我们使用的是函数方式调用lib库。这篇文章我们将使用对象的方式调用lib库。调用代码如下: <?php $hello = new hello(); $result = $hello->get(); var_dump($result); ?> 我们将在扩展中实现hello类。hello类中将依赖lib库。 代码 基础代码 这个扩展,我们将在say扩展上增加相关代码。sa

云原生之高性能web服务器学习(持续更新中)

高性能web服务器 1 Web服务器的基础介绍1.1 Web服务介绍1.1.1 Apache介绍1.1.2 Nginx-高性能的 Web 服务端 2 Nginx架构与安装2.1 Nginx概述2.1.1 Nginx 功能介绍2.1.2 基础特性2.1.3 Web 服务相关的功能 2.2 Nginx 架构和进程2.2.1 架构2.2.2 Ngnix进程结构 2.3 Nginx 模块介绍2.4