はじめに
いい感じの対応策は出てません
もしかしたら、何かほんの少し参考になるような部分もあるかも…
どういう話なの
EKSクラスタにアクセスできるユーザーは、awsのIAMエンティティに紐付いており
- EKSクラスタを作成したIAMエンティティ
- k8sクラスタ内では
system:masters
でのアクセスになる
- k8sクラスタ内では
- configMap/aws-authに設定されているIAMエンティティ
- どのIAMエンティティにk8s側でどの権限を与えるか、を設定する
のどちらかになります
クラスタを作成したIAMエンティティはひとつだけだし設定も何もないので、実質的にはconfigmap/aws-auth
の設定が全てになります
たったひとつの単なるconfigmapにクラスタの接続に関するほぼ全てが詰まっています
これの編集に失敗すれば、クラスタへのアクセス方法は失われます
当然削除なんて以ての外です、クラスタは即死します
nodeのクラスタへのアクセスもここで管理しているので、サービスも死にます
死ぬ確率を下げたり死んだ時の傷を浅くするために何ができるのかを考えてみようという話です
やってしまわないために
- 今のとこ、k8sにリソースの削除保護という概念はない(確かないはず)
- 削除保護はできないけど、dataをimmutableにすることはできる(1.19以降)
- https://kubernetes.io/ja/docs/concepts/configuration/configmap/#configmap-immutable
- これをすると、権限追加処理を自動化している場合に少し面倒になるかも
- RBACでなんとか頑張る
- aws-authを触れる権限をなるべく絞る
- とはいっても、所詮はnamespace:kube-systemにあるconfigmapのひとつなので、あまりガチガチにすると通常の運用に影響が出てしまう
- resourceNamesでリソース名を対象にした権限制御は可能だが、これは許可するもので、特定のリソースをeditを拒否するような用途はできなさそう
- aws-authを触れる権限をなるべく絞る
やってしまった時のために
- クラスタを作成したIAMエンティティを記録しておく
- aws-authがなくてもアクセスできる唯一の者
- すでに削除済みでも、同名のIAMエンティティを作成すればそれでアクセスできるらしい
- クラスタを作成するIAMエンティティを固定する
- クラスタを作成したIAMユーザーがわかっても、そのユーザーがすぐに対応できるとは限らない
- IAMユーザーの使い回しはよくないので、クラスタを作成するIAMロールを決めてそれをassumeRoleする形になるか
- 現状のaws-authの管理を確認
- パッとapplyし直せるように
- patchやeditで運用してると今どうなってたっけ…ってなる
- テンプレートで自動化とかしてたら意外と現状deployしてるものが手元に残らなかったり、生成するのも意外と手間取ったり
やってしまったら
- 復帰を目指す
- まだクラスタにアクセスできるIAMエンティティでaws-authをapply
- クラスタを作成したIAMエンティティがわからない場合、awsに問い合わせたら時間がかかるけど特定してくれるらしい
- cloudtrailに記録されるので保存期間内ならそっちを探す
- こうなったら総当りするほうが早そう
- クラスタを作成したIAMエンティティがわからない場合、awsに問い合わせたら時間がかかるけど特定してくれるらしい
- まだクラスタにアクセスできるIAMエンティティでaws-authをapply
- クラスタを作り直す
- クラスタをIAMエンティティがどうしてもわからない、とかで問い合わせて回答を待ってるよりいっそ新しいクラスタを作り直したほうがサービス復帰は早そう
- DBなどはk8sクラスタ外で運用していて、k8sで扱ってるのはステートレスなコンピューティングのみ、という場合は比較的早く復帰できそう
- terraformなどを使っていれば尚更
- DBなどもクラスタで管理してるステートフルなクラスタだと大変そう
- (一般的な事故・障害対応として、クラスタ作り直しは手順整えて通しで確認するくらいやっておいてもよさそう)
ちなみに
EKSのapiでなんとかできるようになる未来があるようです
https://github.com/aws/containers-roadmap/issues/185
ふと思ったけど
これ、このconfigmapに限らずclusterroleとかも消したら死ぬんじゃないかと思いました
k8s難しいですね