Giới thiệu
Trong môi trường Kubernetes, việc xác thực và phân quyền truy cập AWS là một thách thức lớn. Các phương pháp truyền thống thường yêu cầu tạo người dùng IAM với khóa truy cập vĩnh viễn và lưu trữ chúng trong cluster. Tuy nhiên, những giải pháp hiện đại đã loại bỏ hoàn toàn việc lưu trữ thông tin xác thực này, thay vào đó sử dụng các mã thông báo tạm thời theo nguyên tắc tối thiểu hóa quyền hạn. Hãy tưởng tượng như việc nâng cấp từ chìa khóa vật lý sang thẻ thông minh cho các workload trong Kubernetes - thay vì lưu trữ chìa khóa chính trong mỗi pod, các container nhận thẻ truy cập tạm thời chỉ hoạt động cho các tài nguyên cụ thể và tự động hết hạn.
Phương pháp cũ: Lưu trữ thông tin xác thực (những điều cần tránh)
Trước khi đi sâu vào các giải pháp hiện đại, chúng ta cần hiểu rõ những gì mà chúng ta đang từ bỏ. Các phương pháp tiếp cận truyền thống để truy cập AWS từ Kubernetes thường bao gồm:
- Tạo người dùng IAM với khóa truy cập (AWS_ACCESS_KEY_ID và AWS_SECRET_ACCESS_KEY)
- Lưu trữ các thông tin xác thực này trong secrets của Kubernetes, biến môi trường hoặc tệp cấu hình
- Mã hóa chúng trực tiếp trong hình ảnh container hoặc mã ứng dụng
Dưới đây là cách mà điều này diễn ra trong một triển khai Kubernetes điển hình:
yaml
apiVersion: v1
kind: Secret
metadata:
name: aws-credentials
namespace: default
type: Opaque
data:
AWS_ACCESS_KEY_ID: ABCDEF
AWS_SECRET_ACCESS_KEY: GHIJKL
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: legacy-app
template:
metadata:
labels:
app: legacy-app
spec:
containers:
- name: legacy-app
image: my-app:latest
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: aws-credentials
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: aws-credentials
key: AWS_SECRET_ACCESS_KEY
- name: AWS_REGION
value: "us-west-2"
Phương pháp này tạo ra một số thách thức về bảo mật và vận hành trong môi trường Kubernetes:
Rủi ro bảo mật:
- Thông tin xác thực lâu dài không tự động hết hạn
- Các khóa có thể bị rò rỉ từ các container đang chạy hoặc secrets của Kubernetes
- Rò rỉ thông tin xác thực cung cấp quyền truy cập vĩnh viễn cho đến khi bị thu hồi thủ công
- Khó khăn trong việc kiểm toán việc sử dụng thông tin xác thực trên các pod và không gian tên
Thách thức vận hành:
- Quản lý luân chuyển khóa thủ công trên tất cả các pod và cluster
- Rắc rối trong việc quản lý thông tin xác thực khi các khóa được sao chép giữa các không gian tên và môi trường khác nhau
- Quản lý secrets phức tạp trên nhiều cluster Kubernetes
Phương pháp xác thực hiện đại cho Kubernetes
Các phương pháp xác thực AWS hiện đại từ Kubernetes loại bỏ việc lưu trữ thông tin xác thực bằng cách sử dụng các mã thông báo tạm thời tự động được làm mới. Có hai giải pháp chính cho xác thực Kubernetes-to-AWS:
IRSA (IAM roles for service accounts)
IRSA sử dụng OpenID Connect (OIDC) để kết nối các tài khoản dịch vụ Kubernetes với các vai trò IAM của AWS. Khi một pod cần truy cập AWS, nó sẽ trình bày một mã thông báo JWT mà AWS xác thực thông qua nhà cung cấp OIDC của cluster, nhận các thông tin xác thực tạm thời.
Cách hoạt động:
- Pod nhận một mã thông báo JWT từ máy chủ API Kubernetes một cách tự động
- AWS SDK bao gồm mã thông báo này trong các yêu cầu API
- AWS STS xác thực mã thông báo thông qua nhà cung cấp OIDC của cluster EKS
- STS trả về các thông tin xác thực AWS tạm thời cho pod
- Pod sử dụng các thông tin xác thực này để truy cập dịch vụ AWS
Xác thực pod EKS
Xác thực Pod EKS là phương pháp mới hơn của AWS, sử dụng một tiện ích mở rộng cluster tự động xử lý việc trao đổi thông tin xác thực. Một tác nhân Pod Identity chạy như một DaemonSet trên mỗi nút Kubernetes, chặn các cuộc gọi API AWS và lấy thông tin xác thực từ dịch vụ Pod Identity của AWS.
Cách hoạt động:
- Pod thực hiện các cuộc gọi API AWS thông qua AWS SDK
- Tác nhân Pod Identity (chạy như DaemonSet) chặn các cuộc gọi này
- Tác nhân yêu cầu thông tin xác thực từ dịch vụ Pod Identity EKS
- Dịch vụ trả về thông tin xác thực tạm thời cho tác nhân
- Cuộc gọi API gốc tiếp tục với thông tin xác thực hợp lệ
Triển khai với Terraform
Hãy triển khai cả hai phương pháp sử dụng các chính sách IAM nhất quán. Chúng ta sẽ sử dụng một chính sách truy cập S3 chung cho cả hai ví dụ mà các pod có thể sử dụng để truy cập các dịch vụ AWS:
hcl
resource "aws_iam_policy" "s3_access" {
name = "kubernetes-app-s3-access"
description = "Chính sách truy cập S3 cho các ứng dụng Kubernetes"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Resource = "arn:aws:s3:::my-k8s-app-bucket/*"
},
{
Effect = "Allow"
Action = [
"s3:ListBucket"
]
Resource = "arn:aws:s3:::my-k8s-app-bucket"
}
]
})
}
Cấu hình IRSA cho EKS
Cấu hình cluster EKS của bạn với OIDC được kích hoạt để hỗ trợ IRSA:
hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0.0"
cluster_name = "my-k8s-cluster"
cluster_version = "1.28"
enable_irsa = true
vpc_id = var.vpc_id
subnet_ids = var.private_subnets
eks_managed_node_groups = {
main = {
desired_size = 2
max_size = 4
min_size = 1
instance_types = ["t3.medium"]
}
}
}
Tạo vai trò IAM mà tài khoản dịch vụ Kubernetes của bạn sẽ đảm nhận:
hcl
module "irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
role_name = "k8s-app-irsa-role"
role_policy_arns = {
s3_access = aws_iam_policy.s3_access.arn
}
oidc_providers = {
main = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["default:k8s-app-service-account"]
}
}
}
Cấu hình xác thực pod EKS
Kích hoạt tiện ích mở rộng Pod Identity trong cluster EKS của bạn:
hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0.0"
cluster_name = "my-k8s-cluster"
cluster_version = "1.28"
cluster_addons = {
eks-pod-identity-agent = {
addon_version = "v1.3.4-eksbuild.1"
}
}
vpc_id = var.vpc_id
subnet_ids = var.private_subnets
eks_managed_node_groups = {
main = {
desired_size = 2
max_size = 4
min_size = 1
instance_types = ["t3.medium"]
}
}
}
Tạo mối liên kết Pod Identity để liên kết tài khoản dịch vụ Kubernetes của bạn với quyền AWS:
hcl
module "pod_identity" {
source = "terraform-aws-modules/eks-pod-identity/aws"
name = "k8s-app-pod-identity"
additional_policy_arns = {
S3Access = aws_iam_policy.s3_access.arn
}
associations = {
default = {
cluster_name = module.eks.cluster_name
namespace = "default"
service_account = "k8s-app-service-account"
}
}
}
Tài liệu Kubernetes
Triển khai ứng dụng IRSA
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-app-service-account
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/k8s-app-irsa-role
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-app-irsa
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: k8s-app-irsa
template:
metadata:
labels:
app: k8s-app-irsa
spec:
serviceAccountName: k8s-app-service-account
containers:
- name: app
image: my-app:latest
env:
- name: AWS_REGION
value: "us-west-2"
ports:
- containerPort: 8080
Triển khai ứng dụng Pod Identity
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-app-service-account
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-app-pod-identity
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: k8s-app-pod-identity
template:
metadata:
labels:
app: k8s-app-pod-identity
spec:
serviceAccountName: k8s-app-service-account
containers:
- name: app
image: my-app:latest
env:
- name: AWS_REGION
value: "us-west-2"
ports:
- containerPort: 8080
Lưu ý rằng cả hai phương pháp hiện đại đều loại bỏ hoàn toàn nhu cầu về thông tin xác thực được lưu trữ trong cluster Kubernetes của bạn. Triển khai Pod Identity thậm chí đơn giản hơn, không yêu cầu chú thích đặc biệt nào trên tài khoản dịch vụ.
So sánh các phương pháp hiện đại cho Kubernetes
Điểm mạnh và hạn chế của IRSA
Điểm mạnh:
- Hoạt động với bất kỳ cluster Kubernetes nào, không chỉ EKS
- Công nghệ trưởng thành với sự hỗ trợ cộng đồng rộng rãi
- Kiểm soát chi tiết đối với cấu hình mã thông báo JWT
- Tương thích với các hệ thống và mạng dịch vụ khác dựa trên OIDC
Hạn chế:
- Cài đặt phức tạp hơn và khó khăn trong việc xử lý sự cố trong Kubernetes
- Yêu cầu cấu hình nhà cung cấp OIDC ở cấp cluster
- Mã thông báo JWT có thể trở nên lớn và gây ra vấn đề với một số ứng dụng
- Cần quản lý chú thích thủ công cho mỗi tài khoản dịch vụ
Điểm mạnh và hạn chế của Pod Identity
Điểm mạnh:
- Cài đặt và quản lý đơn giản hơn trong EKS
- Tích hợp AWS bản địa với hiệu suất tốt hơn
- Tự động làm mới và luân chuyển thông tin xác thực do tác nhân xử lý
- Có khả năng ghi lại kiểm toán tích hợp thông qua CloudTrail
- Không có giới hạn kích thước mã thông báo JWT hoặc độ phức tạp
Hạn chế:
- Giải pháp chỉ dành cho EKS, không thể di chuyển sang các phân phối Kubernetes khác
- Công nghệ mới hơn với ít kiến thức và hướng dẫn xử lý sự cố từ cộng đồng
- Yêu cầu phiên bản cluster EKS 1.24 trở lên
- Ít tùy chỉnh linh hoạt hơn so với các phương pháp dựa trên OIDC
Thực hành bảo mật tốt nhất cho workloads Kubernetes
Bất kể bạn chọn phương pháp nào cho cluster Kubernetes của mình, hãy tuân theo những nguyên tắc bảo mật này:
Nguyên tắc tối thiểu hóa quyền hạn:
hcl
# Tốt: Quyền truy cập cụ thể cho các tài nguyên cụ thể mà các pod sử dụng
resource "aws_iam_policy" "restricted_s3" {
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["s3:GetObject"]
Resource = "arn:aws:s3:::k8s-specific-bucket/app-folder/*"
}
]
})
}
# Tránh: Quyền hạn quá rộng mà các pod không cần
resource "aws_iam_policy" "too_broad" {
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["s3:*"]
Resource = "*"
}
]
})
}
Các biện pháp bảo mật bổ sung cho Kubernetes:
- Sử dụng cách ly namespace Kubernetes để giới hạn phạm vi tài khoản dịch vụ
- Triển khai kiểm toán thường xuyên việc sử dụng vai trò và quyền trên các cluster
- Giám sát việc sử dụng thông tin xác thực thông qua AWS CloudTrail và nhật ký kiểm toán Kubernetes
- Thiết lập cảnh báo cho các mẫu truy cập bất thường từ các pod
- Sử dụng Kubernetes Network Policies để hạn chế giao tiếp giữa các pod
- Thường xuyên xem xét và luân chuyển bất kỳ thông tin xác thực lâu dài nào còn lại trong cluster của bạn
Lựa chọn phương pháp phù hợp
Chọn IRSA khi:
- Bạn cần hỗ trợ đa đám mây hoặc hybrid cho Kubernetes
- Bạn có yêu cầu tích hợp OIDC phức tạp
- Nhóm của bạn có kinh nghiệm IRSA hiện có
- Bạn cần kiểm soát mã thông báo chi tiết
Chọn Pod Identity khi:
- Bạn chỉ sử dụng EKS
- Bạn muốn giảm thiểu gánh nặng quản lý
- Bạn bắt đầu các dự án mới từ đầu
- Bạn ưu tiên các giải pháp bản địa AWS
Di chuyển từ thông tin xác thực đã lưu khi:
- Bạn đang sử dụng các khóa truy cập lâu dài
- Bạn muốn cải thiện tư thế bảo mật
- Bạn cần luân chuyển thông tin xác thực tốt hơn
- Bạn muốn giảm thiểu gánh nặng vận hành
Kết luận
Các phương pháp xác thực AWS hiện đại loại bỏ rủi ro bảo mật và phức tạp trong vận hành của việc lưu trữ thông tin xác thực trong môi trường Kubernetes. Cả IRSA và Xác thực Pod EKS đều cung cấp truy cập thông tin xác thực tạm thời an toàn, tuân thủ các thực tiễn bảo mật đám mây trong khi tích hợp liền mạch với quy trình làm việc của Kubernetes.
Đối với các dự án EKS mới, Pod Identity cung cấp con đường đơn giản nhất với tích hợp AWS bản địa và giảm thiểu gánh nặng quản lý. Đối với các môi trường Kubernetes hiện có hoặc yêu cầu đa nền tảng, IRSA cung cấp độ tin cậy và linh hoạt đã được chứng minh trên các loại cluster khác nhau.
Bước quan trọng nhất là từ bỏ hoàn toàn thông tin xác thực đã lưu trữ trong các cluster Kubernetes của bạn. Hãy chọn phương pháp hiện đại phù hợp nhất với chuyên môn và yêu cầu hạ tầng của đội ngũ bạn - cả hai đều đại diện cho những cải tiến đáng kể so với quản lý thông tin xác thực truyền thống và sẽ nâng cao tư thế bảo mật của cluster trong khi đơn giản hóa các hoạt động.