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:
- kubectl configured with access to your cluster(s)
- 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:
developmentis already created on the namespace. If you want to create thedevelopmentenvironment, 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.
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:
-
Deploy your first component - Follow the deployment guide
-
Configure additional platform features
- Secret Management - External secret store integration
- Observability and Alerting - Monitoring and alerts
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
planeIDin the ClusterDataPlane/DataPlane CR must match theclusterAgent.planeIDHelm 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}'
Related Documentationβ
- Resource Relationships - Understanding OpenChoreo resource hierarchies
- Deployment Topology - Production deployment architectures
- Multi-Cluster Connectivity - Setting up multi-cluster deployments
- Container Registry Configuration - External registry setup
- Auto-Build Configuration - Build system configuration
- Observability and Alerting - Logging and monitoring setup