Edited at

Kubernetesにて複数人開発する際にぶつかったRBACの壁


はじめに

それまで1人で開発していたEKS環境に新しい開発者が参加する際にいくつかの壁にぶつかりました。

それらは後から見てみれば、どれもKubernetesが搭載するロールベースアクセス制御(RBAC)の話で、"適切に権限を付与しましょう"と言うお話です。

しかし、エラーログが分かりづらかったり、ロールを付与する対象が複数あったり、クラスター作成者は自動的に権限が付与されて問題が起きなかったりなので、トラブルシューティングの参考になればと思います。

ここではEKSを元に書きますが、どうやらGKE,AKSも通ずる話がありそう。


RBACの壁たち


1つ目の壁: IAMユーザーに紐付ける権限

AWSへのアクセス権が適切に設定された状況で kubectl get pods など Kubernetesにアクセスしようとすると次のようなエラーが出ました。

$ kubectl get pods

error: You must be logged in to the server (Unauthorized)

これだけ。

AWSへのアクセスは出来てるし、適切にprofileは設定してるし、いろいろIAMの権限を付け替えてみても、Adminにしても、この1文のみなので困惑しました。

これは実はIAMの認証が通った後、EKSのRBAC認証機能で弾かれていました。

実はEKSは認証が2段階ある。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-auth.html

そのためこの場合は、現在アクセスしているIAMユーザーに対してRBACのロールを与えなければいけません。

ということでこの様にIAMユーザーにロールを付与します。


2つ目の壁: IAMユーザーに紐付ける権限の間違い

ある時IAMユーザーに対してRBACのロールを付与したとき、次のようなエラーが出ました。

$ kubectl get pods

Error from server (Forbidden): services is forbidden: User "sample-username" cannot list services in the namespace "sample-namespace"

これはRBACのロール付与は成功していてユーザーが認証はされていますが、付与するロールが適切でないためRBACの認可がされなかった例です。

これは付与するロールを修正しましょう(それはそれで難しい)。

この問題は開発者に制限したロールを付与しようと探っていた時に出たエラーで、RBACで全権付与した場合は発生しないと思われます。


3つ目の壁: IAMロールに紐付ける権限

IAMユーザーにRBACロールを付与して、KubernetesもといEKSへのアクセスができました。

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
cyten-0123456789-abcde 2/2 Running 0 1m

そこでデプロイに移ろうとしたときに次のような問題が発生しました。

$ kubectl apply -f xxx.yaml

NAME READY STATUS RESTARTS AGE
cyten-0123456789-abcde 2/2 Running 0 1h
cyten-9876543210-vwxyz 0/2 Pending 0 5m

ずっとPendingのままなため、ここでEventの確認、Podの状況を確認してトラブルシューティングします。

すると次のようなログがでした。

$ kubectl describe pod cyten-9876543210-vwxyz

Name: image_name
Namespace: xxx
Node: <none>
Labels: app=label
Annotations: <none>
Status: Pending
IP:
Controlled By: ReplicationController/label
Containers:

...
...
...

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 10s (x7 over 41s) default-scheduler 0/2 nodes are available: 2 node(s) were not ready, 2 node(s) were out of disk space.

上記ログの最下部を見ると、どうやらDisk容量が足りていないらしい。

しかし実はこのメッセージが罠で、これはインスタンスのスペックをいくらいじっても解決せず、実態としてはEKSのIAMロールに対して付与するRBACロールの誤りでした。

実はEKSにおけるRBACのロール付与は、IAMユーザーのみならずIAMロールにも付与する必要があります。

ここではEKSを構成するクラスタのEC2にKubernetesのpodをデプロイする権限がかったため、直前で停止しっぱなしと言う状況でした。

(それなのにエラーメッセージが out of disk space.なのはひどい)

ということなのでこの場合はクラスタを構成するEC2に付与しているIAMロールに対してRBACロールを付与してあげます。


(余談)0つ目の壁: AWSのアクセス権限

$ kubectl get pods

could not get token: NoCredentialProviders: no valid providers in chain. Deprecated.
For verbose messaging see aws.Config.CredentialsChainVerboseErrors
Unable to connect to the server: getting credentials: exec: exit status 1

これはaws-iam-authenticatorが吐いているエラーで、適切にアクセスキーなどが設定されてません。

~/.aws/credentialsprofile が適切に設定されているか確認しましょう。


EKSにてRBACロールを付与する方法

EKSにてRBACロールを付与する方法は、すでにRBAC認証されているユーザーがクラスタに対してConfigMapを適応するのが適切のようです。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html

ここでは1つ目の壁のために、開発者にRBACの全権(master)を付与しました。

また3つ目の壁のために、EC2 IAMにはノードの標準権限・ブートストラッピングの権限を付与しました。


aws-auth.yaml

apiVersion: v1

kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapUsers: |
- userarn: arn:aws:iam::123456789012:user/sample-username
username: sample-username
groups:
- system:masters
mapRoles: |
- rolearn: arn:aws:iam::987654321021:role/sample-rolename
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes

$ kubectl apply -f aws-auth.yaml

これで完了です。

付与したConfigMapは次で確認できます。

$ kubectl describe configmap -n kube-system aws-auth

これで今回のトラブルシューティングは以上です。


参考

Amazon EKS トラブルシューティング

クラスターのユーザーまたは IAM ロールの管理

EKSでIAMユーザをアクセスコントロール (RBAC)

EKSのIAMとRBACの認証・認可を試してみる


EKSトラブルシューティングについて

Pod の問題が起きた場合の確認方法を色々やってみる

Kubernetesのポッドが起動しない原因と対策


RBACと独自ロールの作成に関して

GKEでRBACを使ってアクセス可能なnamespaceを限定する

KubernetesのRBACについて