overexchange
overexchange

Reputation: 1

How does --save-config work with resource definition?

With the below yml file:

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
spec:
  containers:
  - name: my-nginx
    image: nginx:alpine

On running kubectl create -f nginx.pod.yml --save-config, then as per the documentation: If true, the configuration of current object will be saved in its annotation.

Where exactly is this annotation saved? How to view this annotation?

Upvotes: 1

Views: 606

Answers (1)

P....
P....

Reputation: 18401

Below command would print all the annotations present in the pod my-nginx:

kubectl get pod my-nginx  -o jsonpath='{.metadata.annotations}'

Under kubectl.kubernetes.io/last-applied-configuration of the above output, your configuration used is stored.

Here is an example showing the usage:

Original manifest for my deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Created the deployment as follow:

k create  -f x.yml --save-config
deployment.apps/my-deploy created

kubectl get deployments.apps my-deploy   -o jsonpath='{.metadata.annotations.kubectl\.kubernetes\.io\/last-applied-configuration}' |jq .
{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "annotations": {},
    "creationTimestamp": null,
    "labels": {
      "app": "my-deploy"
    },
    "name": "my-deploy",
    "namespace": "default"
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "my-deploy"
      }
    },
    "strategy": {},
    "template": {
      "metadata": {
        "creationTimestamp": null,
        "labels": {
          "app": "my-deploy"
        }
      },
      "spec": {
        "containers": [
          {
            "image": "nginx",
            "name": "nginx",
            "resources": {}
          }
        ]
      }
    }
  },
  "status": {}
}

kubectl get deployments.apps my-deploy   -o jsonpath='{.spec.template.spec.containers[*].image}'
nginx

Now some user came and changed the image on nginx from nginx to httpd, using imperative commands.

k set image deployment/my-deploy nginx=httpd --record
deployment.apps/my-deploy image updated


kubectl get deployments.apps my-deploy   -o jsonpath='{.spec.template.spec.containers[*].image}'
httpd

However, we can check that the last applied declarative configuration is not updated.

kubectl get deployments.apps my-deploy   -o jsonpath='{.metadata.annotations.kubectl\.kubernetes\.io\/last-applied-configuration}' |jq .
{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "annotations": {},
    "creationTimestamp": null,
    "labels": {
      "app": "my-deploy"
    },
    "name": "my-deploy",
    "namespace": "default"
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "my-deploy"
      }
    },
    "strategy": {},
    "template": {
      "metadata": {
        "creationTimestamp": null,
        "labels": {
          "app": "my-deploy"
        }
      },
      "spec": {
        "containers": [
          {
            "image": "nginx",
            "name": "nginx",
            "resources": {}
          }
        ]
      }
    }
  },
  "status": {}
}

Now, change the image name in the original manifest file from nginx to flask, then do kubectl apply(a declarative command)

kubectl apply -f orig.yml
deployment.apps/my-deploy configured
kubectl get deployments.apps my-deploy   -o jsonpath='{.spec.template.spec.containers[*].image}'
flask

Now check the last applied configuration annotation, this would have flask in it. Remember, it was missing when kubectl set image command was used.

kubectl get deployments.apps my-deploy   -o jsonpath='{.metadata.annotations.kubectl\.kubernetes\.io\/last-applied-configuration}' |jq .
{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "annotations": {},
    "creationTimestamp": null,
    "labels": {
      "app": "my-deploy"
    },
    "name": "my-deploy",
    "namespace": "default"
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "my-deploy"
      }
    },
    "strategy": {},
    "template": {
      "metadata": {
        "creationTimestamp": null,
        "labels": {
          "app": "my-deploy"
        }
      },
      "spec": {
        "containers": [
          {
            "image": "flask",
            "name": "nginx",
            "resources": {}
          }
        ]
      }
    }
  },
  "status": {}
}

Where is the "last-applied" annotation saved:

Just like everything else, Its saved in etcd , created the pod using the manifest provided in the question and ran raw etcd command to print the content. (in this dev environment, etcd was not encrypted).

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/ca.crt get /registry/pods/default/my-nginx
/registry/pods/default/my-nginx
k8s

v1Pod⚌
⚌
                                                                                                                                                                   my-nginxdefault"*$a3s4b729-c96a-40f7-8de9-5d5f4ag21gfa2⚌⚌⚌b⚌
0kubectl.kubernetes.io/last-applied-configuration⚌{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"my-nginx","namespace":"default"},"spec":{"containers":[{"image":"nginx:alpine","name":"my-nginx"}]}}

Upvotes: 2

Related Questions