EKS Authentication & Authorization
Authentication (AuthN) và Authorization (AuthZ) trong EKS hoạt động theo 2 lớp tách biệt: AWS IAM xác thực danh tính, Kubernetes RBAC kiểm soát quyền truy cập vào resource trong cluster.
🔐 1. Tổng quan - Luồng xác thực
Điểm quan trọng:
- AWS IAM chỉ làm nhiệm vụ xác thực (ai đang gọi?).
- Kubernetes RBAC mới là nơi kiểm soát quyền (được làm gì?).
- Mapping giữa IAM identity và K8s user/group được quản lý qua Access Entries (cách mới) hoặc aws-auth ConfigMap (cách cũ).
🗂️ 2. aws-auth ConfigMap (Legacy)
2.1. aws-auth là gì?
aws-auth là một ConfigMap nằm trong namespace kube-system, dùng để map IAM user/role sang Kubernetes username và group.
AWS khuyến cáo dùng EKS Access Entries thay thế. aws-auth vẫn hoạt động nhưng dễ gây lỗi vì:
- Chỉnh sửa sai cú pháp YAML có thể lock out toàn bộ cluster.
- Không có API riêng, chỉ là ConfigMap thông thường.
- Không audit trail rõ ràng.
2.2. Cấu trúc aws-auth
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
# Node group role - bắt buộc để worker node join cluster
- rolearn: arn:aws:iam::123456789012:role/eks-node-group-role
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
# Dev team role
- rolearn: arn:aws:iam::123456789012:role/dev-team-role
username: dev-user
groups:
- dev-group
mapUsers: |
# Individual IAM user (ít dùng, nên dùng role)
- userarn: arn:aws:iam::123456789012:user/admin-user
username: admin-user
groups:
- system:masters
2.3. Chỉnh sửa aws-auth an toàn
Dùng eksctl thay vì sửa trực tiếp bằng kubectl edit:
# Thêm IAM role
eksctl create iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1 \
--arn arn:aws:iam::123456789012:role/dev-team-role \
--username dev-user \
--group dev-group
# Xem danh sách mapping
eksctl get iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1
# Xóa mapping
eksctl delete iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1 \
--arn arn:aws:iam::123456789012:role/dev-team-role
🔑 3. EKS Access Entries (Cách mới - Khuyên dùng)
3.1. Access Entries là gì?
EKS Access Entries là cách quản lý authentication mapping thông qua AWS API thay vì ConfigMap. Ra đời từ EKS 1.28.
Ưu điểm so với aws-auth:
- Quản lý qua AWS Console, CLI, SDK, Terraform — có đầy đủ audit trail trong CloudTrail.
- Không thể vô tình lock out cluster do lỗi YAML.
- Hỗ trợ IAM Roles, IAM Users, và cả EC2 Instance Profiles.
- Tích hợp với AWS Identity Center (SSO).
3.2. Access Policy Types
AWS cung cấp sẵn một số policy:
| Policy | Mô tả |
|---|---|
AmazonEKSClusterAdminPolicy | Full admin (tương đương system:masters) |
AmazonEKSAdminPolicy | Admin nhưng không quản lý cluster-level resource |
AmazonEKSEditPolicy | Đọc/ghi workload thông thường |
AmazonEKSViewPolicy | Chỉ đọc |
3.3. Tạo Access Entry bằng AWS CLI
# Bước 1: Tạo access entry cho IAM Role
aws eks create-access-entry \
--cluster-name my-cluster \
--region ap-southeast-1 \
--principal-arn arn:aws:iam::123456789012:role/dev-team-role \
--type STANDARD \
--kubernetes-groups dev-group
# Bước 2: Gán Access Policy
aws eks associate-access-policy \
--cluster-name my-cluster \
--region ap-southeast-1 \
--principal-arn arn:aws:iam::123456789012:role/dev-team-role \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \
--access-scope type=namespace,namespaces=dev-namespace
--access-scope type=namespace,namespaces=dev-namespace giới hạn quyền chỉ trong namespace dev-namespace. Dùng type=cluster để cấp quyền toàn cluster.
3.4. Tạo Access Entry bằng Terraform
resource "aws_eks_access_entry" "dev_team" {
cluster_name = aws_eks_cluster.main.name
principal_arn = "arn:aws:iam::123456789012:role/dev-team-role"
type = "STANDARD"
}
resource "aws_eks_access_policy_association" "dev_team_view" {
cluster_name = aws_eks_cluster.main.name
principal_arn = aws_eks_access_entry.dev_team.principal_arn
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
access_scope {
type = "namespace"
namespaces = ["dev-namespace"]
}
}
3.5. Enable Access Entry mode cho cluster
Khi tạo cluster mới hoặc migrate:
aws eks update-cluster-config \
--name my-cluster \
--region ap-southeast-1 \
--access-config authenticationMode=API_AND_CONFIG_MAP
Các mode:
CONFIG_MAP— Chỉ dùng aws-auth (legacy, default cho cluster cũ).API_AND_CONFIG_MAP— Hỗ trợ cả hai (dùng khi đang migrate).API— Chỉ dùng Access Entries (khuyến nghị cho cluster mới).
🏷️ 4. Kubernetes RBAC
Sau khi IAM identity đã được map sang K8s username/group, RBAC kiểm soát quyền thực sự.
4.1. Các khái niệm chính
- Role — Cấp quyền trong phạm vi 1 namespace.
- ClusterRole — Cấp quyền toàn cluster.
- RoleBinding — Gắn Role vào user/group trong 1 namespace.
- ClusterRoleBinding — Gắn ClusterRole vào user/group ở phạm vi cluster.
4.2. Ví dụ: Role + RoleBinding cho dev team
# Role: chỉ cho phép xem Pods và Deployments trong namespace dev
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-readonly
namespace: dev-namespace
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
---
# RoleBinding: gắn Role vào group "dev-group"
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-readonly-binding
namespace: dev-namespace
subjects:
- kind: Group
name: dev-group # Phải khớp với group trong aws-auth hoặc Access Entry
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-readonly
apiGroup: rbac.authorization.k8s.io
4.3. Kiểm tra quyền
# Kiểm tra quyền của chính mình
kubectl auth can-i get pods -n dev-namespace
# Kiểm tra quyền của user khác (admin)
kubectl auth can-i get pods -n dev-namespace --as=dev-user
kubectl auth can-i create deployments -n dev-namespace --as-group=dev-group --as=fake-user
# Liệt kê tất cả quyền của service account
kubectl auth can-i --list --as=system:serviceaccount:default:my-sa
☁️ 5. IRSA - IAM Roles for Service Accounts
5.1. Vấn đề: Pod cần truy cập AWS
Khi Pod cần gọi AWS API (S3, DynamoDB, SQS...), không được hardcode credentials vào Pod. IRSA là giải pháp chính thống.
5.2. Cơ chế hoạt động
Luồng hoạt động:
- EKS cluster có OIDC Provider.
- Service Account được annotate với IAM Role ARN.
- Pod dùng Service Account đó nhận OIDC token tự động.
- AWS SDK trong Pod dùng token để call STS
AssumeRoleWithWebIdentity. - STS trả về temporary credentials.
5.3. Thiết lập IRSA
Bước 1: Tạo OIDC Provider cho cluster
eksctl utils associate-iam-oidc-provider \
--cluster my-cluster \
--region ap-southeast-1 \
--approve
Bước 2: Tạo IAM Role với Trust Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account",
"oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
}
}
}
]
}
Bước 3: Annotate Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-s3-role
Cách nhanh hơn với eksctl:
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace default \
--name my-service-account \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve
5.4. Sử dụng trong Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: s3-reader
spec:
template:
spec:
serviceAccountName: my-service-account # Dùng SA đã annotate
containers:
- name: app
image: amazon/aws-cli:latest
command: ["aws", "s3", "ls", "s3://my-bucket"]
# AWS SDK tự động lấy credentials từ OIDC token
# Không cần env AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
🆔 6. EKS Pod Identity (Cách mới hơn IRSA)
6.1. EKS Pod Identity là gì?
EKS Pod Identity là cơ chế thế hệ mới (GA từ EKS 1.28) thay thế IRSA, đơn giản hơn và không phụ thuộc vào OIDC Provider của cluster.
So sánh IRSA vs Pod Identity:
| Tiêu chí | IRSA | EKS Pod Identity |
|---|---|---|
| OIDC Provider | Cần tạo per cluster | Không cần |
| Trust Policy | Ghi cụ thể cluster OIDC URL | Dùng pods.eks.amazonaws.com chung |
| Reusable IAM Role | Phải tạo role mới cho từng cluster | Dùng lại role cho nhiều cluster |
| Cấu hình | Annotate Service Account | Pod Identity Association |
| Cần addon | Không | Pod Identity Agent addon |
6.2. Thiết lập Pod Identity
Bước 1: Cài Pod Identity Agent addon
aws eks create-addon \
--cluster-name my-cluster \
--addon-name eks-pod-identity-agent \
--region ap-southeast-1
Bước 2: Tạo IAM Role với Trust Policy đơn giản hơn
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
Bước 3: Tạo Pod Identity Association
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--region ap-southeast-1 \
--namespace default \
--service-account my-service-account \
--role-arn arn:aws:iam::123456789012:role/my-app-role
Hoặc bằng Terraform:
resource "aws_eks_pod_identity_association" "app" {
cluster_name = aws_eks_cluster.main.name
namespace = "default"
service_account = "my-service-account"
role_arn = aws_iam_role.app_role.arn
}
AWS khuyến nghị dùng EKS Pod Identity cho cluster mới. Trust Policy không còn gắn với OIDC URL của cluster cụ thể, nên role có thể tái sử dụng dễ dàng.
📊 7. Tóm tắt - So sánh các cơ chế
7.1. Human/System Access vào cluster
| Cơ chế | Trường hợp dùng | Khuyến nghị |
|---|---|---|
| aws-auth ConfigMap | Cluster cũ, trước EKS 1.28 | ⚠️ Legacy, hạn chế dùng |
| EKS Access Entries | Cluster EKS 1.28+ | ✅ Khuyên dùng |
7.2. Pod Access vào AWS Services
| Cơ chế | Trường hợp dùng | Khuyến nghị |
|---|---|---|
| IRSA | Cluster cũ, tương thích rộng | ✅ Vẫn hoạt động tốt |
| EKS Pod Identity | Cluster EKS 1.28+ | ✅ Khuyên dùng cho cluster mới |
7.3. Checklist bảo mật
- Không dùng
system:masterscho developer — dùng Access Policy có scope namespace. - Không hardcode AWS credentials trong Pod — dùng IRSA hoặc Pod Identity.
- Áp dụng Least Privilege cho cả IAM Policy và RBAC Role.
- Bật CloudTrail để audit API call lên EKS.
- Enable Access Logging cho EKS API Server endpoint.
- Dùng Private Endpoint khi có thể, hạn chế Public Endpoint.