ข้ามไปยังเนื้อหา

Namespace และ Resource Quota

Namespace แบ่ง object และชื่อของ cluster เดียวให้หลาย user, ทีม หรือโปรเจกต์ใช้ร่วมกัน แต่ไม่ได้แบ่ง network ให้ด้วย ต้องใช้ NetworkPolicy ถึงจะทำได้

Namespace scope ชื่อ ของ object Deployment web ใน namespace team-a กับ Deployment web ใน namespace team-b เป็นคนละ object กันโดยสิ้นเชิง แค่บังเอิญชื่อเหมือนกัน Namespace ยังเป็นหน่วยที่ RBAC (จะพูดถึงใน module ถัดไป) มักถูก scope ไว้ ทำให้สิทธิ์ของแต่ละทีมจำกัดอยู่แค่ namespace ที่ทีมนั้นดูแล ไม่ใช่ทั้ง cluster

สิ่งที่ Namespace ไม่ได้ ให้คือ network isolation โดย default Pod ใน team-a ยังส่ง traffic ไปหา Pod ใน team-b ได้อยู่ดี Namespace เป็นขอบเขตเรื่องชื่อและการจัดระเบียบ ไม่ใช่ขอบเขตเรื่อง network ถ้าอยากบล็อก traffic นั้นต้องใช้ NetworkPolicy ซึ่งอยู่ใน module Networking

apiVersion: v1
kind: Namespace
metadata:
name: team-a
Terminal window
kubectl create namespace team-a
kubectl config set-context --current --namespace=team-a

บาง object เป็น cluster-scoped คืออยู่นอก namespace ไหนเลย เพราะอธิบายแนวคิดระดับ cluster ไม่ใช่สิ่งที่ทีมใดทีมหนึ่งเป็นเจ้าของ Node, PersistentVolume และ ClusterRole ล้วนเป็น cluster-scoped ส่วน object ที่ใช้กันบ่อย ๆ อย่าง Pod, Deployment, Service, ConfigMap, PersistentVolumeClaim เป็น namespaced

Terminal window
# List objects that live outside any namespace
kubectl api-resources --namespaced=false

ResourceQuota จำกัดการใช้ resource รวมทั้งหมดของ namespace หนึ่งตัว คือ CPU กับ memory requests/limits รวมของทุก Pod ใน namespace นั้น และ/หรือจำนวน object รวม เช่น จำนวน Pod, Service หรือ PersistentVolumeClaim สูงสุด

apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
pods: "50"
persistentvolumeclaims: "10"

ResourceQuota จำกัดทั้ง namespace รวมกัน แต่ไม่ได้พูดถึง Pod ตัวใดตัวหนึ่งเลย ถ้าไม่มีขอบเขตระดับ object เดียว Pod ที่ไม่ถูกจำกัดตัวเดียวสามารถขอ CPU กับ memory มากพอจะกิน ResourceQuota ทั้ง namespace ไปคนเดียว ทำให้ Pod อื่นในทีมเดียวกันขาดแคลนไปด้วย LimitRange ปิดช่องว่างนี้ด้วยการตั้งค่า default, ขั้นต่ำ และขั้นสูงของ requests/limits สำหรับ Pod และ container แต่ละตัวที่ถูกสร้างใน namespace นั้น

apiVersion: v1
kind: LimitRange
metadata:
name: team-a-limits
namespace: team-a
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 250m
memory: 256Mi
max:
cpu: "2"
memory: 2Gi
min:
cpu: 100m
memory: 128Mi
flowchart LR
  subgraph cluster["Cluster"]
    subgraph nsa["Namespace: team-a"]
      qa["ResourceQuota"] --- la["LimitRange"]
      pa1["Pod"] --- pa2["Pod"]
    end
    subgraph nsb["Namespace: team-b"]
      qb["ResourceQuota"] --- lb["LimitRange"]
      pb1["Pod"] --- pb2["Pod"]
    end
  end
สอง namespace แต่ละอันถูกจำกัดด้วย ResourceQuota และ LimitRange ของตัวเอง
โดย default namespace ไม่ได้ให้อะไรระหว่าง Pod ที่อยู่คนละ namespace
object ไหนต่อไปนี้เป็น cluster-scoped ไม่ใช่ namespaced
ResourceQuota คุมอะไรที่ LimitRange ไม่ได้คุม
ทำไม namespace ถึงต้องมี LimitRange เพิ่มจาก ResourceQuota