Namespace, Labels và Selectors
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ợ đó: label và selector 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 web ở default và 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ư
kubensgiú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à AND — app=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.