Kubernetes Namespace คืออะไร?
Namespace ในระบบ Kubernetes คือเครื่องมือการแบ่งส่วน (logical partitioning) ที่ช่วยให้คุณจัดการทรัพยากรและสภาพแวดล้อม (Environment) ภายในคลัสเตอร์เดียว Namespace ทำหน้าที่เหมือนเป็น Virtual Cluster ในคลัสเตอร์ Kubernetes เดียว โดยมีการแยก Resources และ RBAC (Role-Based Access Control) ในแต่ละ Namespace ผู้ใช้งานต่างกันสามารถทำงานพร้อมกันโดยไม่กระทบต่อกัน
Default Namespaces ใน Kubernetes
Kubernetes มาพร้อมกับ Namespace พื้นฐานหลายตัวเมื่อคุณสร้าง cluster:
- default – Namespace ค่าเริ่มต้นที่ใช้สำหรับ Pod และ Resource ต่าง ๆ ที่ไม่ระบุ Namespace อื่น
- kube-system – Namespace สำหรับส่วนประกอบของระบบ Kubernetes เช่น DNS, Metrics Server, CoreDNS
- kube-public – Namespace สาธารณะที่สามารถอ่านได้จากทั้ง cluster
- kube-node-lease – Namespace สำหรับ Lease objects ของ Node เพื่อติดตามสถานะ heartbeat ของ Node
สร้างและจัดการ Namespace
การสร้าง Namespace นั้นง่ายมาก คุณสามารถสร้างได้ด้วยคำสั่ง kubectl:
# สร้าง Namespace ชื่อ "development"
kubectl create namespace development
# หรือใช้ YAML file
kubectl apply -f - <
เพื่อดูรายการ Namespace ทั้งหมด:
kubectl get namespaces
kubectl get ns # ชื่อย่อ
เพื่อลบ Namespace:
kubectl delete namespace development
DNS ระหว่าง Namespace
Kubernetes ใช้ Fully Qualified Domain Name (FQDN) สำหรับ Pod ที่ต่าง Namespace หากต้องการเชื่อมต่อ Pod ข้ามเขตแดน Namespace:
# รูปแบบ DNS ระหว่าง Namespace
pod-name.namespace-name.svc.cluster.local
# ตัวอย่าง:
my-app.production.svc.cluster.local
การแบ่งแยก Environment ด้วย Namespace (Dev/Staging/Prod)
วิธีนิยมที่พบในการใช้งาน Namespace กับการจัดการสภาพแวดล้อมที่ซับซ้อนคือการแบ่งแยกออกเป็นสิ่งต่างๆ เช่น Development, Staging และ Production:
# สร้าง 3 Namespace สำหรับสภาพแวดล้อมต่างกัน
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
หลังจากนั้น ผู้ใช้งานสามารถ Deploy ไปที่ Namespace แต่ละตัวได้:
kubectl apply -f deployment.yaml -n development
kubectl apply -f deployment.yaml -n staging
kubectl apply -f deployment.yaml -n production
Resource Quota – จำกัดทรัพยากร CPU/Memory ต่อ Namespace
Resource Quota ช่วยให้คุณจำกัดการใช้ทรัพยากร (CPU, Memory) ในแต่ละ Namespace เพื่อป้องกันไม่ให้ Namespace หนึ่ง ใช้ทรัพยากรมากเกินไปและส่งผลกระทบต่อ Namespace อื่น:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: development
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "100"
persistentvolumeclaims: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["default", "high"]
ตรวจสอบการใช้งาน Resource Quota:
kubectl describe resourcequota compute-quota -n development
kubectl get resourcequota -n development
LimitRange – ควบคุม CPU/Memory ระดับ Pod
LimitRange ใช้สำหรับกำหนดขีดจำกัด CPU และ Memory สำหรับแต่ละ Pod หรือ Container ในแต่ละ Namespace:
apiVersion: v1
kind: LimitRange
metadata:
name: pod-limit
namespace: development
spec:
limits:
- type: Pod
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "100m"
memory: "128Mi"
- type: Container
max:
cpu: "1"
memory: "1Gi"
min:
cpu: "50m"
memory: "64Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
ratio:
limits.cpu: "4"
limits.memory: "1.5"
ติดตั้ง LimitRange:
kubectl apply -f limitrange.yaml
kubectl get limitrange -n development
Network Policy – ควบคุม Traffic ระหว่าง Namespace
Network Policy ช่วยให้คุณควบคุมการสื่อสารระหว่าง Pod ในต่าง Namespace ได้อย่างละเอียด:
# เริ่มด้วย "Deny All" สำหรับ Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: development
spec:
podSelector: {}
policyTypes:
- Ingress
---
# อนุญาต Traffic ระหว่าง Frontend และ Backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: development
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 3000
---
# อนุญาต DNS จาก kube-system Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: development
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
RBAC (Role-Based Access Control) สำหรับ Namespace
Role-Based Access Control (RBAC) ช่วยให้คุณจำกัดการเข้าถึงทรัพยากรตามบทบาท (Role) ของผู้ใช้งาน:
# สร้าง Role สำหรับการอ่าน Pod เท่านั้น
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: development
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: development
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: User
name: "[email protected]"
apiGroup: rbac.authorization.k8s.io
---
# Role สำหรับ Developer (Create/Update/Delete)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer-role
namespace: development
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: development
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: developer-role
subjects:
- kind: ServiceAccount
name: developer-sa
namespace: development
kubectl กับ Namespace
การใช้คำสั่ง kubectl กับ Namespace:
# ตั้งค่า context เพื่อใช้งาน Namespace โดยค่าเริ่มต้น
kubectl config set-context $(kubectl config current-context) --namespace=development
# ดูข้อมูล Pod ทั้งหมด Namespace
kubectl get pods --all-namespaces
kubectl get pods -A
# ดูข้อมูล Pod เฉพาะ Namespace
kubectl get pods -n development
kubectl get pods -n production
# ดูรายละเอียด Pod
kubectl describe pod my-pod -n development
# เปลี่ยน Context ไปยัง Namespace อื่น
kubectl config set-context --current --namespace=production
Multi-Tenant Scenario – ตัวอย่างหลาย Team
ตัวอย่างการจัดการ 3 Team โดยแต่ละ Team มี Namespace ของตัวเองโดยไม่กระทบต่อกัน:
# Team Frontend Namespace
apiVersion: v1
kind: Namespace
metadata:
name: team-frontend
labels:
team: frontend
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: frontend-quota
namespace: team-frontend
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
pods: "100"
---
apiVersion: v1
kind: LimitRange
metadata:
name: frontend-limits
namespace: team-frontend
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: frontend-admin
namespace: team-frontend
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: Group
name: "[email protected]"
apiGroup: rbac.authorization.k8s.io
---
# Team Backend Namespace
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: backend-quota
namespace: team-backend
spec:
hard:
requests.cpu: "20"
requests.memory: "40Gi"
pods: "150"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-admin
namespace: team-backend
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: Group
name: "[email protected]"
apiGroup: rbac.authorization.k8s.io
Best Practices สำหรับ Multi-tenant Kubernetes
- แบ่งแยกตามสภาพแวดล้อม – ใช้ Namespace ต่างกันสำหรับ Dev, Staging และ Production
- ตั้งค่า Resource Quota – ป้องกันการใช้ทรัพยากรมากเกินไป
- ตั้งค่า LimitRange – บังคับให้ Pod มี request และ limit ที่เหมาะสม
- ติดตั้ง Network Policy – เริ่มด้วย Deny All แล้ว Allow เฉพาะที่ต้องการเท่านั้น
- ติดตั้ง RBAC – กำหนด Role ต่างกันตามความต้องการของผู้ใช้งาน
- ใช้ Labels และ Selectors – จัดจำแนก Pod ด้วย Labels เพื่อสะดวกในการค้นหา
- สร้าง ServiceAccount – แต่ละ Namespace ช่วยให้มีการควบคุมการเข้าถึงที่ดี
- ทำการ Monitoring – ใช้เครื่องมือเช่น Prometheus เพื่อติดตามการใช้งาน
ความแยกของ Pod ระหว่าง Namespace
Pod ใน Namespace หนึ่งไม่สามารถเข้าถึง Pod ใน Namespace อื่นได้โดยอัตโนมัติ Namespace ทำหน้าที่เป็น Barrier ที่ป้องกันการเข้าถึง
DNS ระหว่าง Namespace
สำคัญที่จะต้องใช้ DNS name ที่ถูกต้องเพื่อเชื่อมต่อ Service ภาย Namespace อื่น:
# รูปแบบ DNS FQDN
service-name.namespace-name.svc.cluster.local
ClusterRole vs Role
Role มีขอบเขตจำกัดเฉพาะ Namespace เท่านั้น ในขณะที่ ClusterRole มีขอบเขตครอบคลุม Cluster ทั้งหมด โปรดเลือกให้เหมาะสมตามความต้องการของคุณ
Template สำเร็จรูปสำหรับใช้งาน
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: production
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: prod-quota
namespace: production
spec:
hard:
requests.cpu: "50"
requests.memory: "100Gi"
limits.cpu: "100"
limits.memory: "200Gi"
pods: "500"
---
apiVersion: v1
kind: LimitRange
metadata:
name: prod-limits
namespace: production
spec:
limits:
- type: Container
default:
cpu: "1000m"
memory: "1Gi"
defaultRequest:
cpu: "250m"
memory: "256Mi"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-ingress-policy
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 443
สรุป
Namespace เป็นส่วนสำคัญของ Kubernetes ที่ช่วยให้คุณจัดการการแบ่งแยกหลาย Team, สภาพแวดล้อม และผู้ใช้งานได้อย่างมีประสิทธิภาพและปลอดภัย เมื่อคุณรวมใช้ส่วนประกอบต่าง ๆ เข้าด้วยกัน:
- Namespace: แบ่งแยก Resources ต่าง ๆ ออกจากกัน
- Resource Quota: จำกัดการใช้ทรัพยากรทั้งหมด
- LimitRange: กำหนดขีดจำกัด CPU/Memory ต่อ Pod
- Network Policy: ควบคุม Traffic ภายใน/ภายนอก Namespace
- RBAC: จัดการเข้าถึงตามบทบาท
ด้วยการจัดการ Namespace อย่างเหมาะสม คุณจะสร้างสภาพแวดล้อมที่ปลอดภัย มีการล่าเสือ สนับสนุนสภาพแวดล้อมอื่น และมีการควบคุมที่เป็นระเบียบ ทำให้คุณสามารถ Deploy แอปพลิเคชันบน Kubernetes cluster ที่ปลอดภัยและมีประสิทธิภาพสูง บน Cloud VPS ของ ผู้ให้บริการโฮสติ้ง
