Cơ chế xác thực và phân quyền trong Kubernetes API Server

Kube-apiserver là thành phần cốt lõi của cụm Kubernetes, đóng vai trò trung tâm trong việc xử lý mọi tương tác với hệ thống. Nó không chỉ cung cấp giao diện REST cho quản trị cụm mà còn đảm bảo tính toàn vẹn và bảo mật thông qua chuỗi kiểm soát truy cập gồm ba giai đoạn: xác thực (authentication), phân quyền (authorization) và kiểm soát đầu vào (admission control). Mọi thành phần trong hệ sinh thái — từ controller manager đến kubelet — đều phải giao tiếp với etcd thông qua API Server; việc truy cập trực tiếp vào etcd bị cấm hoàn toàn.

Các phương thức xác thực được hỗ trợ

Kubernetes hỗ trợ nhiều cơ chế xác thực đồng thời trên cổng an toàn (secure-port), trong đó mỗi plugin hoạt động độc lập và chỉ cần một trong số chúng xác nhận thành công để yêu cầu được chuyển sang bước phân quyền. Cổng không an toàn (insecure-port) đã bị loại bỏ từ phiên bản 1.20 trở đi do rủi ro bảo mật cao.

1. Chứng chỉ X.509

API Server sử dụng chứng chỉ CA để xác minh danh tính người dùng hoặc thành phần gửi yêu cầu. Tệp CA được chỉ định qua tham số khởi động --client-ca-file. Khi một yêu cầu kèm theo chứng chỉ client hợp lệ được ký bởi CA này, tên người dùng (CN field) và nhóm (O field) sẽ được trích xuất làm thông tin xác thực.

2. Tệp token tĩnh

Tệp CSV chứa danh sách token có cấu trúc: <token>,<username>,<uid>[,<group1>,<group2>...]. Được kích hoạt bằng cờ --token-auth-file, cơ chế này phù hợp cho môi trường nhỏ hoặc thử nghiệm nhưng không khuyến khích dùng trong sản xuất do thiếu khả năng xoay vòng và thu hồi linh hoạt.

3. Bootstrap Token

Là dạng token động được lưu dưới dạng Secret trong namespace kube-system, thường được tạo và quản lý bởi kubeadm. Các token này có thời hạn sống ngắn (mặc định 24 giờ) và tự động bị xóa bởi controller TokenCleaner. Chúng chủ yếu phục vụ cho quy trình khởi tạo cụm hoặc thêm node mới một cách an toàn.

4. Xác thực cơ bản (Basic Auth)

Mặc dù vẫn tồn tại, cơ chế này (kích hoạt bằng --basic-auth-file) không còn được khuyến nghị vì tính chất tĩnh và dễ bị lộ thông tin đăng nhập. Mỗi dòng trong tệp phải có ít nhất ba trường: mật khẩu, tên người dùng và UID.

5. ServiceAccount Token

Mỗi ServiceAccount tự động được cấp một Secret chứa JWT token, được mount vào pod dưới đường dẫn /var/run/secrets/kubernetes.io/serviceaccount/token. Token này được ký bởi private key của API Server và có thể được xác thực cục bộ mà không cần gọi dịch vụ bên ngoài.

6. Webhook Authentication

Cơ chế mở rộng cho phép tích hợp với hệ thống xác thực bên ngoài (như LDAP, OIDC, hoặc hệ thống IAM tùy chỉnh). API Server gửi yêu cầu xác thực tới endpoint được cấu hình trong tệp YAML thông qua --authentication-token-webhook-config-file. Kết quả được lưu cache trong khoảng thời gian xác định bởi --authentication-token-webhook-cache-ttl (mặc định 2 phút).

Quy trình phân quyền (Authorization)

Sau khi xác thực thành công, yêu cầu được chuyển tới module phân quyền. Kubernetes hỗ trợ bốn plugin chính: Node, ABAC, RBACWebhook. Trong đó, RBAC là mô hình được sử dụng phổ biến nhất nhờ tính linh hoạt và khả năng kiểm soát chi tiết.

Các yếu tố quyết định phân quyền

  • Thông tin người dùng: tên, nhóm, thuộc tính bổ sung (extra)
  • Phương thức HTTP và đường dẫn API (ví dụ: GET /api/v1/namespaces/default/pods)
  • Tài nguyên và tài nguyên con (resource/subresource)
  • Namespace liên quan
  • API Group (ví dụ: apps, batch, rbac.authorization.k8s.io)

Cấu trúc RBAC

RABC phân biệt rõ giữa phạm vi cụm (ClusterRole, ClusterRoleBinding) và phạm vi namespace (Role, RoleBinding). Một Role chỉ áp dụng trong một namespace duy nhất, trong khi ClusterRole có thể đề cập đến cả tài nguyên cụm (như Nodes, ClusterRoles) lẫn tài nguyên trong namespace.

Ví dụ cấu hình RBAC

Dưới đây là ví dụ về việc cấp quyền đọc Pod trong namespace default cho người dùng alice:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
  namespace: default
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Và đây là ví dụ cấp quyền đọc Secret trên toàn bộ cụm cho nhóm devops-team:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: devops-secret-access
subjects:
- kind: Group
  name: devops-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Một số nhóm hệ thống phổ biến

Khi định nghĩa subjects, các nhóm đặc biệt sau thường được sử dụng:

  • system:serviceaccounts:<namespace>: Tất cả ServiceAccount trong namespace cụ thể
  • system:serviceaccounts: Tất cả ServiceAccount trong mọi namespace
  • system:authenticated: Tất cả người dùng đã qua xác thực
  • system:unauthenticated: Người dùng chưa xác thực (thường dùng cho endpoint public như healthz)

Phân tích role mặc định

Role cluster-admin là quyền cao nhất trong hệ thống, cho phép truy cập mọi API group, tài nguyên và endpoint không thuộc tài nguyên (non-resource URLs) với mọi hành động:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-admin
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
- nonResourceURLs: ["*"]
  verbs: ["*"]

Để cấp quyền này cho một người dùng cụ thể (ví dụ: dev-admin) trong namespace default, ta sử dụng RoleBinding tham chiếu tới ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-cluster-admin
  namespace: default
subjects:
- kind: User
  name: dev-admin
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

Thẻ: Kubernetes rbac authentication authorization apiserver

Đăng vào ngày 19 tháng 5 lúc 21:39