AWS Controllers for Kubernetes(ACK) ことはじめ vol.3 ~ 気になることを確認してみた編 ~

※ 本記事は、2022/1/10 現在で著者が検証として諸々触ってみた内容をまとめたものです。ACK は現在デベロッパープレビューな OSS です。後述しますが未実装な機能や改善の余地があり、その実装も今後変更される可能性がに大いにございます。

長くなってしまったので、3編に分けております。この記事は Vol.2 です。ACK をご存知でない方やこれから試してみたい方はまず環境を整える必要があるので、vol.1 からご覧になることを推奨します。

目次

クロスアカウントでのリソース作成

アプリケーションをマルチアカウントでマイクロサービスとして管理しているなど、マルチ AWS アカウントな環境にデプロイしたいこともあります。

ACK のコントローラーから複数 AWS アカウントに対してデプロイする方法ですが、現状は Kubernetes の Namaespace 単位で分ける方法があります。

この方法のメリットとしては、組織全体で一つの ACK 用のマネージメントクラスターを用意しておいて、そのクラスターに対して RBAC で各チームに対して用意した Namespace にのみ権限を付与できるところだと思います。他の AWS アカウントに対して誤ってリソースを操作しないようにできるといったことが比較的シンプルに実現できます。

早速やってみます。アカウントA(000000000000) にある ACK がインストールされた EKS クラスターから、アカウント B(111111111111) で S3 バケットを作ります。

まずは、アカウント B で IAM Role を作ります。サービスコントローラーはこの IAM ロール を最終的に AssumeRole しますので、S3 コントローラーなら S3 の FullAccess を割り当てます。

$ aws iam create-role --role-name accountB-s3FullAccess \
  --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::000000000000:role/ack-s3-controller"}, "Action": "sts:AssumeRole"}]}'
$ aws iam attach-role-policy --role-name s3FullAccess \
  --policy-arn 'arn:aws:iam::aws:policy/service-role/AmazonS3FullAccess'

ConfigMap を作成して、アカウント B のアカウント ID と、先ほど作った S3 用の IAM Role ARN を関連付けます。

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: ack-accont-b-s3-map
  namespace: ack-system
data:
  "111111111111": arn:aws:iam::111111111111:role/accountB-s3FullAccess
EOF

最後に、 用意した Namespace に紐づけます。

## Namespace を新規作成するとき
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: account-b
  annotations:
    services.k8s.aws/owner-account-id: "111111111111"
EOF

## 既存の Namespace を使うとき
$ kubectl annotate namespace account-b services.k8s.aws/owner-account-id=111111111111

これで account-b Namespace にリソースをデプロイすれば、アカウント B に S3 バケットが作成されます。

$ cat <<EOF | kubectl apply -f -
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: hama-cross-account-bucket
  namespace: account-b
spec:
  name: hama-cross-account-bucket
EOF

ACK が動いているクラスターを削除してみる

もう一つ気になったのは、ACK が動いている Kubernetes クラスターを削除した時の挙動です。試してみました。

結論として、以下の様な動作になりました。何度も書きますが、あくまでプレビューの中での 2022/01/10 現在の動きです。この先同じかどうかはわかりません。

  • Kubernetes クラスターを削除しても、ACK で作ったAWSリソースは消えませんでした
  • 別の Kubernetes クラスターを立ち上げて、同じマニフェストをデプロイしてみたが反応なし
    • 既存リソースの取り込みとかは行われない

ここから言えるのは、例えば ACK を管理している Kubernetes クラスターを何かしらの理由 (B/G アップデートなど)で削除したとしても、作った AWS 環境は残すことができる。ただし、その後のデプロイ方法を失うことになります。

ただ、アプリケーションと ACK サービスコントローラーを同居させるクラスターを作るならこの話は起こり得ると思いますが、ACK のみを管理するようなマネージメントクラスターで運用するなら、そうそう発生しないことかなとは感じました。

Crossplane との関係性

ACK と一部機能性が被る OSS のプロダクトとして Crossplane があります。CNCF のプロジェクトの一つで現在 Incubating project として認定されています。Crossplane の詳細はまた別のブログで書きたいので、ここでは詳細には書きませんが、以下のようなソフトウェアです。

  • クラウドインフラのリソースを Kubernetes カスタムリソースとして定義・デプロイ可能
    • AWS だけじゃなくて Azure とか GCP といった様々なクラウドインフラを扱えます
  • 加えてデベロッパーがセルフサービスで容易にクラウドサービスを使うための仕組みをプラットフォームチームが作れます
    • イメージ的にはデベロッパー用のカスタムテンプレートを用意して、デベロッパーが設定したい項目だけをマニフェストに定義する…感じです。

ご覧の通り、Crossplane と ACK は、AWS サービスをKubernetes カスタムリソースとして定義デプロイ可能な点では一緒です。また ACK と Crossplane の provider-aws では同様の Code generator がベースとして使われています。

その上で、私が両方触った上での AWS リソースを作るコントローラーとしての違いですが

  • ACK はサービスごとのコントローラーが用意されているのに対して、Crossplane は provider-aws という単一のコントローラーで全サービスを管理します。
  • Crossplane の provider-aws コントローラーは、AWS 側にあるリソースの状態監視も行っており、AWS側を Kubernete に宣言した状態を常に保つ様に動作します。例えば、バージョニングが有効化された S3 バケットのバージョニングを手動で無効にしたら、しばらくするとまたバージョニングが有効になりました。 の間隔が ACK よりもかなり短いです。
  • provider-aws カスタムコントローラーが吐くログがほとんどなくて、何かあった時のデバッグが難しい。
    • [2022/1/16 更新] debug flag があるのを教えてもらいました。ControllerConfig--debug パラメータを付与することで、 ACK 同様に reconcile のログが見れるようになりました。とはいえこれ debug というより info じゃないかな…と思ったりはします。
  • Kubernetes クラスター削除時の挙動は ACK と同じですが、Crossplane では Crossplane 外で作ったリソースを import する仕組みがあるみたいです。この辺も今後色々試してみたいです。これ最高ですよね。

面白いですよね。僕はすでに Crossplane にも興味津々です。

Crossplane の公式ブログに結構個人的に気になっていた内容が揃っていたのもありがたかったです。


CDK8s とのあれこれ

「CDK8s と ACK どちらを使えばいいか?」 って質問が寄せられているのをたまに見ます。CDK8s は使い慣れたプログラミング言語を使って Kubernetes マニフェスト YAML ファイルを生成できるツールキットです。詳細はこちらのブログで書きました。

結論から言うと、CDK8s と ACK は併用できます。CDK8s はカスタムリソースのマニフェスト生成もできるので、Typescript や Python 等の言語で S3 bucket のマニフェストYaml などを生成可能です。

「それ、CDK じゃね?」って思うかもしれません。少し違います。vol.1 で記載しましたが ACK では AWS SDK for Go を使って各サービスの API を介して直接コントロールします。CloudFormation を使いません。また現状 ACK はその機能性を持ち合わせていませんでしたが、将来的に Crossplane と同様に AWS側を Kubernete に宣言した状態を常に保つ様に動作すれば、そこも差別化ポイントとなるでしょう。

ちなみに Crossplane では、experimental な OSS ですし、まだ触ってもいませんが crossplane-cdk8s という CDK8s のライブラリもあるみたいです。これもどこかで触ってみたいですね!

crossplane-contrib/crossplane-cdk8s

おわりに

ことはじめとか言いつつ、3 編にまたがる長いブログになりました。AWS Controllers for Kubernetes (ACK) について、AWS Dev Day で喋って以降もっと紹介したいなと思っていたのでこの年末年始はずっと向き合いました。

プロダクトの成熟度とか、プロダクトの方向性とかでいうと個人的に今は Crossplane の方に興味津々なのですが、ACK の方も公式のツールとしてどんどん進化していって欲しいですね。今後もプロダクトとして追いかけますし、今回色々気になったところもあるので、どんどん Contribute もしていければと思います。


関連リンク: