Kubernetes Namespace คืออะไร? จัดการ Environment ด้วย Namespace อย่างมืออาชีพ
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 - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: dev
EOF
เพื่อดูรายการ 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: "developer@example.com"
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: "frontend-team@company.com"
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: "backend-team@company.com"
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 ของ ผู้ให้บริการโฮสติ้ง