Namespace, Labels và Selectors

K
Kai··4 min read

Hai bài trước, Deployment và Service đều "tìm pod qua nhãn" mà ta chưa nói kỹ. Bài này trả món nợ đó: labelselector là cơ chế gắn thẻ và chọn lọc xuyên suốt Kubernetes — hiểu nó là hiểu cách các đối tượng buộc vào nhau. Đi kèm là namespace, cách chia cluster thành những ngăn tách biệt.

Namespace: chia cluster thành ngăn

Một cluster thường phục vụ nhiều đội, nhiều môi trường, nhiều ứng dụng. Đổ tất cả vào một chỗ thì hỗn loạn. Namespace là một "thư mục ảo" gom nhóm tài nguyên, cho phép cô lập về tên và áp quota/quyền riêng.

kubectl get namespaces
NAME              STATUS   AGE
default           Active   11m
kube-node-lease   Active   11m
kube-public       Active   11m
kube-system       Active   11m

Cluster nào cũng có sẵn vài namespace: default (nơi tài nguyên của bạn rơi vào nếu không chỉ định), kube-system (các thành phần hệ thống — nhớ Bài 1 ta đã soi pod control plane ở đây), kube-public, kube-node-lease. Tạo namespace mới:

kubectl create namespace dev

Rồi triển khai vào đó bằng cờ -n:

kubectl create deployment api --image=nginx:alpine -n dev
kubectl get pods -n dev
NAME                   READY   STATUS    RESTARTS   AGE
api-6676db897b-nlm78   1/1     Running   0          10s

Điểm cốt lõi: tài nguyên trong namespace khác nhau cô lập tên với nhau. Bạn có thể có Deployment webdefault một web khác ở dev — chúng không đụng nhau. kubectl get pods (không -n) chỉ thấy namespace hiện tại; muốn nhìn xuyên suốt dùng --all-namespaces (hoặc -A):

kubectl get pods --all-namespaces
NAMESPACE   NAME                   READY   STATUS    AGE
default     web-5687994c96-682pg   1/1     Running   5m2s
dev         api-6676db897b-nlm78   1/1     Running   10s

Một số tài nguyên nằm trong namespace (Pod, Deployment, Service, ConfigMap...), số khác là cấp cluster, không thuộc namespace nào (Node, Namespace, PersistentVolume). Nếu chuyển namespace thường xuyên, công cụ như kubens giúp đỡ mỏi tay; hoặc đặt mặc định: kubectl config set-context --current --namespace=dev.

Lưu ý: namespace không phải ranh giới bảo mật mạng mặc định — pod ở namespace này vẫn gọi được pod namespace kia qua DNS (web.default). Muốn chặn cần NetworkPolicy (ngoài phạm vi series nền tảng này).

Labels: gắn thẻ tự do cho tài nguyên

Label là các cặp key=value bạn đính lên đối tượng để phân loại chúng theo cách có ý nghĩa với mình: app=web, tier=frontend, env=production, version=v2... Label không làm gì tự thân — sức mạnh đến từ việc chọn lọc theo chúng.

Xem label trên các pod web:

kubectl get pods -l app=web --show-labels
NAME                   READY   STATUS    LABELS
web-5687994c96-682pg   1/1     Running   app=web,pod-template-hash=5687994c96
web-5687994c96-qmkr5   1/1     Running   app=web,pod-template-hash=5687994c96
web-5687994c96-spvjm   1/1     Running   app=web,pod-template-hash=5687994c96

Hai label: app=web (ta đặt trong manifest Bài 4) và pod-template-hash=... (Deployment tự thêm). Cái thứ hai đáng để ý — nó chính là cách ReplicaSet phân biệt "pod của phiên bản nào" trong lúc rolling update (Bài 4): mỗi ReplicaSet có một hash riêng, dán lên pod nó tạo. Hệ thống tự dùng label để quản chính nó.

Gắn/đổi label thủ công:

kubectl label pod web-5687994c96-682pg tier=frontend
pod/web-5687994c96-682pg labeled

Selectors: chọn lọc theo label

Selector là truy vấn lọc đối tượng theo label. Đây là thứ Deployment và Service đã âm thầm dùng. Lọc bằng cờ -l:

kubectl get pods -l 'app=web,tier=frontend'    # khớp: 1 (pod vừa gắn)
kubectl get pods -l app=web                     # khớp: 3 (tất cả pod web)

Dấu phẩy nghĩa là ANDapp=web,tier=frontend chọn pod có cả hai nhãn. Ngoài bằng nhau, selector còn hỗ trợ các phép khác: env in (prod,staging), tier!=backend, hay chỉ cần tồn tại một key (tier).

Đây chính là cơ chế ta gặp suốt mấy bài qua:

   Service "web"  ──selector app=web──►  mọi pod có nhãn app=web
   Deployment "web" ──selector app=web──►  quản pod có nhãn app=web

Vì là chọn động, nó tự bao trùm pod mới: pod nào được dán đúng nhãn là tự động lọt vào tầm Service/Deployment, không cần khai báo lại. Đó là lý do self-healing và scale (Bài 4) "vừa khít" với cân bằng tải của Service (Bài 5) — tất cả nói chung một ngôn ngữ label.

Một mẹo thực tế: nhãn chuẩn khuyến nghị

Kubernetes khuyến nghị một bộ nhãn chung (app.kubernetes.io/name, app.kubernetes.io/version, app.kubernetes.io/part-of...) để công cụ và con người hiểu tài nguyên đồng nhất. Không bắt buộc, nhưng theo từ đầu thì cluster lớn dễ quản hơn nhiều — gắn nhãn nhất quán env, app, version giúp lọc log, gỡ lỗi, và áp chính sách về sau gọn gàng.

Tổng kết

Namespace chia cluster thành những ngăn cô lập tên (mọi cluster có sẵn default, kube-system...); dùng -n/--all-namespaces để làm việc xuyên suốt — nhưng nhớ namespace không tự chặn mạng. Label là cặp key=value gắn thẻ tự do lên đối tượng (kể cả những nhãn hệ thống tự thêm như pod-template-hash), và selector là truy vấn lọc theo nhãn (-l app=web, hỗ trợ AND/in/tồn tại). Đây là "chất keo" nền tảng: Deployment và Service tìm pod động qua selector, nên mọi cơ chế scale/self-healing/cân bằng tải mới ăn khớp với nhau.

Ứng dụng đã chạy và gọi được, nhưng cấu hình (biến môi trường, mật khẩu) vẫn nằm cứng trong image. Bài 7: ConfigMap và Secret — tách cấu hình ra khỏi image để cùng một image chạy được mọi môi trường.