Get a specific apiVersion manifest from k8s
How to put a manifest with one apiVersion set and get it back with another apiVersion
TL;DR
To get a manifest from k8s in any supported API version you can use an extended
kubectl get
notation likekubectl get deployments.v1beta1.extensions mydeploy -o yaml
Briefly and with examples
Everybody knows how to get a resource manifest from Kubernetes. But do you know that you can put a manifest with one apiVersion
set and get the same resource manifest with another apiVersion
back?
Imagine
You have a
deployment
in a cluster, that usesapi-version extensions/v1beta1
from a git repo.You've updated the cluster (1.15 => 1.16). Old deployment works fine, but you can't deploy nothing new with the old manifest because in k8s 1.16
api-version extensions/v1beta1
is absent.You have two options:
Rewrite it manually or
Get it from the cluster in updated spec format (
apps/v1
)
To get manifest from k8s you can:
below there is an example for v1.15, where extensions/v1beta1 is not removed yet
# from extensions
kubectl get deployments.extensions ext -o yaml
# from extensions, but for v1beta1
kubectl get deployments.v1beta1.extensions ext -o yaml
# from apps
kubectl get deployments.apps ext -o yaml
# from apps, but v1
kubectl get deployments.v1.apps ext -o yaml
Notice that if you do just kubectl get deployments ext -o yaml
, you will get a manifest from extensions/v1beta1
nevertheless you've even applied apps/v1
before. Details here.
Prove it
Start 1.15
minikube start --kubernetes-version=v1.15.12
Make 2 manifests for
deployments
with different versions. Note the absence ofspec.selector
inextensions/v1beta1
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: run: apps name: apps spec: replicas: 1 selector: matchLabels: run: apps template: metadata: creationTimestamp: null labels: run: apps spec: containers: - image: nginx name: apps --- apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: run: ext name: ext spec: replicas: 1 template: metadata: creationTimestamp: null labels: run: ext spec: containers: - image: nginx name: ext
Apply
❯ minikube kubectl -- apply -f . deployment.apps/apps created deployment.extensions/ext created
Check that resources
apps
andext
are inextensions/v1beta1
and inapps/v1
too- The hard way - curl:
❯ minikube kubectl -- proxy
Starting to serve on 127.0.0.1:8001
❯ curl -s 127.0.0.1:8001/apis/extensions/v1beta1/namespaces/default/deployments/apps | yq . --yaml-output
kind: Deployment
apiVersion: extensions/v1beta1
# ...
❯ curl -s 127.0.0.1:8001/apis/extensions/v1beta1/namespaces/default/deployments/ext | yq . --yaml-output
kind: Deployment
apiVersion: extensions/v1beta1
# ...
❯ curl -s 127.0.0.1:8001/apis/apps/v1/namespaces/default/deployments/apps | yq . --yaml-output
kind: Deployment
apiVersion: apps/v1
# ...
❯ curl -s 127.0.0.1:8001/apis/apps/v1/namespaces/default/deployments/ext | yq . --yaml-output
kind: Deployment
apiVersion: apps/v1
# ...
- Or kubectl:
# from extensions
kubectl get deployments.extensions ext -o yaml
# from extensions, but v1beta1
kubectl get deployments.v1beta1.extensions ext -o yaml
# from apps
kubectl get deployments.apps ext -o yaml
# from apps, but v1
kubectl get deployments.v1.apps ext -o yaml
Bonus: kubectl explain
If you do kubectl explain deployment
than (surprise!) you'll get a description for extensions/v1beta1
. Because kubectl explain
works the same way, just like kubectl get
:
If you want a specific version, use an --api-version
flag :
minikube kubectl -- explain deployment.spec --api-version apps/v1
minikube kubectl -- explain deployment.spec --api-version extensions/v1beta1