Managing Namespaces and Multi-Tenancy
1. Creating Namespace in Chart
| Property | Value | Description |
|---|---|---|
| namespace | myapp-namespace |
Name of the namespace to create |
| annotations | {"owner": "dev-team"} |
Annotations to apply to the namespace |
| labels | {"env": "production"} |
Labels to apply to the namespace |
Example: Creating a Namespace with Annotations and Labels
apiVersion: v1
kind: Namespace
metadata:
name: myapp-namespace
annotations:
owner: dev-team
labels:
env: production
Note: The namespace will be created if it does not already exist when the chart is installed.
2. Using Release Namespace
| Property | Values | Description |
|---|---|---|
| namespace | string |
The Kubernetes namespace where the release will be installed. |
| createNamespace | boolean |
If true, the namespace will be created if it does not exist. |
Example: Setting Release Namespace
apiVersion: v1
kind: Namespace
metadata:
name: production-apps
---
apiVersion: helm.sh/v1
kind: Release
metadata:
name: my-app-release
spec:
chart:
name: nginx
version: "1.0.0"
namespace: production-apps
createNamespace: true
Note: The namespace must exist or
createNamespace must be set to true for the release to install successfully.
3. Installing Charts Across Namespaces
| Option | Values | Description |
|---|---|---|
| --namespace | string |
Install the chart into a specific namespace |
| --create-namespace | bool |
Create the namespace if it does not exist |
| --atomic | bool |
Fail and rollback if installation fails |
Example: Installing a Chart in a Specific Namespace
helm install my-app stable/nginx-ingress --namespace production --create-namespace
Example: Installing with Atomic Rollback
helm install my-app stable/nginx-ingress --namespace staging --atomic
Note: Ensure the user has appropriate RBAC permissions to install in the target namespace.
4. Implementing Namespace Isolation
| Property | Description | Example |
|---|---|---|
| namespace | The Kubernetes namespace where the chart will be deployed | production |
| nameOverride | Overrides the chart's release name in the namespace | myapp-prod |
| fullnameOverride | Overrides the full release name including namespace prefix | production-myapp-prod |
Example: Deploying to a Specific Namespace
apiVersion: v1
kind: Namespace
metadata:
name: production
---
apiVersion: helm.sh/v2
kind: Release
metadata:
name: myapp-release
namespace: production
spec:
chart:
name: myapp-chart
version: "1.0.0"
Example: Using Values to Set Namespace
namespace: staging
nameOverride: "myapp-staging"
fullnameOverride: "staging-myapp-staging"
# In values.yaml
ingress:
enabled: true
hosts:
- host: myapp.staging.example.com
paths:
- path: /
backend:
serviceName: myapp-service
servicePort: 80
Note: Helm does not enforce namespace isolation by default. It is the responsibility of the user or CI/CD pipeline to ensure that charts are deployed to the correct namespace.
Warning: Be cautious when deploying charts to namespaces with existing resources. Helm will attempt to upgrade or recreate resources, which may lead to data loss or service disruption.
5. Using Namespace-scoped Resources
| Resource Type | Namespace Scope | Description | Example |
|---|---|---|---|
| ConfigMap | Yes | Stores non-confidential data in key-value pairs | |
| Secret | Yes | Stores sensitive data like passwords or tokens | |
| Service | Yes | Exposes an application within a namespace | |
| Deployment | Yes | Manages a set of replica Pods | |
Example: Namespace-scoped Resource in Helm Chart
apiVersion: v1
kind: Service
metadata:
name: {{ include "myapp.fullname" . }}
namespace: {{ .Values.namespace }}
spec:
selector:
app: {{ include "myapp.name" . }}
ports:
- port: {{ .Values.service.port }}
targetPort: 80
Note: Helm charts can define resources in specific namespaces using
.Values.namespace or by setting the namespace during installation with --namespace.Warning: Be cautious when deleting namespaces, as it will remove all resources within that namespace.
6. Managing Cluster-scoped Resources
| Resource Type | Description | Scope | Notes |
|---|---|---|---|
| ClusterRole | Defines permissions at the cluster level | Cluster | Used with ClusterRoleBinding to grant access across namespaces |
| ClusterRoleBinding | Binds ClusterRole to users or groups across namespaces | Cluster | Cannot be scoped to a namespace |
| PersistentVolume | Represents a piece of storage in the cluster | Cluster | Must be created before PersistentVolumeClaim |
| StorageClass | Defines storage types with provisioners | Cluster | Used for dynamic volume provisioning |
| CustomResourceDefinition | Extends Kubernetes API with custom resources | Cluster | Requires CRD to be installed before using custom resources |
Example: Defining a ClusterRole for Multi-Tenant Access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tenant-admin
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "delete"]
Example: Binding ClusterRole to a User
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tenant-admin-binding
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tenant-admin
apiGroup: rbac.authorization.k8s.io
Note: Cluster-scoped resources are not namespaced and can be accessed from any namespace. Helm charts should not define cluster-scoped resources unless explicitly required for multi-tenancy or infrastructure setup.
7. Implementing Resource Quotas
| Resource | Quota Type | Default Limit | Notes |
|---|---|---|---|
| limits.cpu | Resource | Unlimited | Maximum CPU allocation per namespace |
| limits.memory | Resource | Unlimited | Maximum memory allocation per namespace |
| requests.cpu | Resource | Unlimited | Minimum CPU requested per namespace |
| requests.memory | Resource | Unlimited | Minimum memory requested per namespace |
| pods | Count | Unlimited | Maximum number of pods allowed in the namespace |
| services.loadbalancers | Count | Unlimited | Maximum number of LoadBalancer services |
| services.nodeports | Count | Unlimited | Maximum number of NodePort services |
Example: Setting Resource Quotas in a Namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: example-quota
namespace: production
spec:
hard:
limits.cpu: "2"
limits.memory: 4Gi
requests.cpu: "1"
requests.memory: 2Gi
pods: "10"
services.loadbalancers: "5"
services.nodeports: "3"
Note: Resource quotas are enforced at the namespace level and apply to all pods within that namespace. They do not prevent individual pods from exceeding their own limits, but rather enforce a total limit across the namespace.
Warning: Setting quotas too low can cause applications to fail or become unresponsive. Always test quota configurations in a non-production environment before applying them.
8. Using LimitRange for Namespaces
| Property | Values | Description |
|---|---|---|
| apiVersion | v1 |
The API version of the LimitRange resource |
| kind | LimitRange |
The kind of the Kubernetes resource |
| metadata.name | example-limit-range |
Name of the LimitRange resource |
| spec.limits[].type | Container, PersistentVolumeClaim |
Type of resource to limit (e.g., container or PVC) |
| spec.limits[].max.cpu | 2 |
Maximum CPU allocation per container |
| spec.limits[].min.memory | 128Mi |
Minimum memory allocation per container |
| spec.limits[].default.cpu | 500m |
Default CPU allocation if not specified |
| spec.limits[].default.memory | 256Mi |
Default memory allocation if not specified |
Example: Define LimitRange in a Helm Chart
apiVersion: v1
kind: LimitRange
metadata:
name: {{ .Values.limitRange.name }}
spec:
limits:
- default:
cpu: {{ .Values.limitRange.defaultCpu }}
memory: {{ .Values.limitRange.defaultMemory }}
defaultRequest:
cpu: {{ .Values.limitRange.defaultRequestCpu }}
memory: {{ .Values.limitRange.defaultRequestMemory }}
max:
cpu: {{ .Values.limitRange.maxCpu }}
memory: {{ .Values.limitRange.maxMemory }}
min:
cpu: {{ .Values.limitRange.minCpu }}
memory: {{ .Values.limitRange.minMemory }}
type: Container
Note: LimitRange is applied per namespace and affects all pods created in that namespace unless overridden.
Warning: LimitRange does not enforce limits on resources that are already created; it only applies to new resources.
9. Handling Cross-Namespace References
| Reference Type | Description | Usage | Notes |
|---|---|---|---|
| ServiceReference | Refers to a Kubernetes Service in another namespace | service.name: "my-service"service.namespace: "other-namespace" |
Must have appropriate RBAC permissions to access the service |
| ConfigMapReference | References a ConfigMap in another namespace | configMap.name: "my-configmap"configMap.namespace: "other-namespace" |
Used for cross-namespace configuration sharing |
| SecretReference | References a Secret in another namespace | secret.name: "my-secret"secret.namespace: "other-namespace" |
Requires proper RBAC to read secrets in other namespaces |
Example: Using Cross-Namespace Service in Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-deployment
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: nginx:latest
env:
- name: BACKEND_URL
valueFrom:
configMapKeyRef:
name: backend-config
key: url
namespace: backend-namespace
Note: When referencing resources in other namespaces, ensure that the Helm chart has appropriate RBAC rules or that the namespace is properly configured to allow cross-namespace access.
10. Implementing Multi-Tenant Charts
| Property | Description | Example |
|---|---|---|
| tenantId | Unique identifier for each tenant | tenant-123 |
| namespace | Kubernetes namespace to deploy tenant resources | tenant-123-namespace |
| configMap | Configuration values specific to tenant | tenant-123-config |
Example: Multi-Tenant Chart Values
tenantId: tenant-123
namespace: tenant-123-namespace
configMap:
databaseUrl: "postgres://tenant-123-db"
apiUrl: "https://api.tenant-123.com"
Note: Ensure that each tenant's namespace has appropriate RBAC rules to isolate resources.
Warning: Avoid hardcoding tenant IDs in templates; use values files or secrets instead.