はじめに
それまで1人で開発していたEKS環境に新しい開発者が参加する際にいくつかの壁にぶつかりました。
それらは後から見てみれば、どれもKubernetes(EKS)が搭載するロールベースアクセス制御(RBAC)の話で、"適切に権限を付与しましょう"と言うお話です。
しかし、エラーログが分かりづらかったり、ロールを付与する対象が複数あったり、クラスター作成者は自動的に権限が付与されて問題が起きなかったりなので、トラブルシューティングの参考になればと思います。
RBACの壁たち
1つ目の壁: IAMユーザーに紐付ける権限
AWSへのアクセス権が適切に設定されたIAM USERをkubeconfigに設定された状況で 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段階ある。
そのためこの場合は、現在アクセスしている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
samplepod-0123456789-abcde 2/2 Running 0 1m
そこでデプロイに移ろうとしたときに次のような問題が発生しました。
$ kubectl apply -f xxx.yaml
NAME READY STATUS RESTARTS AGE
samplepod-0123456789-abcde 2/2 Running 0 1h
samplepod-9876543210-vwxyz 0/2 Pending 0 5m
ずっとPendingのままなため、ここでEventの確認、Podの状況を確認してトラブルシューティングします。
describe
すると次の様でした。
$ kubectl describe pod samplepod-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/credentials
や profile
が適切に設定されているか確認しましょう。
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にはノードの標準権限・ブートストラッピングの権限を付与しました。
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のポッドが起動しない原因と対策