You can move a Rancher namespace between projects, but it’s not a direct drag-and-drop operation. Rancher doesn’t have a built-in UI feature for this because namespaces are fundamentally tied to the Kubernetes cluster they reside in, and projects are a Rancher-specific organizational construct within a cluster.
Let’s see how this plays out in practice. Imagine you have a namespace dev-app-1 in a project called Development within your dev cluster. You decide it needs to move to a new project, Staging-Apps, also within the dev cluster.
Here’s a typical scenario:
# rancher-project-dev.yaml
apiVersion: management.cattle.io/v3
kind: Project
metadata:
name: Development
namespace: kube-system # This is the cluster where the project lives
labels:
cattle.io/creator: user:user-xxxx
spec:
containerDefaultResourceLimit: {}
containerDefaultResourceQuota: {}
containerResourceQuota: {}
resourceQuota: {}
clusterId: c-xxxxx:p-xxxxx # This is the cluster ID
# rancher-project-staging.yaml
apiVersion: management.cattle.io/v3
kind: Project
metadata:
name: Staging-Apps
namespace: kube-system
labels:
cattle.io/creator: user:user-xxxx
spec:
containerDefaultResourceLimit: {}
containerDefaultResourceQuota: {}
containerResourceQuota: {}
resourceQuota: {}
clusterId: c-xxxxx:p-xxxxx
And your namespace:
# kubectl get ns dev-app-1 -o yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev-app-1
uid: d6a3b0c1-2d3e-4f5a-6b7c-8d9e0f1a2b3c
creationTimestamp: "2023-10-27T10:00:00Z"
labels:
field.cattle.io/projectId: c-xxxxx:p-xxxxx # This links it to the 'Development' project
The key to moving a namespace is understanding that Rancher projects are essentially metadata attached to a Kubernetes namespace, specifically the field.cattle.io/projectId label. To move the namespace, you need to change this label to point to the new project’s ID.
The Process: Re-labeling the Namespace
-
Identify the Target Project ID: First, you need the unique Rancher Project ID for your target project (
Staging-Appsin our example). You can find this by looking at theclusterIdfield in the project’s YAML definition (as shown above) or by navigating to the project in the Rancher UI and inspecting the URL. It will look something likec-xxxxx:p-yyyyy. Let’s assume the ID forStaging-Appsisc-xxxxx:p-zzzzz. -
Update the Namespace Label: Use
kubectlto edit the labels of your namespace. You’ll remove the oldfield.cattle.io/projectIdlabel and add the new one.kubectl label namespace dev-app-1 field.cattle.io/projectId=c-xxxxx:p-zzzzz --overwriteThe
--overwriteflag is crucial here because the label already exists. This command directly modifies the Kubernetes object, and Rancher’s UI will reflect this change shortly after. -
Verification: After running the command, you can verify the change:
kubectl get namespace dev-app-1 -o yaml | grep projectIdYou should see:
field.cattle.io/projectId: c-xxxxx:p-zzzzzIn the Rancher UI, if you refresh the
Staging-Appsproject, you should now seedev-app-1listed under its namespaces. TheDevelopmentproject will no longer show it.
This approach works because Rancher projects are a layer of abstraction on top of Kubernetes. They don’t create new Kubernetes resources for projects themselves; instead, they use labels on existing Kubernetes namespaces to associate them with a project. By changing the label, you’re effectively telling Rancher, "This namespace now belongs to this project."
The most surprising true thing about this process is how simple it is at the Kubernetes level, despite Rancher’s UI presenting projects as distinct containers. It’s a testament to how Rancher leverages Kubernetes’ native labeling system for its organizational features.
The next concept you’ll likely encounter is managing resource quotas and network policies that are often project-specific, and how these translate to the namespaces once they’ve been moved.