How do I copy all resources to a new namespace?

11/24/2020

I would like to create a new namespace which is identical to the old one.

My approach would look something like this (full command below):

kubectl get <resources> -o json --namespace OLD-NAMESPACE | jq '.items[].metadata.namespace = "NEW-NAMESPACE"' | kubectl create -f  -

This basically gets all resource definitions in a json format, replaces the old namespace with the new one, and applies everything.

Unfortunately, this does not work, since the old definitions contain namespace specific things. To avoid this, there used to be an --export flag, which has been deprecated see here.

Any Idea how I could do this?

Full command:

kubectl get bindings,configmaps,endpoints,limitranges,persistentvolumeclaims,persistentvolumes,pods,podtemplates,replicationcontrollers,resourcequotas,secrets,mutatingwebhookconfigurations,validatingwebhookconfigurations,controllerrevisions,daemonsets,deployments,replicasets,statefulsets,tokenreviews,localsubjectaccessreviews,selfsubjectaccessreviews,selfsubjectrulesreviews,subjectaccessreviews,horizontalpodautoscalers,cronjobs,jobs,certificatesigningrequests,leases,endpointslices,events,ingressclasses,networkpolicies,runtimeclasses,poddisruptionbudgets,rolebindings,roles,debugattachments,csidrivers,volumeattachments -o json --namespace OLD-NAMESPACE | jq '.items[].metadata.namespace = "NEW-NAMESPACE"' | kubectl create -f  -
-- User12547645
kubernetes
migration
namespaces

2 Answers

11/24/2020

you can try this

kubectl get all -n OLD_NAMESPACE -o yaml | sed -e 's/namespace: OLD_NAMESPACE/namespace:  NEW_NAMESPACE/' | kubectl apply -f -

this will work

if you are using a higher K8s version above 1.14 sed will work to replace the namespaces

if kubectl get all not adding all resources we can apply like

kubectl get bindings,configmaps,endpoints,limitranges,persistentvolumeclaims,persistentvolumes,pods,podtemplates,replicationcontrollers,resourcequotas,secrets,mutatingwebhookconfigurations,validatingwebhookconfigurations,controllerrevisions,daemonsets,deployments,replicasets,statefulsets,tokenreviews,localsubjectaccessreviews,selfsubjectaccessreviews,selfsubjectrulesreviews,subjectaccessreviews,horizontalpodautoscalers,cronjobs,jobs,certificatesigningrequests,leases,endpointslices,events,ingressclasses,networkpolicies,runtimeclasses,poddisruptionbudgets,rolebindings,roles,debugattachments,csidrivers,volumeattachments -n OLD_NAMESPACE -o yaml | sed -e 's/namespace: OLD_NAMESPACE/namespace:  NEW_NAMESPACE/' | kubectl apply -f -
-- Harsh Manvar
Source: StackOverflow

11/24/2020

For now there is no any established way to solve your task.
There are some common approaches you could try.
Also see discussion here.


If a resource is created by kubectl apply then applied yaml will be saved in a special annotation.
kubectl.kubernetes.io/last-applied-configuration
You could retrieve it like this:

kubectl get deploy example -o json | \
jq -r '.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration"' | jq .

Note that kubectl create and kubectl replace do NOT retain this annotation.
See more examples here.
Also keep in mind how this approach works with object updates.


Alternatively you could resort to direct json / yaml processing.

kubectl get deploy example -ojson | \ice 
jq 'del(.metadata.creationTimestamp, .metadata.managedFields, \
  .metadata.namespace, .metadata.ownerReferences, \
  .metadata.resourceVersion, .metadata.selfLink, \
  .metadata.uid, .status)'

Make sure that you delete all service fields (for example, Helm adds a lot of stuff).


Most probably kubectl get all won't work for you. First it actually does not show all resources.
Here are the rules for expanding all alias.

 - No cluster scoped resources
 - No namespace admin level resources (limits, quota, policy, authorization rules)
 - No resources that are potentially unrecoverable (secrets and pvc)
 - Resources that are considered "similar" to #3 should be grouped the same (configmaps)

Confusingly, this information seems to have been deleted from kubernetes docs and exists only in archived copies, but it's still relevant.

Besides that kubectl get all will return you both Pods and deployment controllers (like Deployments or StatefulSets) which is not what you want, as in most times you don't want to create you pods explicitly.

-- Olesya Bolobova
Source: StackOverflow