1 前言
本节介绍如何反序列化 yaml 文件,并将其转换为 K8S Deployment 对象。
备注:有关 GO SDK 安装、GO 项目配置请查看本系列前面的文章,本文不再赘述。
2 序列化与反序列化
1907年3月12日,一个叫斯坦因的英国人来到敦煌,随后的几天里,他通过小恩小惠取得了守护人王道士的信任,并在3月16日进入了千佛洞。
那一天,一个震惊世界的文化奇迹从历史的尘封中露出真貌,这——便是敦煌。
那里曾经风雨西窗,那里曾经衰草斜阳。
斯坦因以极低的价格买走了许多珍贵的文物,其中不乏精美的壁画。因为有些壁画实在过于庞大,为了方便运输,斯坦因竟然“肢解”了它们,尽管这些壁画在到达英国后经过了重新拼装,但却带来了不可估量的艺术损失。
斯坦因将壁画切割成碎片,再从碎片恢复成原样的过程,就是对象的序列化与反序列化过程。
序列化和反序列化的本质是实现对象数据类型转换(比如对象转换成切片),而对象类型转换的目的是方便数据的存储和传输。
3 运行环境
本系列文章使用的环境配置如下(不要求读者完全匹配,可根据自己实际情况酌情处理):
- K8s 版本 : 1.19.0
- Docker 版本:20.10.8
- CentOS 版本:7.7.1908
- Go SDK 版本:go1.16.6 linux/amd64
4 项目代码
进入 GO 项目根目录:
# cd $GOPATH/src
新建 k8s-unmarshal 目录,并在目录下创建 busybox.yaml 文件:
# mkdir k8s-unmarshal
# cd k8s-unmarshal
# touch busybox.yaml
编辑 busybox.yaml,在文件中创建一个 deployment 声明:
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3600" ]
其次创建 main.go 文件:
# touch main.go
编辑 main.go 文件,添加如下代码:
package main
import (
json2 "encoding/json"
"fmt"
"io/ioutil"
v1 "k8s.io/api/apps/v1"
yaml2 "k8s.io/apimachinery/pkg/util/yaml"
)
func main() {
yaml, err := ioutil.ReadFile("./busybox.yaml")
if err != nil {
panic(err)
}
json, err := yaml2.ToJSON(yaml)
if err != nil {
panic(err)
}
deployment := v1.Deployment{}
err = json2.Unmarshal(json, &deployment)
if err != nil {
panic(err)
}
fmt.Println(deployment)
}
5 运行项目
如果想运行成功上面的代码样例,需执行如下两个步骤:
- 创建 go.mod
- 运行 main.go
5.1 创建 go.mod
go mod 在 GO v1.11 版本引入,在 v1.12 版本基本稳定,到 v1.13 版本的时候默认是打开的,可以使用如下命令查看:
[root@k8s-master-1 k8s-unmarsha]# go env | grep -i GO111MODULE
GO111MODULE="on"
执行下列命令创建 go.mod 文件:
[root@k8s-master-1 k8s-unmarsha]# go mod init
go: creating new go.mod: module k8s-unmarsha
go: to add module requirements and sums:
go mod tidy
如果执行结果如上所示,还需要继续执行下面指令(备注,如果指令执行失败,大概率是依赖包下不到,可参考本系列第一篇文章配置好下载包代理):
[root@k8s-master-1 k8s-unmarshal]# go mod tidy
go: finding module for package k8s.io/apimachinery/pkg/util/yaml
go: finding module for package k8s.io/api/apps/v1
go: found k8s.io/api/apps/v1 in k8s.io/api v0.22.2
go: found k8s.io/apimachinery/pkg/util/yaml in k8s.io/apimachinery v0.22.2
执行完毕后, $GOPATH/src/k8s-unmarsha 目录结构如下:
[root@k8s-master-1 k8s-unmarshal]# tree
.
├── busybox.yaml
├── go.mod
├── go.sum
└── main.go
0 directories, 4 files
5.2 运行 main.go
运行 main.go:
[root@k8s-master-1 k8s-unmarshal]# go run main.go
{{Deployment apps/v1} {busybox 0 0001-01-01 00:00:00 +0000 UTC <nil> <nil> map[app:busybox] map[] [] [] []} {0xc000293128 &LabelSelector{MatchLabels:map[string]string{app: busybox,},MatchExpressions:[]LabelSelectorRequirement{},} {{busybox 0 0001-01-01 00:00:00 +0000 UTC <nil> <nil> map[app:busybox] map[] [] [] []} {[] [] [{busybox busybox [/bin/sh -c sleep 3600] [] [] [] [] {map[] map[]} [] [] nil nil nil nil IfNotPresent nil false false false}] [] <nil> <nil> map[] <nil> false false false <nil> nil [] nil [] [] <nil> nil [] <nil> <nil> <nil> map[] [] <nil>}} { nil} 0 <nil> false <nil>} {0 0 0 0 0 0 [] <nil>}}
如果命令输出上述结果则表示程序执行成功。
自此,成功将 yaml 文件反序列化 为 K8S deployment 对象。
5.3 代码解释
下面简单介绍代码逻辑。
5.3.1 读取 yaml 格式文件
下面代码作用是读取当前目录下 busybox.yaml 资源文件,并以字节切片的数据类型保存在变量 yaml 中,如果读取失败直接报错退出。
yaml, err := ioutil.ReadFile("./busybox.yaml")
if err != nil {
panic(err)
}
5.3.2 转换成 json 切片格式
下面代码作用是读取上面生成的 yaml 字节切片,并将其转换为 json 格式的字节切片数据类型。读者如果觉得费解,可以简单理解为单纯的数据类型转换即可。
json, err := yaml2.ToJSON(yaml)
if err != nil {
panic(err)
}
5.3.3 反序列化字节切片
下面代码根据上面创建好的 json 字节切片,再利用 encoding/json 库的 Unmarshal 方法将字节切片类型反序列成 K8S deployment 对象。
deployment := v1.Deployment{}
err = json2.Unmarshal(json, &deployment)
if err != nil {
panic(err)
}
6 总结
本小节介绍了如何将 yaml 文件反序列化为 deployment 对象,下节笔者将会带领读者深入到 K8S 源码,看看 Deployment 对象的内部结构组成。更多精彩,敬请期待。