Work with Namespaces
Learn how to work with Kubernetes namespaces for Python environments. This lesson covers the core concepts, practical steps, and troubleshooting tips to help you isolate and organize your Python services.
Focus: work with namespaces for python environments
You’ve got your Python service containerized, wired into a Deployment, and exposed through a Service — maybe even an Ingress. But now your team grows, you add a staging environment, a few cron jobs, and suddenly everything is fighting for the same resources. Endpoints are colliding, kubectl get pods returns a wall of unrelated workloads, and you have no way to say “this is the production Python API” versus “this is a dev experiment.” That chaos is exactly the problem Kubernetes namespaces solve. In this lesson, you’ll learn how to create, manage, and use namespaces to isolate and organize your Python environments — and why this simple step is the difference between a demo cluster and a production-ready one.
The problem this lesson solves
When you first start with Kubernetes, everything goes into the default namespace. It feels fine — your Python app is tiny, you know exactly what’s running. But as you progress, several problems creep in:
- Resource contention — your staging API competes with production for CPU and memory.
- Naming collisions — you can’t have two Services both named
apiin the same namespace, even if they belong to different environments. - Unclear ownership — you can’t tell which Pod belongs to which team or environment just by looking at a list.
- Security risks — any Pod can talk to any Service, and access control becomes a mess.
Without namespaces, you’re flying blind. You might think, “I’ll just name things api-prod and api-staging,” but that’s a band-aid that doesn’t give you resource quotas, network policies, or Role-Based Access Control (RBAC) scoped to an environment. Namespaces are the fundamental unit of isolation in Kubernetes, and if you skip them, you’ll hit a wall the moment you deploy more than a toy app.
Pro tip: Even for personal projects, get into the habit of using namespaces from day one. It costs almost nothing and saves hours of debugging later.
Core concept / mental model
Think of a Kubernetes cluster as an apartment building. The cluster is the whole building, and each namespace is an apartment. Each apartment has its own rooms (Pods, Services, Deployments), its own front door (Service DNS), and its own rules (ResourceQuota, LimitRange, NetworkPolicy). One apartment doesn’t know or care about the others — until you choose to share a hallway (via a cross-namespace Service or Ingress).
In technical terms, a namespace is a logical partition of cluster resources. Kubernetes API objects like Pods, Services, and Deployments belong to exactly one namespace. Cluster-wide resources like Nodes and PersistentVolumes are not namespaced — they exist at the cluster level.
Here’s a word-based diagram of how your Python environments might be organized:
Cluster
├── namespace: production
│ ├── Deployment: fastapi-api
│ ├── Service: fastapi-api
│ └── ConfigMap: app-config
├── namespace: staging
│ ├── Deployment: fastapi-api
│ └── Service: fastapi-api
└── namespace: development
├── Deployment: fastapi-api
└── Service: fastapi-api
Notice that fastapi-api exists in every namespace — that’s allowed because namespaces provide isolation. You can have the same name in different namespaces without conflict.
How it works step by step
Working with namespaces involves creating them, deploying workloads into them, and managing access. Here’s the logical sequence:
Step 1: List existing namespaces
First, see what you already have. Kubernetes always comes with four default namespaces: default, kube-system, kube-public, and kube-node-lease. Don’t delete or modify these.
kubectl get namespaces
Step 2: Create a namespace
You can create a namespace imperatively (quick, for testing) or declaratively (best for version control).
# Imperative
kubectl create namespace production
# Declarative — save this to namespace-production.yaml and run kubectl apply -f
apiVersion: v1
kind: Namespace
metadata:
name: production
Step 3: Deploy your Python app into the namespace
When you apply a manifest, either set the namespace in the file or pass -n on the command line.
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-api
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: fastapi-api
template:
metadata:
labels:
app: fastapi-api
spec:
containers:
- name: api
image: python:3.11-slim
command: ["/bin/sh", "-c"]
args:
- pip install fastapi uvicorn && uvicorn main:app --host 0.0.0.0 --port 8000
kubectl apply -f deployment.yaml
Step 4: Switch context to the namespace
To avoid typing -n every time, set your default namespace with kubectl config.
kubectl config set-context --current --namespace production
Now kubectl get pods will only show pods in production.
Step 5: Verify and manage
Check your resources, inspect logs, and clean up when done.
kubectl get pods -n production
kubectl logs deployment/fastapi-api -n production
kubectl delete namespace production # deletes everything inside it
Hands-on walkthrough
Let’s put this into practice. You’ll create two namespaces — dev and prod — deploy a simple Python “hello” HTTP server to each, and prove they’re isolated.
1. Write a minimal Python server
Create a file server.py (or use a pre-built image like python:3.11-slim with inline code). For simplicity, let’s use a one-line command that runs an HTTP server:
# server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b"Hello from Python!")
HTTPServer(('0.0.0.0', 8000), Handler).serve_forever()
2. Create two namespaces
kubectl create namespace dev
kubectl create namespace prod
3. Deploy the same app to both
Create a deployment manifest with the namespace field, but we’ll apply it twice with different namespaces using -n.
# hello-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-python
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: python:3.11-slim
command: ["/bin/sh", "-c"]
args:
- pip install --no-cache-dir -q fastapi uvicorn && echo 'from fastapi import FastAPI; app = FastAPI(); @app.get("/") def root(): return {"msg": "hello"}' > main.py && uvicorn main:app --host 0.0.0.0 --port 8000
ports:
- containerPort: 8000
kubectl apply -f hello-deployment.yaml -n dev
kubectl apply -f hello-deployment.yaml -n prod
4. Verify isolation
List pods in each namespace:
kubectl get pods -n dev
kubectl get pods -n prod
Expected output:
NAME READY STATUS RESTARTS AGE
hello-python-7d5b9f8d4b-9x1k2 1/1 Running 0 30s
Both namespaces have a pod with the same naming pattern, but they are independent. Try to access the Service — if you expose them, they’ll have different DNS names.
5. Clean up
kubectl delete namespace dev prod
Pro tip: Use
kubectl get all -n <namespace>to see everything running in a namespace at a glance.
Compare options / when to choose what
There are several ways to isolate environments in Kubernetes. Let’s compare them.
| Approach | Use case | Pros | Cons |
|---|---|---|---|
| Single namespace | Early dev, tiny apps | Simple, zero overhead | No isolation, risk of collisions |
| Multiple namespaces per environment | Common for staging/prod | Clear separation, resource quotas, RBAC per environment | Slightly more overhead to manage |
| Separate clusters | Compliance, hard multi-tenancy | Strongest isolation | Cost, operational complexity |
| Labels + selectors | Organizing within a namespace | Flexible, no namespace overhead | Doesn’t provide isolation or quotas |
When to choose what:
- Personal project? You can get away with one namespace, but trust me, use two — dev and prod — so you learn the discipline.
- Team with staging and production? Use namespaces per environment.
- Strict regulatory data separation? Separate clusters are the safer bet.
Troubleshooting & edge cases
Even with namespaces, things go wrong. Here are the common ones and how to fix them.
Error: namespace not found
When you try to apply a manifest with a namespace that doesn’t exist, you get:
Error from server (NotFound): error when creating ... namespaces "production" not found
Fix: Create the namespace first (kubectl create namespace production) or ensure the manifest includes the Namespace object and you apply it first.
Problem: I see all pods, not just mine
If you run kubectl get pods and see everything, your context is set to default. Set your namespace or pass -n.
kubectl config set-context --current --namespace dev
Edge case: Cross-namespace DNS
Services in different namespaces are not reachable by short name. You need the full DNS name: service-name.namespace.svc.cluster.local. If your Python app tries to call http://api but api is in another namespace, it will fail. Use the FQDN.
Gotcha: Deleting a namespace deletes everything
There’s no undo. Make sure you have backups or YAML files before kubectl delete namespace. Use --cascade=orphan if you want to keep the objects but remove the namespace (advanced).
What you learned & what's next
You now understand the purpose of namespaces, how to create them, how to deploy your Python workloads into them, and how to switch between them. You also know the key edge cases like DNS and deletion behavior. You connected this to your Python environments — dev, staging, prod — and you’re ready for the next lesson.
Next up in the Kubernetes for Python Developers track, you’ll dive into Resource Limits and Quotas — how to set CPU and memory boundaries per namespace so one chatty service can’t starve the rest. You’ll use namespaces you just created as the sandbox for those experiments.
Remember: Namespaces are your first tool for organization and isolation. Master them, and the rest of Kubernetes becomes much more manageable.
Practice recap
Create two namespaces, dev and prod, and deploy a simple Python HTTP server to each. Verify they are isolated by listing pods in each and attempting to access a Service by short name from the other namespace. Then clean up by deleting both namespaces.
Common mistakes
- Forgetting to create the namespace before applying a manifest that references it — you get a 'namespace not found' error.
- Deploying everything into the
defaultnamespace and then wondering why you can't tell environments apart. - Trying to call a Service in another namespace using its short name — you need the FQDN (
service.namespace.svc.cluster.local). - Deleting a namespace without realizing it cascades and deletes all Pods, Services, and ConfigMaps inside it.
Variations
- Use
kubectl create namespacefor quick setup, or manage namespaces as declarative YAML in Git for version control. - Rely on labels and selectors instead of namespaces if you only need organizational grouping without isolation or quotas.
- Use separate clusters instead of namespaces when you require hard security isolation or compliance boundaries.
Real-world use cases
- A SaaS company runs separate namespaces for each customer environment to enforce resource quotas and network policies.
- A Python microservices team uses
dev,staging, andprodnamespaces to keep deployments isolated while sharing one cluster. - A machine learning platform isolates training jobs in dedicated namespaces with their own GPU quotas and RBAC rules.
Key takeaways
- Namespaces are logical partitions that isolate resources like Pods, Services, and ConfigMaps within a cluster.
- Use namespaces per environment (dev, staging, prod) to avoid naming collisions and share cluster resources safely.
- Set your default namespace with
kubectl config set-context --current --namespace <name>to reduce command clutter. - Services across namespaces are only reachable via their full DNS name:
service.namespace.svc.cluster.local. - Deleting a namespace recursively deletes all contained resources — always back up manifests first.
- Namespaces enable additional management tools like ResourceQuotas and RBAC, making them foundational for production Python deployments.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.