将YAML格式的Kubernetes清单反序列化为Go语言对象
以下本文将介绍如何将YAML格式的Kubernetes清单加载并反序列化为具有相应类型的Go语言对象。
通过使用 k8s.io/apimachinery 模块提供的 yaml 包的功能,可以实现这一点。
实施示例和解释
以下是一个例子,它读取以YAML格式编写的Pod清单文件,并将其反序列化为具有core/v1 Pod类型的对象,然后使用client-go从Go语言对象创建Kubernetes Pod对象。在这个例子中创建的Pod有以下两种类型。
-
- 具有原始清单字段值的Pod
- 更改了Pod名称的新Pod
package main
import (
"context"
"flag"
"fmt"
"os"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/clientcmd"
)
var kubeconfig string
func main() {
// YAMLマニフェストの読み込み
path := "sample_pod.yaml"
data, err := os.ReadFile(path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// シリアライザの作成
jsonSerializer := json.NewSerializerWithOptions(
json.SimpleMetaFactory{},
nil,
scheme.Scheme,
json.SerializerOptions{},
)
yamlSerializer := yaml.NewDecodingSerializer(jsonSerializer)
// 読み込んだYAMLマニフェストのバイト列をcorev1.Pod型のオブジェクトにデシリアライズ
var original corev1.Pod
if _, _, err := yamlSerializer.Decode(data, nil, &original); err != nil {
fmt.Println(err)
os.Exit(1)
}
// Podを作成するクライアントの作成
flag.StringVar(&kubeconfig, "kubeconfig", "", "kubeconfig path")
flag.Parse()
config, _ := clientcmd.BuildConfigFromFlags("", kubeconfig)
clientset, _ := kubernetes.NewForConfig(config)
// オブジェクトからsample-original Podを作成
_, err = clientset.CoreV1().Pods("default").Create(context.TODO(), &original, metav1.CreateOptions{})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// sample-originalオブジェクトのPod名を変更した新規オブジェクトを作成
updated := original.DeepCopy()
updated.ObjectMeta.Name = "sample-updated"
// Pod名を変更した新規オブジェクトからsample-original Podを作成
_, err = clientset.CoreV1().Pods("default").Create(context.TODO(), updated, metav1.CreateOptions{})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
读取的YAML清单目标如下。
apiVersion: v1
kind: Pod
metadata:
name: original-sample
namespace: default
spec:
containers:
- name: sleep-container
image: alpine
command: ["sleep", "3600"]
以下是对deserialize.go的实现进行说明。
[]字节 → 对corev1.Pod的反序列化
将字节列(byte列)反序列化为corev1.Pod类型的对象是在yamlSerializer对象的Decode方法中完成的。
yamlSerializer对象的Decode方法会将接收到的YAML转换为JSON,并调用apimachinery/pkg/runtime/serializer/json包中Serializer类型的Decode方法。
如果对Decode的具体实现感兴趣,可以参考k8s.io/apimachinery/pkg/runtime/serializer/json包中的Decode方法。
调用yaml.NewDecodingSerializer函数来初始化yamlSerializer,并将jsonSerializer作为参数传递。
而在初始化jsonSerializer时,调用了k8s.io/apimachinery/pkg/runtime/serializer/json包中的NewSerializerWithOptions函数。
该函数的实现如下所示。
// NewSerializerWithOptions creates a JSON/YAML serializer that handles encoding versioned objects into the proper JSON/YAML
// form. If typer is not nil, the object has the group, version, and kind fields set. Options are copied into the Serializer
// and are immutable.
func NewSerializerWithOptions(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, options SerializerOptions) *Serializer {
return &Serializer{
meta: meta,
creater: creater,
typer: typer,
options: options,
identifier: identifier(options),
}
}
只需要一种选项:
如函数文档所述,通过在第三个typer参数中传递非nil值,创建的对象将具有Group-Version-Kind字段。
在这里,我们指定了要反序列化的资源的scheme。
在deserialize.go中,我们使用了k8s.io/client-go/kubernetes/scheme包中的Scheme变量,并传递了具有corev1.Pod类型的scheme。
方案变量具有k8s.io/apimachinery/pkg/runtime/scheme包中的Scheme类型,而此类型满足NewSerializerWithOptions函数的typer参数应具备的runtime.ObjectTyper接口。
这段是关于将YAML格式的Kubernetes清单转换为corev1.Pod对象的部分的说明。
从Go对象创建Kubernetes对象。
在deserialize.go文件中,从创建客户端以后的处理中,我们使用client-go库从配置文件中创建的对象来创建Kubernetes的Pod对象。
并且我们还根据从配置文件中创建的对象创建了其他对象,并通过修改部分字段的值来创建与原始配置文件不同的Kubernetes的Pod对象。
请参考以下有关client-go的内容,该节涉及client-go、api和apimachinery的功能和关系。
请问您需要将”实行结果”翻译成中文吗?
在deserialize.go的执行结果中,我们可以看到预期创建了Kubernetes Pod对象。
go run deserialize.go --kubeconfig $HOME/.kube/config
k get po
NAME READY STATUS RESTARTS AGE
sample-original 1/1 Running 0 47m
sample-updated 1/1 Running 0 47m
总结
本文介绍了如何使用yaml包提供的功能,通过以下步骤将YAML格式的Kubernetes清单加载并反序列化为具有相应类型的Go语言对象。
翻译结果:
通过使用k8s.io/apimachinery模块提供的yaml包的功能,我们可以实现以下步骤来加载并反序列化YAML格式的Kubernetes清单为具备相应类型的Go语言对象。
-
- 准备具有反序列化类型信息的方案。
-
- 使用准备好的方案创建jsonSerializer。
-
- 从创建好的jsonSerializer创建yamlSerializer。
- 在yamlSerializer的Decode方法中,指定YAML清单的字节序列和反序列化目标对象的指针进行执行。
由于输入是字节序列,因此在反序列化请求的主体时,不仅限于清单文件,可能会出现许多情况。
请提供更多的上下文以便我能够正确地为您提供答案。
- Kubernetes Programming with Go