EKSクラスター初期作成時における権限周りの設定について
はじめに
EKSにおいてクラスター作成直後の段階では、クラスターを作成したIAMエンティティ(IAMユーザー、またはIAMロール)しかクラスターを操作するためのsystem:masters許可を持っていません。もし、他のIAMユーザー、IAMロールにもクラスターを操作するための権限を付与するためには、クラスターを作成したIAMエンティティを用いてaws-auth ConfigMapの設定を追加する必要があります。
この記事では、EKSの権限設定で起こりがちなエラーの対処方法を整理するとともに、EKSクラスターを作成してからaws-auth ConfigMapに適切な設定を行うまでの方法について整理したいと思います。
EKSクラスターアクセス権限の仕組み
EKSのアクセス権限には、「AWS側のIAMの仕組み」と「KubernetesのRBACの仕組み」が組み合わさっています。
AWSドキュメントの引用
Amazon EKS は、(Kubernetes のバージョン aws eks get-token 以降で使用可能な 1.16.156 コマンド、または AWS CLI 向けの AWS IAM Authenticator for Kubernetes 経由で) Kubernetes クラスターの認証に IAM を使用します。ただし認証には Kubernetes にネイティブな [Role Based Access Control] (RBAC) (ロールベースのアクセスコントロール) を引き続き使用します。つまり IAM は、有効な IAM エンティティの認証にのみ使用されます。Amazon EKS クラスターの Kubernetes API とやり取りするためのすべてのアクセス許可は、ネイティブ Kubernetes RBAC システムを介して管理されます。
ドキュメントには、「EKSを操作する権限があるか=(IAMの仕組み)」と「操作しようとしているIAMはどこまでKubernetesの権限が与えられているか(RBACの仕組み)」の2つの概念が登場しています。
EKSを操作するには、そのIAMエンティティに「EKSを操作する権限」があり、尚且つ、そのIAMエンティティに対して「KubernetesのRBACの設定内で必要な操作権限が与えられている」必要があるということが把握できればいいと思います。
例えば、AWSのフルアクセス権限を与えられたIAMユーザー(user-01
)であっても、KubernetesのRBACの設定内でuser-01
に何も権限が与えられていないと、user-01
はKubernetesが絡むEKSの操作はできません。
EKSクラスター作成の注意点
EKSクラスターを作成する際、作成元は、「eksctlコマンドによる作成」と、「マネジメントコンソールからの作成」という2つに大別されると思います。(コマンドによる作成はeksctlをインストールしたEC2からの実行を前提としています。)
この時、EKSの使用上、 クラスター作成直後の段階では、クラスターを作成したIAMエンティティ(IAMユーザー、またはIAMロール)しかクラスターを操作するためのsystem:masters許可を持たない ため、新たにEKSの操作権限を付与するためには クラスターを作成したIAMエンティティ を用いてEKSの操作をしなければなりません。
したがって、クラスターを作成したIAMエンティティ の把握が重要になります。EKSクラスターを作成する際は、eksctlコマンドでEKSクラスターを作成する場合と、マネジメントコンソールからポチポチとやって作成する2パターンになると思います。このことを考慮に入れると、system:masters許可を持つIAMエンティティは以下のいずれかになることが想定されます。
- eksctlコマンドの場合
EC2に割り当てられたIAMロール(IAMインスタンスプロファイル)、または、aws configureで設定されているIAMユーザーかIAMロール - マネジメントコンソールの場合
マネジメントコンソールにログインしているIAMユーザー、または、Assume RoleしているIAMロール
EKSクラスターの作成
先述した通りEKSクラスター作成時には、クラスターを作成したIAMエンティティ が重要となります。IAMのベストプラクティスでは、ユーザーではなくロールに許可を付与することが推奨されているため、本記事では、IAMロールを用いてEKSクラスターを作成する手順を紹介します。
EC2などからeksctl
コマンドで実行した場合でも基本的な考え方は変わらないので、操作が複雑になるマネジメントコンソールで作成した場合について整理します。
マネジメントコンソールからEKSクラスターを作成するものの、実際のEKSの操作はEC2にeksctl
やkubectl
をインストールして行います。
マネジメントコンソールでのロールの切り替え
マネジメントコンソールにログインしているIAMユーザーから、IAMロールをAssume Roleします。
手順
IAMロールのページに「コンソールでロールを切り替えるためのリンク」があるので、そのリンクにアクセスし、ロールの切り替えを実施します。
IAMの設定
IAMロール名は、iam-role-for-assume
です。
AdministratorAccess
EC2とIAMユーザーからAssume Roleできるように設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com",
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111122223333:role/iam-role-for-assume"
}
}
このIAMポリシーをIAMユーザーにアタッチします。
EKSクラスターの作成
マネジメントコンソールよりEKSクラスターを作成します。(設定のパラメーターについては割愛します。)
他のIAMエンティティにアクセス権を付与する
kubectlとeksctlのインストール
kubectl
とeksctl
が必要になるので、適当なEC2にkubectl
をインストールしてそこから作業します。OSはAmazon Linux 2023です。(Systems Manager経由での作業を想定しています。)
インストール手順
sudo curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version
kubectlはEKSクラスターのkubectlバージョンに合わせたものを使用します。この例では1.28です。
sudo curl -L -o /usr/local/bin/kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.28.1/2023-09-14/bin/linux/amd64/kubectl
sudo chmod +x /usr/local/bin/kubectl
kubectl version --client
kubeconfigの作成
クラスターへのアクセスを設定するために使われるファイルを作成します。このコマンドの実行には、EKSクラスターの参照権限 (eks:DescribeCluster)が必要です。
aws eks update-kubeconfig --region us-east-1 --name cluster01
成功すれば、Added new context arn:aws:eks:us-east-1:111122223333:cluster/cluster01 to /home/ssm-user/.kube/config
と表示されます。
IAMロールの引き受け
この状態でkubectlのコマンドを実行すると、エラーが表示されます。
エラー例
sh-5.2$ kubectl get svc
E0124 05:19:31.253265 9551 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
E0124 05:19:31.918720 9551 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
E0124 05:19:32.545847 9551 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
E0124 05:19:33.185396 9551 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
E0124 05:19:33.830485 9551 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
error: You must be logged in to the server (the server has asked for the client to provide credentials)
sh-5.2$
このエラーを避けるために、先ほどEKSクラスターを作成した際のIAMロールをEC2がAssume Roleする必要があります。
aws sts assume-role --role-arn arn:aws:iam::111122223333:role/iam-role-for-assume --role-session-name AWSCLI-Session
以下のAccessKeyId、SecretAccessKey、SessionTokenの部分を出力結果の値に置き換えてください。
export AWS_ACCESS_KEY_ID=AccessKeyId
export AWS_SECRET_ACCESS_KEY=SecretAccessKey
export AWS_SESSION_TOKEN=SessionToken
必要に応じて、aws sts get-caller-identity
を実行し、IAMロールの引き受けが成功しているか確認してください。
sh-5.2$ aws sts get-caller-identity
{
"UserId": "xxxxxxxx:AWSCLI-Session",
"Account": "111122223333",
"Arn": "arn:aws:sts::111122223333:assumed-role/iam-role-for-assume/AWSCLI-Session"
}
sh-5.2$
kubectlコマンドを実行すると、値が返ってきていることがわかります。
例
sh-5.2$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 10m
sh-5.2$
他のIAMロールにEKSの権限を付与する
EKSクラスターを作成したIAMロールを引き受け、EKSを操作できる状態になりました。しかしながら、これでは作業のたびにEKSクラスターを作成したIAMロールを引き受けなければなりません。
このIAMロールでは、EKSクラスターに対し、system:masters許可が付与されており、場合によっては権限が大きすぎます。また、IAMエンティティ全てが、このIAMロールを引き受けるようにするということは、セキュリティ的にも問題があります。
したがって、特定のIAMロールにEKSの権限を付与することが必要となるため、その設定を実施します。
aws-auth ConfigMapの作成
IAMロールにEKSの権限を付与するには、aws-auth ConfigMapに設定を追加する必要があります。
しかし、私が検証した時点では、aws-auth ConfigMapはクラスターを作成しただけだと存在しませんでした。
sh-5.2$ eksctl get iamidentitymapping --cluster cluster01 --region=us-east-1
No iamidentitymappings found
sh-5.2$
kubectl describe -n kube-system configmap/aws-auth
でaws-auth自体を確認することもできます。
aws-auth configMapは、EKS上のノードグループの作成に合わせて作成されることが判明したので、まずはノードグループを作成します。
手順
マネジメントコンソール上から「ノードグループの追加」を選び、適当にノードグループを作成します。
ノードグループが作成されると、eksctl get iamidentitymapping --cluster cluster01 --region=us-east-1
が成功します。(実行結果は省略します。)
configmap/aws-authに権限追加
IAMロールとIAMユーザーのパターンを紹介します。この作業を実行することで、EKSクラスターを作成したIAMエンティティ以外のIAMロールにもEKSの操作権限を付与することができます。
eksctl create iamidentitymapping --cluster cluster01 --region us-east-1 --arn arn:aws:iam::111122223333:role/iam-role-for-assume-02 --group system:masters --username admin
eksctl create iamidentitymapping --cluster cluster01 --region us-east-1 --arn arn:aws:iam::111122223333:user/test-user --group system:masters --username admin
エラーメッセージの紹介
これから紹介するエラーメッセージは、EKSの初期設定を行う際に私が直面したエラーをまとめたものです。
エラー1
1つ目のエラーです。 (環境固有の部分はxxxxxxxxとしています。)
EKSを初めて構築する際は、aws eks update-kubeconfig
コマンドを実施した際に、このエラーメッセージとなることが多いと思います。
原因
エラーメッセージの通り、User: arn:aws:xxxxxxxxにEKSクラスターの参照権限(eks:DescribeCluster)がないことが原因です。
解決策
aws eks update-kubeconfig
を実行元のIAMエンティティ(IAMユーザー、IAMロール)にeks:DescribeClusterのポリシーを追加することで解決できます。
エラー2
2つ目のエラーです。 (このメッセージは、マネジメントコンソールで表示されるものです。)
原因
現在ログインしているマネジメントコンソールのIAMエンティティ(IAMユーザー、IAMロール)にEKSの情報をマネジメント経由で見るための権限がEKSのaws-auth ConfigMap
に登録されていないことが原因です。
解決策
アクセスしたいIAMエンティティをaws configMAPに登録することで解決できます。手順は、本記事を参照ください。
エラー3
3つ目のエラーです。(サーバーからkubectlコマンドを実施した際に表示されるものです。)
原因
kubectlコマンドによって実行されようとしているEKSに対する操作がEKSのaws-auth ConfigMap
に登録されていないことが原因です。
解決策
kubectlコマンド実行時に使用されているIAMエンティティをaws sts get-caller-ideneity
で調査し、そのIAMエンティティをaws-auth Config Map
に登録することで解決できます。
手順は、本記事を参照ください。
以下のドキュメントが参考になります。
エラー4
4つ目のエラーです。(このメッセージは、マネジメントコンソールで表示されるものです。)
原因
マネジメントコンソールからEKSのリソースを確認する際、使用しているIAMエンティティに十分な権限が付与されていない場合に出力されるメッセージです。
system:mastersのような強い権限を与えられていない場合は、一部のリソースだけマネジメントコンソール上からアクセスできないといったことが発生します。
対処法については以下が参考になると思います。AWS側でマネジメントコンソールからEKSのリソースを確認するための設定が紹介されています。
まとめ
本記事では、EKS構築時に私が陥った権限回りについてまとめました。「AWSのIAMの概念」と「Kubernetes側の概念」が組み合わさっているため、多少複雑ですが、理解しさえすれば単純な概念だと思います。本記事が誰かの役に立てば幸いです。
参考記事
Discussion