Juju-62q's blog

参加記録やメモ書き、思考のまとめをしています

IAM Role for Podsとeksctlを使ってみた所感

TL;DR

  • IAM Role for PodsAWSKubernetesを上手く繋げていてとても便利
  • Kubernetes on AWSのエコシステムも順調に対応してきている
  • eksctlとGitOpsをどう組み合わせていくのか今後に期待

IAM Role for Pods

9/5にEKSなどKubernetes on AWSを利用しているユーザなら待望の機能であるIAM Role for Podsがリリースされました。

詳しくはAWSの記事を見るといいと思います。公式ドキュメントへのリンクも記事内にあるので適宜見ましょう。

aws.amazon.com

なぜIAM Role for Podsが待望だったか

まず前提として、AWSKubernetesを"まともに"動かすためにはそれなりにたくさんの権限が必要です。 それは、DNSを操作する権限だったり、EC2インスタンスを制御する権限だったり、ALBを制御する権限だったり、アプリが利用するリソースによってはさらにたくさんの権限が必要となります。

IAM Role for Podsがなかった時、AWSの機能で権限を与えるにはEC2インスタンスにIAM Roleを付与するほかありませんでした。 すると全てのPodが上記の権限を全て持つことになります。これはあまり健全な状態とは言えません。

この状態を打開し、PodにIAMを割り当てるためのOSSとして有名なものにkube2iamkiamがあります。 これらのツールはEC2 metadataサーバへの通信をジャックし、これらのツールが代わりにそれっぽいレスポンスを返却することPodはEC2インスタンスのRoleを取得しに行ったつもりがkube2iamやkiamが返却するIAM Roleの一時権限をえるという形で実装がなされています。 このやり方はAWS SDKとしてはかなり古いバージョンでも対応している方法なため多くのツールで変更を加えることなく動作するでしょう。

しかし、kube2iamであればレースコンディションが発生した時に別のRoleが割り当てられるというアンセキュアな要素を、kiamであればEKSで利用する場合にアーキテクチャが大きく引っ張られて複雑になってしまうという要素を許容することになります。 また、EC2 metadataへのアクセスをジャックしているためそれらを利用しているツールは正常に動作しなくなります(ホワイトリスト方式での制御は可能なので利用したいエンドポイントを全て抜き出して、正規表現にして起動コマンドに指定すれば動作する)。

IAM Role for Podsはこれらのデメリットを受けることなく権限管理をすることが可能です。 さらに言えば、kiamやkube2iamとは大きく異なるアプローチを採用しているため併用することが可能です。嬉しいですね。

IAM Role for Podsの動作

アーキテクチャはだいたいこんな感じです。

f:id:Juju_62q:20190919003806p:plain

IAM Role for Podsの動作の肝はIAMというAWSの世界観をOIDC (OpenID Connect)で中継することで、serviceaccountというKubernetesの世界に落とし込んでいる点です。 OIDCを利用してIAM Roleにアクセスすると、IAM Roleの一時認証情報を含むJSONを取得することが可能です。 この機能を利用してKubernetesのserviceaccount tokenをPodに付与することでPod単位でのIAM制御を実現しています。 ここからわかるように基本的にIAM Roleとserviceaccountは一対のものとして管理を行います。

eksctlでIAMを管理する

eksctlはweaveworksが開発しているEKSをいい感じに使うためのツールです。 AWSが公式にサポートしていくと表明したツールでもあります。

このeksctlを利用してIAM Role for Podsがどんな感じに使えるかというと下記のような感じです。

iam:
  withOIDC: true
  serviceAccounts:
  - metadata:
      name: ${SERVICE_ACCOUNT_NAME}
      namespace: ${NAMESPACE}
    attachPolicyARNs:
    - ${POLICY_ARN}

上記のconfigファイルを作成して、下記コマンドを流すことでIAM Role、serviceaccountが発行されます。

$ eksctl utils associate-iam-oidc-provider --config-file=${FILE_PATH}
$ eksctl create iamserviceaccount --config-file=${FILE_PATH}

さて、これは本当に便利なのだろうか🤔

eksctlでIAM Role for Podsを使ってみた感想

ここから先はあくまで個人の感想なのでそれについてはご容赦ください。

まず、eksctlでIAM Role for Podsが使えるのはシンプルに便利で、複雑な操作をラップしてくれているため、非常に使いやすいです。 では何が気になっているかというとeksctlの責務やGitOpsとの相性、各種ツールの対応状況です。

eksctlの責務

今回の機能でまず気になったのはこの部分です。 自分は今まで、eksctlを"クラスタのプロビジョニングツール"として利用していました。 つまり、eksctlがCloudFormationを介して制御をするのはあくまでAWSのリソースです。

しかし、IAM Role for Podsの機能ではIAM Roleの作成にとどまらず、Kubernetesのリソースであるserviceaccountを作成し、それらの紐付けも行います。 つまり、プロビジョニングツールとして使いたかったものがKubernetesのリソースの制御も行うようになりました。

これについてはkube-proxyのアップデート機能がついたり、aws-authというconfigMapをノード作成時、削除時に制御するためもう少し前から制御するようになっていました。 ただし、基本的には回避しながらeksctlとの共存をする方法が用意されていました。

しかしIAM Role for Podsは共存というのは考えられておらず、そのIAMとserviceaccountの管理を全て別の方法で行うか、eksctlに全部やってもらうかしか基本的にありません。 この状況を考えると、eksctlはEKSがそもそも提供していたものや、AWSの機能として出てきたものまでは管理可能という方針で開発されているのでしょうか?その辺りの考え方を少し知りたいなと思いました。

GitOpsとの相性

Kubernetesクラスタを管理する際serviceaccountはClusterRoleBindingなどRBACを管理するためのリソース群と同時に作成されることが多いです。 しかし eksctlを利用してIAM Role for Podsを管理するとserviceaccountの作成まではeksctlの責務で行うことになります。 また、IAM Roleの名称には乱数が付与され、IAM Roleとserviceaccountの対応はeksctlが務めることになります。IAM Roleの名称は当然一定とは限りません。

この部分がGitOpsと混ざった時にどう運用をするのかは少し気がかりです。 GitOpsはmanifestのリポジトリをSingle Source of Truthとして扱うという考え方です。 これに従うと当然serviceaccountはKubernetesのmanifestとして管理されているべきでしょう。 しかし、manifestにしてしまうとIAM Roleの名称変更に対応することができません。

weaveworksはGitOpsの提唱元であり、Fluxやkube-diffなどGitOpsを快適に行うためのツールを幾らか開発しています。 一方でeksctlはCloudFormationやコマンドラインで一度実行するというツールです。 つまりeksctlではかなりCIOpsチックな運用を要求されます。これとGitOpsがどう組み合わさっていくのかはとても気になっています。 Fluxのような形で定期実行を行い、クラスタの状態を定義されている状態に直すというような方針に開発が進むのでしょうか?

ちなみに自分はserviceaccountまではeksctlで管理するようにしてmanifestからserviceaccountの定義を外してFluxなりArgo CDなりを使ってデプロイを行うのが全て自己管理するよりも相対的に健全なのかなと考えています。

各種ツールの対応状況

IAM Role for PodsはPodに少し特殊な方法でcredential等を渡しているため、対応したSDKがある程度新しいものでした。 よってリリース直後はKubernetes on AWSの主要なコンポーネントはほとんど対応していませんでした。 ところがこれらはここ1週間くらいで一気に対応を果たしました。

ツール名 対応状況
ALB Ingress Controller v1.1.3 ~
External DNS v0.5.17 ~
ClusterAutoscaler 1.16.0 ~

あとはご自身で開発しているアプリケーションのAWS SDKをバージョンアップすれば十分利用可能ということになります。

まとめ

IAM Role for Podsは便利。 Kubernetesコミュニティ側は概ね対応を果たしているので早いところ使っていきたい。 GitOpsなどと組み合わせた時のeksctlの責務や運用方法は要検討。