Skip to main content
Version: v1.0.0-rc.1 (pre-release)

Controlplane Namespace Management

You can create multiple namespaces in OpenChoreo controlplane to group resources and keep them isolated in the controlplane cluster.

After creating a new namespace in OpenChoreo controlplane, cluster-scoped default resources (ClusterComponentType, ClusterTrait, ClusterWorkflow, ClusterDataPlane, ClusterWorkflowPlane) are automatically visible without any additional setup. You only need to create namespace-scoped Environments, a DeploymentPipeline, and a Project.

If you need physical isolation, you can create namespace-scoped variants (ComponentType, Trait, DataPlane, etc.) that override the cluster-scoped defaults within that namespace.

Overview​

OpenChoreo supports multiple namespaces, where each namespace serves as an isolated environment for projects, components, and related resources. Cluster-scoped platform resources are shared across all namespaces by default, so new namespaces only need a few namespace-scoped resources (Environments, DeploymentPipeline, Project) before developers can start deploying.

For a deeper understanding of OpenChoreo resources and their relationships, see the Concepts documentation.

Prerequisites​

Before starting, ensure you have:

  1. kubectl configured with access to your cluster(s)
  2. Cluster admin or namespace admin permissions

Set Environment Variables​

Set these environment variables to simplify the commands throughout this guide:

# Required: Your new namespace name
export NAMESPACE_NAME="<your-namespace-name>"

# Optional: Name for a namespace-scoped DataPlane (only used in the isolation section below)
export DATAPLANE_NAME="<your-dataplane-name>"

# Optional: Context names if working with multiple clusters
export CONTROL_PLANE_CONTEXT="<your-control-plane-context>"
export DATA_PLANE_CONTEXT="<your-data-plane-context>"
export WORKFLOW_PLANE_CONTEXT="<your-workflow-plane-context>"

Namespace Creation​

To create a namespace, run:

kubectl create namespace $NAMESPACE_NAME
kubectl label namespace $NAMESPACE_NAME openchoreo.dev/control-plane=true

Namespace Configuration​

Mandatory Resources​

1. Environments (At least 1)​

Environments represent deployment targets (e.g., development, staging, production). Each environment references a DataPlane or ClusterDataPlane. If you followed the getting-started guides, a ClusterDataPlane named default is already available cluster-wide.

Create environments manually

kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: Environment
metadata:
annotations:
openchoreo.dev/description: Development
openchoreo.dev/display-name: Development
labels:
openchoreo.dev/name: development
name: development
namespace: $NAMESPACE_NAME
spec:
dataPlaneRef:
kind: ClusterDataPlane
name: default
isProduction: false
EOF

Create environments from samples

You can create multiple environments for a complete deployment pipeline. You can use samples with namespace and dataplane modifications.

# QA Environment
kubectl apply -f <(curl -s https://raw.githubusercontent.com/openchoreo/openchoreo/refs/heads/main/samples/platform-config/new-environments/qa-environment.yaml | yq eval ".metadata.namespace = \"$NAMESPACE_NAME\"" -)

# Pre-production Environment
kubectl apply -f <(curl -s https://raw.githubusercontent.com/openchoreo/openchoreo/refs/heads/main/samples/platform-config/new-environments/pre-production-environment.yaml | yq eval ".metadata.namespace = \"$NAMESPACE_NAME\"" -)

# Production Environment
kubectl apply -f <(curl -s https://raw.githubusercontent.com/openchoreo/openchoreo/refs/heads/main/samples/platform-config/new-environments/production-environment.yaml | yq eval ".metadata.namespace = \"$NAMESPACE_NAME\"" -)

Verification:

kubectl get environment -n $NAMESPACE_NAME

2. Deployment Pipeline (At least 1)​

A DeploymentPipeline defines the promotion path for releases across environments (e.g., dev β†’ qa β†’ pre-production β†’ production).

Note: The following pipeline assumes an environment: development is already created on the namespace. If you want to create the development environment, run:

# Development Environment
kubectl apply -f <(curl -s https://raw.githubusercontent.com/openchoreo/openchoreo/refs/heads/main/samples/platform-config/new-environments/development-environment.yaml | yq eval ".metadata.namespace = \"$NAMESPACE_NAME\"" -)

Create a deployment pipeline:

kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: DeploymentPipeline
metadata:
name: default
namespace: $NAMESPACE_NAME
annotations:
openchoreo.dev/display-name: "Default Pipeline"
openchoreo.dev/description: "Standard deployment pipeline with dev, qa, pre-production, and production environments"
labels:
openchoreo.dev/name: default
spec:
promotionPaths:
- sourceEnvironmentRef:
name: development
targetEnvironmentRefs:
- name: qa
- sourceEnvironmentRef:
name: qa
targetEnvironmentRefs:
- name: preproduction
- sourceEnvironmentRef:
name: preproduction
targetEnvironmentRefs:
- name: production
EOF

Verification:

kubectl get deploymentpipeline -n $NAMESPACE_NAME
kubectl get deploymentpipeline default -n $NAMESPACE_NAME -o yaml

3. Project (At least 1)​

A Project is a logical grouping of related components that share a deployment pipeline.

Create a project:

kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: Project
metadata:
name: default
namespace: $NAMESPACE_NAME
annotations:
openchoreo.dev/display-name: "Default Project"
openchoreo.dev/description: "Default project for components"
labels:
openchoreo.dev/name: default
spec:
deploymentPipelineRef:
name: default
EOF

Verification:

kubectl get project -n $NAMESPACE_NAME
kubectl get project default -n $NAMESPACE_NAME -o yaml

Optional Resources​

These resources enhance OpenChoreo capabilities but are not required for basic deployments.

note

If you followed the getting-started guides, cluster-scoped planes (ClusterDataPlane, ClusterWorkflowPlane, ClusterObservabilityPlane) are already registered and visible to all namespaces. You only need the namespace-scoped variants below if you want physical isolation for a specific namespace.

DataPlane (Namespace-scoped, for isolation)​

By default, namespaces use the ClusterDataPlane. Create a namespace-scoped DataPlane only when you need a dedicated data plane for a specific namespace.

# Extract client CA from data plane
DP_CA_CERT=$(kubectl --context ${DATA_PLANE_CONTEXT:-$(kubectl config current-context)} get secret cluster-agent-tls \
-n openchoreo-data-plane \
-o jsonpath='{.data.ca\.crt}' | base64 -d)

# Create namespace-scoped DataPlane resource
kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: DataPlane
metadata:
name: $DATAPLANE_NAME
namespace: $NAMESPACE_NAME
annotations:
openchoreo.dev/display-name: "$DATAPLANE_NAME"
openchoreo.dev/description: "DataPlane for $NAMESPACE_NAME"
spec:
planeID: default
secretStoreRef:
name: default
gateway:
ingress:
external:
name: gateway-default
namespace: openchoreo-data-plane
http:
host: openchoreoapis.localhost
port: 19080
listenerName: http
clusterAgent:
clientCA:
value: |
$(echo "$DP_CA_CERT" | sed 's/^/ /')
EOF

Verification:

kubectl get dataplane -n $NAMESPACE_NAME

Workflow Plane (Optional)​

The Workflow Plane is required if developers need to build applications from source code. Without it, you can only deploy pre-built container images. If a ClusterWorkflowPlane is already registered, new namespaces can use it automatically.

Prerequisites:

  • Container registry (local or external)

Setup:

See the Container Registry Configuration and Auto-Build Configuration guides for detailed setup instructions.

Namespace-scoped setup (for isolation):

# Extract client CA from workflow plane
WP_CA_CERT=$(kubectl --context ${WORKFLOW_PLANE_CONTEXT:-$(kubectl config current-context)} get secret cluster-agent-tls \
-n openchoreo-workflow-plane \
-o jsonpath='{.data.ca\.crt}' | base64 -d)

# Create namespace-scoped WorkflowPlane resource
kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: WorkflowPlane
metadata:
name: default
namespace: $NAMESPACE_NAME
spec:
planeID: "default"
secretStoreRef:
name: default
clusterAgent:
clientCA:
value: |
$(echo "$WP_CA_CERT" | sed 's/^/ /')
EOF

Verification:

kubectl get workflowplane -n $NAMESPACE_NAME

Observability Plane (Optional)​

The Observability Plane provides centralized logging and monitoring for deployed components. If a ClusterObservabilityPlane is already registered, new namespaces can use it automatically.

Prerequisites:

  • OpenSearch cluster (or similar log aggregation system)
  • FluentBit (installed with data plane observability features)

Setup:

See the Observability and Alerting guide for detailed setup instructions.

Namespace-scoped setup (for isolation):

# Extract client CA from observability plane
OP_CA_CERT=$(kubectl --context ${OBSERVABILITY_PLANE_CONTEXT:-$(kubectl config current-context)} get secret cluster-agent-tls \
-n openchoreo-observability-plane \
-o jsonpath='{.data.ca\.crt}' | base64 -d)

# Create namespace-scoped ObservabilityPlane resource
kubectl apply -f - <<EOF
apiVersion: openchoreo.dev/v1alpha1
kind: ObservabilityPlane
metadata:
name: default
namespace: $NAMESPACE_NAME
spec:
planeID: "default"
clusterAgent:
clientCA:
value: |
$(echo "$OP_CA_CERT" | sed 's/^/ /')
observerURL: http://observer.openchoreo-observability-plane.svc.cluster.local:8080
EOF

Verification:

kubectl get observabilityplane -n $NAMESPACE_NAME

Component Types, Workflows, and Traits (Namespace-scoped, for isolation)​

By default, new namespaces inherit ClusterComponentTypes, ClusterWorkflows, and ClusterTraits. Create namespace-scoped variants only when you need to customize or override them for a specific namespace.

# Copy a ClusterComponentType as a namespace-scoped ComponentType
kubectl get clustercomponenttype service -o yaml | \
yq eval ".kind = \"ComponentType\" | .metadata.namespace = \"$NAMESPACE_NAME\" | del(.metadata.resourceVersion, .metadata.uid, .metadata.creationTimestamp)" - | \
kubectl apply -f -

Next Steps​

Once your namespace is prepared, you can:

  1. Deploy your first component - Follow the deployment guide

  2. Configure additional platform features

Troubleshooting​

DataPlane shows as "NotReady"​

Check the ClusterDataPlane or DataPlane status and conditions:

# For cluster-scoped (default):
kubectl get clusterdataplane $DATAPLANE_NAME
kubectl get clusterdataplane $DATAPLANE_NAME -o yaml | grep -A 20 "^status:"

# For namespace-scoped:
kubectl get dataplane $DATAPLANE_NAME -n $NAMESPACE_NAME
kubectl get dataplane $DATAPLANE_NAME -n $NAMESPACE_NAME -o yaml | grep -A 20 "^status:"

Common issues:

  • Invalid Kubernetes API server URL (direct API mode)
  • Incorrect certificates or authentication credentials (direct API mode)
  • Network connectivity issues between control plane and data plane
  • PlaneID mismatch (agent mode): The planeID in the ClusterDataPlane/DataPlane CR must match the clusterAgent.planeID Helm value
  • CA certificate mismatch (agent mode): The client CA in the ClusterDataPlane/DataPlane CR must match the agent's certificate

For agent mode, check agent logs:

# Data plane agent logs
kubectl logs -n openchoreo-data-plane -l app=cluster-agent --tail=30

# Control plane gateway logs
kubectl logs -n openchoreo-control-plane -l app=cluster-gateway --tail=30

# Look for connection errors or certificate validation failures

Component Types or Workflows not appearing​

Check that cluster-scoped resources exist, or that namespace-scoped resources were created in the correct namespace:

# Check cluster-scoped resources (visible to all namespaces):
kubectl get clustercomponenttype,clusterworkflow

# Check namespace-scoped resources:
kubectl get componenttype,workflow -n $NAMESPACE_NAME

Pods stuck in Pending​

Check pod status and events:

kubectl describe pod <pod-name> -n <namespace>

Common causes:

  • Insufficient resources: Increase RAM/CPU allocation to your cluster
  • PVC issues: Check if storage provisioner is available
  • Image pull errors: Verify image registry credentials and network connectivity

Environment cannot resolve DataPlane reference​

Verify the DataPlane name in the Environment spec matches an existing ClusterDataPlane or DataPlane:

# Check cluster-scoped (default):
kubectl get clusterdataplane

# Check namespace-scoped:
kubectl get dataplane -n $NAMESPACE_NAME

# Check the environment's reference:
kubectl get environment <env-name> -n $NAMESPACE_NAME -o jsonpath='{.spec.dataPlaneRef}'

Project cannot find DeploymentPipeline​

Verify the DeploymentPipeline exists and the reference is correct:

kubectl get deploymentpipeline -n $NAMESPACE_NAME
kubectl get project <project-name> -n $NAMESPACE_NAME -o jsonpath='{.spec.deploymentPipelineRef.name}'