kubectl 获取资源yaml

# 获取deployment web3 的资源yaml
$ kubectl get deployment web3 -o yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2022-10-15T06:50:31Z"
  generation: 37
  name: web3
  namespace: default
  resourceVersion: "1165211"
  uid: d8e51b61-27a3-4ec6-a05c-f95f16eb7039
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: web3
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web3
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      - command:
        - sh
        - -c
        - sleep 10000
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        name: busy
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2022-10-15T06:50:31Z"
    lastUpdateTime: "2022-10-15T06:50:33Z"
    message: ReplicaSet "web3-698d69754" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  - lastTransitionTime: "2022-11-11T07:47:51Z"
    lastUpdateTime: "2022-11-11T07:47:51Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 37
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

Go 获取资源yaml

这里先直接将获取到的deployment 转成yaml

package main

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
	"sigs.k8s.io/yaml"
)

func main() {
	configpath := "etc/kube.conf"
	config, err := clientcmd.BuildConfigFromFlags("", configpath)
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}
	dep, err := clientset.AppsV1().Deployments("default").Get(context.Background(), "web5", metav1.GetOptions{})
	if err != nil {
		log.Fatal(err)
	}

	// 将deployment 对象解析为yaml,返回[]byte 和err错误信息
	y, err := yaml.Marshal(dep)
	if err != nil {
		log.Fatal(err)
	}
    //将[]byte 转成字符串
	fmt.Println(string(y))
}

输出yaml,可以发现少了apiVersion: apps/v1、kind: Deployment,多了managedFields: 下面那一堆内容

managedFields【ManagedFieldsEntry array】:这主要用于内部管理,用户通常不需要设置或理解此字段。

metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2022-10-16T12:22:46Z"
  generation: 1
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:progressDeadlineSeconds: {}
        f:replicas: {}
        f:revisionHistoryLimit: {}
        f:selector: {}
        f:strategy:
          f:rollingUpdate:
            .: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
          f:type: {}
        f:template:
          f:metadata:
            f:labels:
              .: {}
              f:app: {}
          f:spec:
            f:containers:
              k:{"name":"busy"}:
                .: {}
                f:command: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
              k:{"name":"nginx"}:
                .: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":80,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:protocol: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: createDpl
    operation: Update
    time: "2022-10-16T12:22:46Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:deployment.kubernetes.io/revision: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:updatedReplicas: {}
    manager: kube-controller-manager
    operation: Update
    subresource: status
    time: "2022-11-11T07:47:43Z"
  name: web5
  namespace: default
  resourceVersion: "1165192"
  uid: 10873d0b-e863-45f6-8320-816dd7340f86
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: web5
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web5
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      - command:
        - sh
        - -c
        - sleep 10000
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        name: busy
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2022-10-16T12:22:46Z"
    lastUpdateTime: "2022-10-16T12:22:47Z"
    message: ReplicaSet "web5-5f5cc4bd84" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  - lastTransitionTime: "2022-11-11T07:47:43Z"
    lastUpdateTime: "2022-11-11T07:47:43Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

获取和kubectl 输出一样的yaml

Deployment

上面输出开头缺少的可以通过GetObjectKind().SetGroupVersionKind来设置

package main

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
	"sigs.k8s.io/yaml"
)

func main() {
	configpath := "etc/kube.conf"
	config, err := clientcmd.BuildConfigFromFlags("", configpath)
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}
	dep, err := clientset.AppsV1().Deployments("default").Get(context.Background(), "web5", metav1.GetOptions{})
	if err != nil {
		log.Fatal(err)
	}
    //设置Group、Version、Kind
	dep.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
		Group:   "apps",
		Version: "v1",
		Kind:    "Deployment",
	})
    //ManagedFields 字段里面的的内容我们不需要
	dep.ManagedFields = []metav1.ManagedFieldsEntry{}
	y, err := yaml.Marshal(dep)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(y))
}

输出

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2022-10-16T12:22:46Z"
  generation: 1
  name: web5
  namespace: default
  resourceVersion: "1165192"
  uid: 10873d0b-e863-45f6-8320-816dd7340f86
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: web5
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web5
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      - command:
        - sh
        - -c
        - sleep 10000
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        name: busy
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2022-10-16T12:22:46Z"
    lastUpdateTime: "2022-10-16T12:22:47Z"
    message: ReplicaSet "web5-5f5cc4bd84" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  - lastTransitionTime: "2022-11-11T07:47:43Z"
    lastUpdateTime: "2022-11-11T07:47:43Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

pod

资源Group 版本可以通过kubectl api-resources来查看

package main

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
	"sigs.k8s.io/yaml"
)

func main() {
	configpath := "etc/kube.conf"
	config, err := clientcmd.BuildConfigFromFlags("", configpath)
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}


	pod, err := clientset.CoreV1().Pods("default").Get(context.Background(), "nginx2", metav1.GetOptions{})
	if err != nil {
		log.Fatal(err)
	}

	pod.ManagedFields = []metav1.ManagedFieldsEntry{}
	pod.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
   		Kind:    "Pod",
		Version: "v1",
	})

	y, err := yaml.Marshal(pod)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(y))
}

输出

apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/containerID: 75fcba1d6395886df8eae80a22cf1d61ad28dea108315c429d7176f4ed131970
    cni.projectcalico.org/podIP: 10.244.135.8/32
    cni.projectcalico.org/podIPs: 10.244.135.8/32
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx2","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.19.9","name":"nginx","ports":[{"containerPort":80}]}]}}
  creationTimestamp: "2022-11-09T14:05:38Z"
  name: nginx2
  namespace: default
  resourceVersion: "969866"
  uid: 1360fc10-821d-4784-bbe6-cda292b52803
spec:
  containers:
  - image: nginx:1.19.9
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-ptkc4
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: node3
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-ptkc4
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-11-09T14:05:38Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2022-11-09T14:06:30Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2022-11-09T14:06:30Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2022-11-09T14:05:38Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://11f72e146858e73329341e812f7b428518d31019de6ffa2e830395a8b55de17e
    image: nginx:1.19.9
    imageID: docker-pullable://nginx@sha256:6b5f5eec0ac03442f3b186d552ce895dce2a54be6cb834358040404a242fd476
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-11-09T14:06:30Z"
  hostIP: 192.168.4.14
  phase: Running
  podIP: 10.244.135.8
  podIPs:
  - ip: 10.244.135.8
  qosClass: BestEffort
  startTime: "2022-11-09T14:05:38Z"