Kubernetes

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

  1. แบ่งแยกตามสภาพแวดล้อม – ใช้ Namespace ต่างกันสำหรับ Dev, Staging และ Production
  2. ตั้งค่า Resource Quota – ป้องกันการใช้ทรัพยากรมากเกินไป
  3. ตั้งค่า LimitRange – บังคับให้ Pod มี request และ limit ที่เหมาะสม
  4. ติดตั้ง Network Policy – เริ่มด้วย Deny All แล้ว Allow เฉพาะที่ต้องการเท่านั้น
  5. ติดตั้ง RBAC – กำหนด Role ต่างกันตามความต้องการของผู้ใช้งาน
  6. ใช้ Labels และ Selectors – จัดจำแนก Pod ด้วย Labels เพื่อสะดวกในการค้นหา
  7. สร้าง ServiceAccount – แต่ละ Namespace ช่วยให้มีการควบคุมการเข้าถึงที่ดี
  8. ทำการ 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 ของ ผู้ให้บริการโฮสติ้ง