EKS Pod Identity

EKS Pod Identity

·

9 min read

EKS Pod Identity là một giải pháp trong Amazon Elastic Kubernetes Service (EKS) cho phép các pod trong Kubernetes cluster có thể truy cập an toàn vào các dịch vụ AWS mà không cần sử dụng các thông tin xác thực (credentials) tĩnh như Access Key hoặc Secret Key. Thay vào đó, EKS Pod Identity sử dụng IAM roles (Identity and Access Management roles) gắn với pod để cung cấp quyền truy cập động và bảo mật.

Các thành phần chính của EKS Pod Identity:

  1. IAM Roles for Service Accounts (IRSA):

    • Đây là cơ chế cho phép gán IAM role trực tiếp cho Kubernetes Service Account. Khi một pod sử dụng Service Account này, nó sẽ tự động thừa hưởng IAM role tương ứng để truy cập tài nguyên AWS.
  2. Service Account:

    • Mỗi pod trong Kubernetes thường sử dụng một Service Account. Với IRSA, Service Account này được liên kết với IAM role, và pod sử dụng Service Account đó sẽ có các quyền được xác định trong IAM role.
  3. OIDC Provider:

    • Để xác thực giữa Kubernetes Service Account và IAM role, EKS sử dụng OpenID Connect (OIDC). Bạn cần đăng ký OIDC provider với IAM để hệ thống có thể xác thực danh tính của các pod.

eks-blueprint-blue

Quy trình hoạt động:

  1. Thiết lập IAM Role và Service Account:

    • Bạn tạo một IAM role với các quyền cần thiết và liên kết nó với một Service Account trong Kubernetes bằng cách sử dụng annotation trên Service Account.
  2. Pod Deployment:

    • Khi bạn triển khai một pod và nó sử dụng Service Account đã được liên kết với IAM role, pod sẽ tự động lấy được các quyền từ IAM role.
  3. Truy cập tài nguyên AWS:

    • Khi pod cần truy cập tài nguyên AWS (ví dụ: S3, DynamoDB), nó sử dụng IAM role để lấy các token tạm thời, mà không cần phải sử dụng thông tin xác thực tĩnh.

Lợi ích của EKS Pod Identity:

  • Bảo mật tốt hơn: Giảm thiểu rủi ro bảo mật vì không cần lưu trữ hoặc quản lý thông tin xác thực tĩnh trong pod.

  • Quản lý quyền dễ dàng: Dễ dàng quản lý và điều chỉnh quyền truy cập của các pod bằng cách thay đổi IAM role mà không cần thay đổi cấu hình trong pod.

  • Tuân thủ tốt hơn: Đảm bảo tuân thủ các tiêu chuẩn bảo mật của AWS khi truy cập tài nguyên AWS.

Để sử dụng IRSA (IAM Roles for Service Accounts), Service Account, và OIDC Provider để truy cập vào S3 mà không cần dùng thông tin xác thực tĩnh trong pod, bạn có thể thực hiện các bước sau:

Bước 1: Thiết lập OIDC Provider cho EKS Cluster

Trước tiên, bạn cần phải đảm bảo rằng OIDC provider đã được thiết lập cho EKS cluster của bạn.

  1. Xác định URL của OIDC provider:

     aws eks describe-cluster --name <cluster-name> --query "cluster.identity.oidc.issuer" --output text
    

    Output sẽ trông như thế này: https://oidc.eks.<region>.amazonaws.com/id/<eks-cluster-id>

  2. Tạo OIDC provider (nếu chưa có):

     eksctl utils associate-iam-oidc-provider --cluster <cluster-name> --approve
    

Bước 2: Tạo IAM Role cho Service Account

  1. Tạo file JSON trust policy để chỉ cho phép các Service Account trong EKS cluster của bạn có thể assume role này:

    trust-policy.json:

     {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Principal": {
                     "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.eks.<region>.amazonaws.com/id/<eks-cluster-id>"
                 },
                 "Action": "sts:AssumeRoleWithWebIdentity",
                 "Condition": {
                     "StringEquals": {
                         "oidc.eks.<region>.amazonaws.com/id/<eks-cluster-id>:sub": "system:serviceaccount:<namespace>:<service-account-name>"
                     }
                 }
             }
         ]
     }
    

    trust-policy.json là một tệp JSON chứa một chính sách trust (tin cậy) được sử dụng để xác định các thực thể nào được phép "assume" (thực hiện vai trò của) một IAM role cụ thể trong AWS. Chính sách này được gọi là Assume Role Policy và nó quy định rằng thực thể nào có thể lấy các quyền của IAM role được chỉ định.

    • Xác định sự tin cậy: Nó định nghĩa rằng Service Account của Kubernetes, xác thực qua OIDC provider của EKS, được phép assume IAM role này.

    • Bảo mật: Bằng cách giới hạn chỉ một Service Account cụ thể trong một namespace cụ thể được phép assume IAM role, bạn giảm thiểu khả năng các thực thể không mong muốn có thể lấy quyền truy cập

Khi bạn tạo một IAM role, bạn cần phải chỉ định ai có quyền sử dụng role đó. Trong trường hợp của EKS với IRSA, bạn muốn Kubernetes Service Account có thể assume IAM role này để lấy các quyền truy cập vào tài nguyên AWS, như S3. Điều này được thực hiện bằng cách thiết lập một trust relationship giữa OIDC provider của EKS và IAM role.

  • Principal: Xác định ai hoặc cái gì có thể assume role này. Trong trường hợp của IRSA, principal là OIDC provider của EKS cluster của bạn. Đó là lý do tại sao bạn thấy Federated được chỉ định với ARN của OIDC provider.

  • Effect: Chỉ định hiệu lực của chính sách (thường là "Allow").

  • Action: Xác định hành động mà principal được phép thực hiện, trong trường hợp này là "sts:AssumeRoleWithWebIdentity".

  • Condition: Một tập hợp các điều kiện mà IAM role sẽ áp dụng. Trong trường hợp này, điều kiện yêu cầu principal chỉ có thể assume role nếu nó là một Kubernetes Service Account cụ thể (system:serviceaccount:<namespace>:<service-account-name>).

  1. Tạo IAM role với chính sách trust này:

     aws iam create-role --role-name <role-name> --assume-role-policy-document file://trust-policy.json
    
  2. Gán chính sách quyền truy cập S3 cho IAM role:

     aws iam attach-role-policy --role-name <role-name> --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
    

Bước 3: Tạo Service Account trong Kubernetes

  1. Tạo Service Account với annotation liên kết IAM role:

     yamlCopy codeapiVersion: v1
     kind: ServiceAccount
     metadata:
       name: <service-account-name>
       namespace: <namespace>
       annotations:
         eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<role-name>
    

    Áp dụng Service Account này trong Kubernetes:

     kubectl apply -f service-account.yaml
    

Bước 4: Triển khai Pod sử dụng Service Account này

  1. Triển khai pod sử dụng Service Account đã tạo ở trên:

     apiVersion: v1
     kind: Pod
     metadata:
       name: s3-access-pod
       namespace: <namespace>
     spec:
       serviceAccountName: <service-account-name>
       containers:
       - name: s3-access-container
         image: amazonlinux
         command: [ "/bin/bash", "-c", "--" ]
         args: [ "while true; do sleep 30; done;" ]
    

    Áp dụng cấu hình này:

     kubectl apply -f pod.yaml
    

Bước 5: Kiểm tra truy cập vào S3 từ pod

  1. Kết nối vào pod:

     kubectl exec -it s3-access-pod -- /bin/bash
    
  2. Cài đặt AWS CLI (nếu chưa có):

     yum install -y aws-cli
    
  3. Thực hiện lệnh truy cập S3:

     aws s3 ls s3://<bucket-name>
    

Pod của bạn sẽ có quyền truy cập vào S3 mà không cần phải sử dụng thông tin xác thực tĩnh (Access Key và Secret Key), vì nó đã được liên kết với IAM role thông qua IRSA và OIDC Provider.

Cách IRSA Hoạt Động

  1. Thiết lập OIDC Provider:

    • Khi bạn tạo một EKS cluster, AWS sẽ cung cấp một OpenID Connect (OIDC) provider cho cluster này. OIDC là một giao thức dựa trên OAuth 2.0, cho phép các ứng dụng xác thực người dùng hoặc dịch vụ bằng cách sử dụng tokens.

    • Bạn phải liên kết OIDC provider của cluster với IAM, tạo ra một kết nối giữa danh tính trong Kubernetes và IAM roles trong AWS.

  2. Tạo IAM Role với Trust Policy:

    • Bạn tạo một IAM role với một trust policy xác định rằng IAM role này chỉ có thể được assume bởi các Kubernetes Service Account, được xác thực thông qua OIDC provider.

    • Trust policy trong IAM role sẽ bao gồm ARN của OIDC provider và định danh của Service Account trong Kubernetes (ví dụ, system:serviceaccount:<namespace>:<service-account-name>).

  3. Liên Kết IAM Role với Service Account:

    • Trong Kubernetes, bạn tạo một Service Account và liên kết nó với IAM role đã tạo bằng cách thêm annotation eks.amazonaws.com/role-arn vào Service Account.

    • Mỗi pod sử dụng Service Account này sẽ tự động có thể assume IAM role liên kết, và do đó có quyền truy cập vào các tài nguyên AWS mà IAM role cung cấp.

  4. Pod Assume IAM Role:

    • Khi một pod được triển khai và sử dụng Service Account đã được liên kết với IAM role, Kubernetes API Server sẽ cấp cho pod một JSON Web Token (JWT) đại diện cho danh tính của pod đó.

    • Pod gửi JWT này đến AWS Security Token Service (STS) cùng với yêu cầu assume IAM role.

  5. AWS STS Cấp Token Tạm Thời:

    • AWS STS xác thực JWT thông qua OIDC provider để đảm bảo rằng yêu cầu đến từ một Service Account hợp lệ.

    • Nếu thành công, AWS STS sẽ trả về một set of temporary security credentials (bao gồm Access Key ID, Secret Access Key, và Session Token) có thời gian sống ngắn, cho phép pod truy cập các tài nguyên AWS như S3, DynamoDB, hoặc các dịch vụ khác.

  6. Pod Sử Dụng Token Để Truy Cập Dịch Vụ AWS:

    • Pod sử dụng các temporary credentials này để thực hiện các hành động trên dịch vụ AWS mà không cần lưu trữ hoặc quản lý các thông tin xác thực tĩnh.

  1. Pod yêu cầu thông tin xác thực (Step 1):

    • Pod đang chạy trong Kubernetes cluster cần truy cập vào một dịch vụ AWS, ví dụ như S3. Để làm điều này, nó sẽ sử dụng JWT token được tự động gắn kèm khi pod khởi chạy (được cấp bởi Service Account).

    • Pod gửi yêu cầu đến AWS Security Token Service (STS) kèm theo JWT và ARN của IAM Role, yêu cầu cấp thông tin xác thực tạm thời (temporary credentials) để thực hiện các hành động cụ thể, như liệt kê các S3 buckets.

  2. Gửi yêu cầu đến AWS IAM (Step 2):

    • AWS STS nhận được yêu cầu và sẽ gửi nó tới AWS IAM để xác thực và kiểm tra xem yêu cầu có hợp lệ hay không.
  3. Xác thực thông qua OIDC Identity Provider (Step 3):

    • AWS IAM sử dụng OIDC Identity Provider (đã được cấu hình khi thiết lập EKS cluster) để xác thực JWT token của pod.

    • OIDC Identity Provider sẽ kiểm tra public keys được lấy từ JWKS URL (cung cấp trong file .well-known/OpenID-configuration) để xác minh JWT.

  4. Kiểm tra quyền hạn (Step 4):

    • Sau khi JWT được xác thực thành công, IAM sẽ kiểm tra chính sách liên quan đến IAM Role để đảm bảo rằng pod có quyền thực hiện hành động yêu cầu (ví dụ: liệt kê S3 buckets).

    • Nếu tất cả đều hợp lệ, IAM sẽ chấp thuận yêu cầu.

  5. STS Cấp Temporary Credentials (Step 5):

    • AWS STS sẽ tạo và gửi về cho pod một bộ thông tin xác thực tạm thời (Temporary Credentials), bao gồm Access Key ID, Secret Access Key, và Session Token.

    • Pod sử dụng những thông tin này để thực hiện các yêu cầu đến dịch vụ AWS như S3.

  6. Pod sử dụng Temporary Credentials (Step 6):

    • Pod sử dụng AWS SDK cùng với Temporary Credentials vừa nhận được để thực hiện hành động mong muốn, chẳng hạn như liệt kê các S3 buckets.

Tóm tắt quy trình:

  • Pod: Gửi yêu cầu thông tin xác thực kèm JWT và ARN IAM Role để có quyền truy cập vào AWS.

  • OIDC Provider: Xác thực JWT với IAM Role dựa trên thông tin trong trust policy.

  • IAM: Kiểm tra và xác nhận quyền truy cập của pod dựa trên chính sách IAM Role.

  • STS: Cấp thông tin xác thực tạm thời nếu yêu cầu hợp lệ.

  • Pod: Sử dụng thông tin xác thực tạm thời để thực hiện các hành động trên dịch vụ AWS.