Node Log Query và Phân Quyền Kubelet Chi Tiết

K
Kai··4 min read

Bài 65 lấy log của kubelet và apiserver bằng journalctl — phải SSH vào đúng node. v1.36 đưa hai tính năng chạm tới chính cách đó: query log node qua API thay vì SSH, và siết quyền truy cập API kubelet ở mức từng endpoint. Cả hai đóng Part XIV và nối thẳng về Part I (kubelet ở Bài 11, RBAC apiserver→kubelet ở Bài 9).

Node Log Query: log node qua API

Kubelet có thể phục vụ log của các service systemd trên node qua endpoint /logs, gated sau một cờ config. Mặc định cờ tắt — xem trên cụm:

kubectl get --raw /api/v1/nodes/worker-0/proxy/configz | jq '.kubeletconfig.enableSystemLogQuery'
false

Bật nó (thêm enableSystemLogQuery: true vào kubelet config rồi restart kubelet — thao tác trên worker, như cách cấu hình kubelet ở Bài 11), rồi query log của một service thẳng qua API server:

kubectl get --raw "/api/v1/nodes/worker-0/proxy/logs/?query=kubelet&tailLines=3"
May 24 01:08:54 worker-0 kubelet[300312]: I0524 ... "SyncLoop (probe)" probe="readiness" status="ready" pod="kube-system/cilium-operator-..."
May 24 01:09:00 worker-0 kubelet[300312]: I0524 ... "SyncLoop (probe)" probe="readiness" status="ready" pod="kube-system/coredns-..."

Tham số query=kubelet chọn service; đổi sang containerd thì ra log runtime:

kubectl get --raw "/api/v1/nodes/worker-0/proxy/logs/?query=containerd&tailLines=1"
May 24 01:08:49 worker-0 containerd[2034]: ... level=info msg="container event discarded" ...

Đây là log journald của Bài 65, nhưng lấy qua API server thay vì SSH. Với cụm nhiều node, không phải đăng nhập từng máy để xem vì sao kubelet hay containerd trục trặc — query qua một đầu mối. Đổi lại, nó mở một đường đọc log node qua API, nên quyền truy cập đường đó cần được kiểm soát — dẫn thẳng sang phần sau.

Quyền API kubelet: từ một cục thành chi tiết

Mọi truy cập tới API kubelet (logs, metrics, exec, stats...) đều đi qua API server proxy, và API server hỏi authorizer trước. Trước đây câu hỏi đó gộp một cục: ai có get trên nodes/proxy thì vào được mọi endpoint kubelet — log, exec, metrics, tất cả. Một agent giám sát chỉ cần /metrics cũng phải được cấp nodes/proxy, tức là vô tình có luôn quyền exec vào pod trên node. v1.36 ổn định fine-grained kubelet authorization: mỗi endpoint thành một subresource riêng (nodes/metrics, nodes/log, nodes/configz, nodes/stats, nodes/healthz...), gác độc lập.

Dựng một ServiceAccount chỉ được nodes/metrics, không gì khác:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata: {name: kubelet-metrics-only}
rules:
- {apiGroups: [""], resources: ["nodes/metrics"], verbs: ["get"]}

(kèm một ClusterRoleBinding gắn nó vào SA metrics-reader.) Hỏi authorizer từng subresource — chú ý cú pháp --subresource, không phải nodes/metrics:

SA=system:serviceaccount:kauthz:metrics-reader
for sr in metrics proxy log healthz configz stats; do
  echo "nodes/$sr: $(kubectl auth can-i get nodes --subresource=$sr --as=$SA)"
done
nodes/metrics  -> yes
nodes/proxy    -> no
nodes/log      -> no
nodes/healthz  -> no
nodes/configz  -> no
nodes/stats    -> no

SA này đọc được /metrics của kubelet nhưng không exec (nodes/proxy), không đọc log (nodes/log) hay config (nodes/configz). Trước fine-grained authz, để cho nó /metrics phải cấp nodes/proxy — và thế là trao luôn cả exec lẫn log. Giờ cấp đúng cái cần, đúng nguyên tắc least-privilege của Bài 52. Hai tính năng bài này ăn khớp: Node Log Query mở đường đọc log node qua API, và fine-grained authz cho phép cấp riêng nodes/log cho người cần xem log mà không trao quyền exec.

🧹 Dọn dẹp

# revert kubelet worker-0 về cấu hình cũ (bỏ enableSystemLogQuery)
ssh worker-0 'sudo mv /var/lib/kubelet/kubelet-config.yaml.bak /var/lib/kubelet/kubelet-config.yaml; sudo systemctl restart kubelet'
kubectl delete namespace kauthz
kubectl delete clusterrole kubelet-metrics-only
kubectl delete clusterrolebinding kubelet-metrics-only

Node Log Query là một cờ config — bài này bật để thử rồi revert, trả worker-0 về nguyên trạng (enableSystemLogQuery: false). Fine-grained authz chỉ là object RBAC. Manifest ở github.com/nghiadaulau/kubernetes-from-scratch, thư mục 71-node-log-kubelet-authz.

Tổng kết

Hai tính năng v1.36 chạm tới kubelet của Part I. Node Log Query cho lấy log service node (kubelet, containerd...) qua endpoint /logs?query=<service> của kubelet, sau khi bật enableSystemLogQuery: true — ta query log kubelet và containerd của worker-0 qua API server, không SSH (so với journalctl của Bài 65). Fine-grained kubelet authorization tách quyền API kubelet, trước gộp trong nodes/proxy, thành từng subresource độc lập (nodes/metrics, nodes/log, nodes/configz...): một SA chỉ có nodes/metrics đọc được metrics nhưng không exec, không đọc log — least-privilege thật thay vì trao cả cụm quyền. Hai cái bổ nhau: query log node tiện hơn nhưng mở một bề mặt mới, và fine-grained authz cho cấp đúng quyền hẹp cho bề mặt đó.

Part XIV khép lại — bốn nhóm tính năng vừa graduate ở chính v1.36 mà cụm đang chạy: admission bằng CEL, in-place resize, storage mới, và quan sát/bảo mật kubelet. Còn lại đúng một việc của cả series: Bài 72 dọn dẹp toàn bộ hạ tầng và nhìn lại hành trình từ certificate đầu tiên tới đây.