こんにちは、クラウド事業部の山路です。
昨年12月のアップデートにより、Amazon EKSへのアクセス制御方法を Access Entry
というリソース/APIで実現できるようになりました。今回はこの新機能を簡単に検証してみます。
背景
Amazon EKSへのアクセスを制御する場合、これまではAWS、KubernetesのそれぞれのAPIに対するアクセス制御を設定する必要がありました。
※参考:
これによる課題はいくつかあります。
まず、アクセス制御を実現するための手順が複雑になります。クラスター管理者はAWS APIとKubernetes APIを行き来しながら設定変更を行うため、作業ミスの可能性も高くなります。例えば誤って aws-auth
ConfigMapを削除してしまうと、最悪の場合そのクラスターには誰もアクセスできなくなってしまいます。
また、クラスター作成者に付与される cluster-admin
権限が残り続けることも課題でした。たとえクラスター作成者がその後そのクラスターを操作しないとしてもroot権限が付与され続けることになり、強力な権限が関係のないアカウントに付与され続ける状態は、セキュリティ的にも大きな問題となりえます。
これを改善するため、Amazon EKS APIがAmazon EKSとKubernetesオブジェクトに対しAWS IAM principalを直接付与できるようになりました。これはつまりAWS側のリソースだけでEKSに対するアクセス制御を完結できるようになったことを意味します。
この仕組みを実現するため、Access Policy
Access Entry
という2つのリソースを利用します。Access Policy
は特定のクラスターアクションを実行するための権限を、 Access Entry
は Access Policy とそのポリシーを利用するIAMロール・ユーザーとの紐づけを管理します。
※画像: AWSブログより引用
Access Policy
Access Entry
を利用することで、EKSへのアクセス制御をAWS APIで完結できるようになります。これにより、例えばAWS CloudFormation / Terraform / AWS CDKといったIaCツールを使用して、クラスターのアクセス管理を実現できました。また、クラスター作成者に付与された cluster-admin
権限も取り除けるので、不必要に強い権限の付与を避けることができます。さらに設定ミスでクラスターへのアクセス権限を削除してしまった場合も、新しいAPIから権限を付与しなおすことで復旧できます。
なお、新しいAPI追加後も、従来通り aws-auth
ConfigMapによる権限管理は可能です。現在EKSへのアクセスには以下の3つの認証モードを利用できます。
CONFIG_MAP
: 従来通りaws-auth
ConfigMapによる認証API_AND_CONFIG_MAP
: 新しいAPIと従来のConfigMapによる認証をどちらも利用できるAPI
: 新しいAPIによる認証
2つ目の認証モードは新旧の認証モードを利用できるので、利用者は既存のConfigMapベースの認証からAPIベースの認証への移行がやりやすくなります。認証モードの切り替えは既存のクラスターに対する設定変更で実現可能であり、従来のConfigMapベースの認証とAPI認証を並行して利用することで、従来の権限を損なうことなくAPI認証モードへの移行を進めることができます。
なお、新しいAPIを利用する際はいくつか注意事項があります。
- 認証モードの切り替えは一方向です。切り替えは
CONFIG_MAP
→API_AND_CONFIG_MAP
→API
の方向に切り替え可能で、切り替え後は元のモードに戻すことはできません。 - API認証を利用するには、 ver 1.23以降のクラスターが必要です。また、指定のバージョン以上のPlatform versionを利用している必要もあります。
利用時の条件などは AWS公式ドキュメント もご確認ください。
検証
ここから実際に新しいアクセスコントロールを試します。以降の作業ではAWS CLIを利用するため、必要に応じてAWS CLIのバージョンを更新し、 list-access-policies
などの新しいコマンドを実行可能にします。
AWS CLIを更新後に list-access-policies
コマンドを実行すると、利用できるAccess Policyが出力されます。
$ aws eks list-access-policies { "accessPolicies": [ { "name": "AmazonEKSAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" }, { "name": "AmazonEKSClusterAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" }, { "name": "AmazonEKSEditPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" }, { "name": "AmazonEKSViewPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" } ] }
なお、ここで出力されるポリシーの権限は、Kubernetesに用意されたユーザー向けのロールに対応しています。
AmazonEKSClusterAdminPolicy
: cluster-adminAmazonEKSAdminPolicy
: adminAmazonEKSEditPolicy
: editAmazonEKSViewPolicy
: view
またAmazon EKSを作成済みの場合、 describe-cluster
コマンドを実行すると authenticationMode
というパラメータも確認できます。
$ aws eks describe-cluster --name eks-cluster --query 'cluster.accessConfig' { "authenticationMode": "CONFIG_MAP" }
認証モードの変更
API認証を利用するため、まずは authenticationMode
の変更を行います。クラスターを新規に作成する場合、AWS CLIでは以下のようなコマンドで指定できます。
$ aws eks create-cluster \ --name <CLUSTER_NAME> \ --role-arn <CLUSTER_ROLE_ARN> \ --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \ --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ --access-config authenticationMode=API
またAWS CloudFormationを利用する場合、 AWS::EKS::Cluster
の AccessConfig
というパラメータで指定します。
Type: AWS::EKS::Cluster Properties: AccessConfig: AuthenticationMode: String BootstrapClusterCreatorAdminPermissions: Boolean
既存のクラスターの設定を変更する場合、AWS CLIでは update-cluster-config
コマンドを使用します。
$ aws eks update-cluster-config \ --name <CLUSTER_NAME> \ --access-config authenticationMode=<Select auth mode>
今回はAWS CloudFormationでクラスターを作成していたので、ファイルに AccessConfig
を設定し、更新しました。
更新後、修正されていることを確認します。
$ aws cloudformation deploy --template-file eks-cluster.yaml \ --stack-name eks-cluster \ --capabilities CAPABILITY_IAM $ aws eks describe-cluster --name eks-cluster --query 'cluster.accessConfig' { "authenticationMode": "API_AND_CONFIG_MAP" }
なお、今回は BootstrapClusterCreatorAdminPermissions
というパラメータは特に指定しなかったため、作成したユーザーに対するアクセス権限が付与されています。CloudFormationで指定する場合はリソースのReplaceを必要とするのでご注意ください。
$ aws eks list-access-entries --cluster-name eks-cluster { "accessEntries": [ "arn:aws:iam::<AWS Account ID>:user/yamaji" ] }
EKSへのアクセスユーザーを追加
ここで、別のユーザーに対してクラスターへのアクセス権を付与します。
AWS CLIの場合、アクセス権を付与するため、まずは新しいアクセスエントリーを作成します。
$ aws eks create-access-entry \ --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN>
その後、作成したアクセスエントリーとアクセスポリシーを紐づけることで、権限付与は完了します。
$ aws eks associate-access-policy \ --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN> \ --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster
今回はCloudFormationで以下のようなテンプレートを使用します。
AWSTemplateFormatVersion: 2010-09-09 Description: 'Access entries for EKS cluster' Parameters: ClusterName: Type: String Resources: AccessEntry: Type: 'AWS::EKS::AccessEntry' Properties: AccessPolicies: - AccessScope: Type: 'cluster' PolicyArn: 'arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy' ClusterName: !Ref ClusterName PrincipalArn: !Sub 'arn:aws:iam::${AWS::AccountId}:user/test-user'
上記テンプレートファイルを使用してアクセス権の付与を行います。
$ aws cloudformation deploy --stack-name eks-accessentry \ --template-file eks-accessentry.yaml \ --parameter-overrides ClusterName=eks-cluster $ aws eks list-access-entries --cluster-name eks-cluster { "accessEntries": [ "arn:aws:iam::<AWS Account ID>:user/test-user", "arn:aws:iam::<AWS Account ID>:user/yamaji" ] }
あとは追加したユーザーでアクセスできるようkubeconfigを更新すれば、EKSにアクセスし、クラスター上のリソースも見れるようになります。
$ aws eks update-kubeconfig --name eks-cluster # kubectlは定期的にアップデートしておきましょう $ kubectl version Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.0", GitCommit:"c2b5237ccd9c0f1d600d3072634ca66cefdf272f", GitTreeState:"clean", BuildDate:"2021-08-04T18:03:20Z", GoVersion:"go1.16.6", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"27+", GitVersion:"v1.27.8-eks-8cb36c9", GitCommit:"fca3a8722c88c4dba573a903712a6feaf3c40a51", GitTreeState:"clean", BuildDate:"2023-11-22T21:52:13Z", GoVersion:"go1.20.11", Compiler:"gc", Platform:"linux/amd64"} WARNING: version difference between client (1.22) and server (1.27) exceeds the supported minor version skew of +/-1 # 今回はクラスターだけ作成しておりNodeがないためPodは作れない状態です $ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-8496bbc677-2hkgr 0/1 Pending 0 35m kube-system coredns-8496bbc677-zmwvh 0/1 Pending 0 35m
Namespaceレベルの権限コントロール
新しいアクセス管理を利用すると、Kubernetes Namespaceレベルの権限コントロールも可能となります。先ほど使用したCloudFormationには AccessScope
というパラメーターがありましたが、ここで namespace
を指定することも可能です。
AWSTemplateFormatVersion: 2010-09-09 Description: 'Access entries for EKS cluster' Parameters: ClusterName: Type: String Resources: AccessEntry: Type: 'AWS::EKS::AccessEntry' Properties: AccessPolicies: - AccessScope: Type: 'namespace' Namespaces: # 対象のNamespaceを指定 - 'default' PolicyArn: 'arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy' ClusterName: !Ref ClusterName PrincipalArn: !Sub 'arn:aws:iam::${AWS::AccountId}:user/test-user'
このファイルを使用してAccess Entryを更新すると、 test-user
からは default
Namespaceにしかアクセスできず、それ以外 (ここでは kube-system
) にはアクセスできません。
$ kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 46m $ kubectl get all -n kube-system Error from server (Forbidden): pods is forbidden: User "arn:aws:iam::<AWS Account ID>:user/test-user" cannot list resource "pods" in API group "" in the namespace "kube-system" Error from server (Forbidden): replicationcontrollers is forbidden: User "arn:aws:iam::<AWS Account ID>:user/test-user" cannot list resource "replicationcontrollers" in API group "" in the namespace "kube-system" Error from server (Forbidden): services is forbidden: User "arn:aws:iam::<AWS Account ID>:user/test-user" cannot list resource "services" in API group "" in the namespace "kube-system" (以降割愛)
なお、Access EntryはKubernetes RBACと組み合わせることも可能です。例えばAccess EntryはKubernetes Groupを指定することもできるので、Cluster Role BindingでKubernetes GroupとCluster Roleを紐づければ、Kubernetes RBACベースでの制御を実現できます。
さいごに
Amazon EKSへの新しいアクセス制御方法の紹介でした。従来のConfigMapベースの認証にこだわりがない場合は、基本的にAPI認証のほうが使いやすそうな印象です。
設定変更も簡単にできるので、EKSへのアクセス管理に苦労している人は検討してみるのはいかがでしょうか。
弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。