问题背景
大概是因为 k8s 定义了一些特殊的数据类型,所以 k8s 对象 yaml 序列化时与其它 yaml 包结果不同。
源代码
package main
import (
"log"
"os"
"github.com/ghodss/yaml"
yamlv2 "gopkg.in/yaml.v2"
yamlv3 "k8s.io/apimachinery/pkg/util/yaml"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
func main() {
// 输出重定向到文件
f, err := os.OpenFile("test.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer f.Close()
log.SetOutput(f)
var service *corev1.Service
service = &corev1.Service{
ObjectMeta: v1.ObjectMeta{
Name: "test-service",
Namespace: "default",
Labels: map[string]string{
"app": "test-app",
},
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{
"app": "test-app",
},
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: 8080,
},
},
},
},
}
{
bytes, err := yaml.Marshal(service)
if err != nil {
panic(err)
}
log.Printf("yaml:\n%s\n\n", string(bytes))
var service2 *corev1.Service
err = yaml.Unmarshal(bytes, &service2)
if err != nil {
panic(err)
}
log.Printf("service2: %+v\n\n", service2)
log.Println()
}
{
bytes, err := yamlv2.Marshal(service)
if err != nil {
panic(err)
}
log.Printf("yamlv2:\n%s\n\n", string(bytes))
var service2 *corev1.Service
err = yamlv2.Unmarshal(bytes, &service2)
if err != nil {
panic(err)
}
log.Printf("service2: %+v\n\n", service2)
log.Println()
}
{
bytes3, err := yaml.Marshal(service)
if err != nil {
panic(err)
}
log.Printf("yaml:\n%s", string(bytes3))
var service2 *corev1.Service
err = yamlv3.Unmarshal(bytes3, &service2)
if err != nil {
panic(err)
}
log.Printf("service2: %+v\n\n", service2)
log.Println()
}
}
module tmpGo
go 1.20
require (
github.com/ghodss/yaml v1.0.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.29.1
k8s.io/apimachinery v0.29.1
)
require (
github.com/go-logr/logr v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
输出结果:
2024/01/31 17:10:20 yaml:
metadata:
creationTimestamp: null
labels:
app: test-app
name: test-service
namespace: default
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: test-app
status:
loadBalancer: {}
2024/01/31 17:10:20 service2: &Service{ObjectMeta:{test-service default 0 0001-01-01 00:00:00 +0000 UTC <nil> <nil> map[app:test-app] map[] [] [] []},Spec:ServiceSpec{Ports:[]ServicePort{ServicePort{Name:http,Protocol:,Port:80,TargetPort:{0 8080 },NodePort:0,AppProtocol:nil,},},Selector:map[string]string{app: test-app,},ClusterIP:,Type:,ExternalIPs:[],SessionAffinity:,LoadBalancerIP:,LoadBalancerSourceRanges:[],ExternalName:,ExternalTrafficPolicy:,HealthCheckNodePort:0,PublishNotReadyAddresses:false,SessionAffinityConfig:nil,IPFamilyPolicy:nil,ClusterIPs:[],IPFamilies:[],AllocateLoadBalancerNodePorts:nil,LoadBalancerClass:nil,InternalTrafficPolicy:nil,},Status:ServiceStatus{LoadBalancer:LoadBalancerStatus{Ingress:[]LoadBalancerIngress{},},Conditions:[]Condition{},},}
2024/01/31 17:10:20
2024/01/31 17:10:20 yamlv2:
typemeta:
kind: ""
apiversion: ""
objectmeta:
name: test-service
generatename: ""
namespace: default
selflink: ""
uid: ""
resourceversion: ""
generation: 0
creationtimestamp: "0001-01-01T00:00:00Z"
deletiontimestamp: null
deletiongraceperiodseconds: null
labels:
app: test-app
annotations: {}
ownerreferences: []
finalizers: []
managedfields: []
spec:
ports:
- name: http
protocol: ""
appprotocol: null
port: 80
targetport:
type: 0
intval: 8080
strval: ""
nodeport: 0
selector:
app: test-app
clusterip: ""
clusterips: []
type: ""
externalips: []
sessionaffinity: ""
loadbalancerip: ""
loadbalancersourceranges: []
externalname: ""
externaltrafficpolicy: ""
healthchecknodeport: 0
publishnotreadyaddresses: false
sessionaffinityconfig: null
ipfamilies: []
ipfamilypolicy: null
allocateloadbalancernodeports: null
loadbalancerclass: null
internaltrafficpolicy: null
status:
loadbalancer:
ingress: []
conditions: []
2024/01/31 17:10:20 service2: &Service{ObjectMeta:{test-service default 0 0001-01-01 00:00:00 +0000 UTC <nil> <nil> map[app:test-app] map[] [] [] []},Spec:ServiceSpec{Ports:[]ServicePort{ServicePort{Name:http,Protocol:,Port:80,TargetPort:{0 8080 },NodePort:0,AppProtocol:nil,},},Selector:map[string]string{app: test-app,},ClusterIP:,Type:,ExternalIPs:[],SessionAffinity:,LoadBalancerIP:,LoadBalancerSourceRanges:[],ExternalName:,ExternalTrafficPolicy:,HealthCheckNodePort:0,PublishNotReadyAddresses:false,SessionAffinityConfig:nil,IPFamilyPolicy:nil,ClusterIPs:[],IPFamilies:[],AllocateLoadBalancerNodePorts:nil,LoadBalancerClass:nil,InternalTrafficPolicy:nil,},Status:ServiceStatus{LoadBalancer:LoadBalancerStatus{Ingress:[]LoadBalancerIngress{},},Conditions:[]Condition{},},}
2024/01/31 17:10:20
2024/01/31 17:10:20 yaml:
metadata:
creationTimestamp: null
labels:
app: test-app
name: test-service
namespace: default
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: test-app
status:
loadBalancer: {}
2024/01/31 17:10:20 service2: &Service{ObjectMeta:{test-service default 0 0001-01-01 00:00:00 +0000 UTC <nil> <nil> map[app:test-app] map[] [] [] []},Spec:ServiceSpec{Ports:[]ServicePort{ServicePort{Name:http,Protocol:,Port:80,TargetPort:{0 8080 },NodePort:0,AppProtocol:nil,},},Selector:map[string]string{app: test-app,},ClusterIP:,Type:,ExternalIPs:[],SessionAffinity:,LoadBalancerIP:,LoadBalancerSourceRanges:[],ExternalName:,ExternalTrafficPolicy:,HealthCheckNodePort:0,PublishNotReadyAddresses:false,SessionAffinityConfig:nil,IPFamilyPolicy:nil,ClusterIPs:[],IPFamilies:[],AllocateLoadBalancerNodePorts:nil,LoadBalancerClass:nil,InternalTrafficPolicy:nil,},Status:ServiceStatus{LoadBalancer:LoadBalancerStatus{Ingress:[]LoadBalancerIngress{},},Conditions:[]Condition{},},}
2024/01/31 17:10:20