Chatwork 坂本です。
EKSを運用していて、微妙だな、、と思うのがaws-authという名前のConfig Mapでの権限管理だと思います。 2023年12月についに脱Config Mapが可能な機能がAWSからリリースされ、APIで管理できるようになり、移行を進めつつ、いろいろと整理できたので、その内容を記載したいと思います。
いくつかドキュメントを読みましたが、Datadogのブログのドキュメントが1番理解しやすく、正直なところ、このブログを書く必要がないかも、とも思いますが、自分の整理がてら記載します。
Config Mapでの権限管理の問題
EKSを運用していて、下記のような問題がありました。
- クラスタ作成時のRoleが日々の運用の中で意図せずdelete/createされてしまい、Role名が変わってしまって、誰も触れないクラスタができる
- aws-authでの権限管理はクラスタ作成者(RoleやUser)が自動的に管理者に設定されるが、その管理者は変更できない
- Kubernetes側の権限がないとaws-authも更新できず、どうにもならない
- 本番のクラスタではaws-authに複数のRoleを記載しているが、テスト用のクラスタなどは権限をaws-authで管理していないことがあり、その場合にRoleが変わってしまって、誰も触れないクラスタになってしまう
- aws-authを誤って消してしまい(or 修正ミスしてしまい)、ノードが全滅
また、弊社ではもともとeksctlでクラスタを構築していましたが、さすがにいろいろとつらくなってきたので、terraformに移行しようとしていますが*1、aws-auth Config Mapの依存関係を考慮しないと、Kubernetes Resourceなどがエラーになったりして、なかなか厄介な状態でした。
APIの機能をざっくりと
機能に関しては下記のドキュメントを読んでいただければなんとなくわかると思いますが、aws-authに記載していた各種ARNとKubernetesのGroupの紐づけを、AWS側で管理できるようになります。 これがAccess Entryの機能です。
Entryには下記の項目があります。
- Principal ARN
- 利用したいARN
- Type(option)
- EC2_Linuxなどある程度の分類をする機能だが、ほとんどの場合にはStandard(指定しない場合にはStandardになる)を指定する
- Username(option)
- Config Mapにも記載していたKubernetes上でのログなどに残るUsernameを設定する
- 指定しなくても、よしなに入れてくれる
- Groupnames
- Config Mapにも記載していたKubernetesのGroup
- 複数記載が可能
system:から始まるGroupは設定できない- バリデーションで弾かれますが、
system:から始まるGroupは設定できないため、Kubernetes側にはもともとないオリジナルのGroupだけど、system:から始まるGroupで管理していた場合には移行時にRBAC側のBindingの変更が必要な場合があるので注意が必要
- バリデーションで弾かれますが、
またGroupへの紐づけだけではなく、そのRoleに対して、権限を付与することも可能です。 これがAccess Policyの機能です。これは必須ではなく、AWSのAPIでもある程度の権限を付与することは可能、ぐらいに捉えるのがよいと思います。
AWSとしては4つの権限を用意しており、これらの権限をclusterもしくはnamespace単位で付与することが可能です。
- AmazonEKSAdminPolicy
- AmazonEKSClusterAdminPolicy
- AmazonEKSEditPolicy
- AmazonEKSViewPolicy
実際に何ができるのかはこちらで確認できます。
Access Policyの紐づけを行わない場合には、従来通りRBACでのGroupへのBinding(ClusterBinding)が必要になります。
API利用時の注意点
managed node group 追加時の挙動
Node Groupにはself hostedとmanagedがありますが、弊社ではmanagedのみを利用しているので、managedのみの言及となります。
managed node groupを追加した場合、APIのAccess Entryに必要な設定が自動で作成されるので、基本的には何もする必要はありません。
これはAccess configurationをAPI_AND_CONFIG_MAPにした場合にも同様です。この場合にはAccess Entryとaws-auth configmapの両方が追加されます。
こちらには下記のように記載されていますが、API_AND_CONFIG_MAPの場合でもAccess Entryにも自動で作成されます。
It's unnecessary to create an access entry for an IAM role that's used for a managed node group or a Fargate profile, because Amazon EKS adds entries for these roles to the aws-auth ConfigMap, regardless of which platform version your cluster is at.
Access Entryの場合には、NodeのGroupがsystem:nodesだけとなり、Config Mapの場合のsystem:nodes, system:bootstrapperとは異なりますが、問題なく接続できます。
また、(NodeのAccess Entryに限らずですが)API_AND_CONFIG_MAPで、異なる設定が記載されている場合には、APIの設定がoverrideされます。
If you don't delete the entry from the ConfigMap, the settings for the access entry for the IAM principal ARN override the ConfigMap entry
Access EntryとConfig Mapで記載が異なるとややこしいことになりがちなので、可能であればAPIのみにしたほうがわかりやすいと思います。
access config設定時のbootstrapClusterCreatorAdminPermissionsについて
Config Mapの際には、クラスタ作成者のARNが自動的に管理者になっていましたが(Datadogのブログでは"shadow administrators"と記載されている)、APIを有効にすると、この管理者は機能しなくなります。
これに近い機能を提供するのがこのbootstrapClusterCreatorAdminPermissionsです。クラスタ作成者のARNをAccess Entryに追加し、AmazonEKSClusterAdminPolicyと紐づけてくれます。
クラスタの新規作成時はいいのですが、Creatorは作成時にしか判断できないようで("shadow administrators"を見てくれるわけではなさそう)、terraformだとforce updateになって、クラスタが作り直しになってしまうので、あとからaccess configを設定する場合には注意が必要です。
デフォルトではtrueになっていますが、CreateAccessEntryの権限があれば、クラスタ作成後にAWSの権限のみで追加できるので、いくつかのARNを追加するような場合には(それをterraformでfor_eachのようにしている場合には)、条件分けも手間なので、falseがよいと思います。
まとめ
EKSの権限管理にAccess Entryを利用する場合の細かい注意点などを記載しました。
Config Mapで事故りたくない!のは皆さん共通の思いだと思いますので、APIへの移行をおすすめします。
API_AND_CONFIG_MAPであれば、共存も可能なので、まずはAPI_AND_CONFIG_MAPに変更するだけでもいいかもしれません。
*1:公式のeks moduleではなく、それを参考にした独自のmoduleを作成、利用しています