こんにちは、タカサオです!
先日開催されたre:Invent 2025で、EKS Capabilitiesが発表されました!
EKS CapabilitiesはGitOps,プラットフォームエンジニアリングを行う際に便利な以下の機能をAWSマネージドで提供してくれる機能です。
- ArgoCD
- AWS Controllers for Kubernetes (ACK)
- Kube Resource Orchestrator (KRO)
これらのうち、KROは馴染が無かったため、自分の勉強のため実機検証してみましたー
なお、今回のブログは以下のAWS公式ドキュメントを元に作成しています。
対象読者
- Kube Resource Orchestrator (KRO)とはどういったものなのか興味がある方
- EKS capabilitiesでKROを利用するための流れを知りたい方
- Kubernetesの基本的なリソース(Pod等)や操作方法を理解されている方
Kube Resource Orchestrator (KRO) とは?
Kube Resource Orchestrator (KRO) は複数のKubernetesリソースを組合せて高レベルのカスタムリソースを作成する機能を提供します。
また、ACKと組合せる事でKubernetesリソースとAWSリソースを組合せた抽象的なカスタムリソースを作成できます。
KROを使うと何が嬉しいの?
プラットフォームエンジニアが再利用可能なリソース構成パターンを定義して、アプリ開発エンジニアに解放する事ができる様になります。
これにより、適切なガバナンスを効かせつつ、アプリ開発エンジニアにセルフサービスでリソースを作成してもらうのに使えます。
このあたりは後で図を用いて解説します。
ガバナンスと、セルフサービスによるリソース構築迅速化・プラットフォームエンジニアの負荷軽減を両立できる、プラットフォームエンジニアリングにとても役立つ機能です!
KROの構成要素
KROを利用する上で作成する必要があるリソースは2つがあります。
ResourceGraphDefinition (RGD)
複数のKubernetesリソースやAWSリソースを組合せて、1つの高レベルに抽象化したカスタムリソースを定義します。
以下は、kind:Deploymentとkind:Serviceを組合せたkind:WebApplicationというRGDを作成した例です。
役割的には、プラットフォームエンジニアがRGDを作成する事になります。
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: web-application
spec:
schema:
apiVersion: v1alpha1
kind: WebApplication
spec:
name: string
replicas: integer
resources:
- id: deployment
template:
apiVersion: apps/v1
kind: Deployment
# ... deployment spec
- id: service
template:
apiVersion: v1
kind: Service
# ... service spec
カスタムリソースインスタンス
アプリ開発エンジニアはそのRGDリソースを元にカスタムリソースのインスタンスを作成します。
以下の例は、上述のkind:WebApplicationのカスタムリソースを作成しています。
apiVersion: v1alpha1
kind: WebApplication
metadata:
name: my-web-app
namespace: default
spec:
name: my-web-app
replicas: 3
RGDとカスタムリソースインスタンスの関係を図にしてみました。
RGDでカスタムリソースを定義する事で、パラメータを指定するだけで複数リソースを作成できる事が分ると思います。
RGDをプラットフォームエンジニアが用意しつつ、アプリ開発エンジニアがカスタムリソースインスタンスを作成する様に分担する事で、プラットフォームとしてのガバナンスを効かせつつリソース構築のセルフサービス化が実現できます。
KROをEKSで使える様にする
EKS CapabilitiesとしてKROを利用するためには、KRO Capabilityを有効化する必要があります。
有効化にはCLIとAWSコンソールを利用するパターンがありますが、今回はAWSコンソールを利用します。
なお、予めEKSクラスタは構築済みの想定とします。
KRO Capabilityを有効化する手順
-
対象のEKSクラスタを選択後、「機能」タブをクリック
-
機能設定で「概要」を選択し、「機能を作成」ボタンをクリック
-
「機能を選択」画面に移るので、「Kube Resource Orchestrator (KRO)」にチェックを入れます
今回は、AWSリソースも含めたカスタムリソースを作成してみるので、「Kubernetes 用 AWS コントローラー (ACK)」にもチェックを入れ、「次へ」ボタンをクリックします -
ACK, KROそれぞれの機能名、IAMロールを設定します。今回は管理者ロールを作成でやってみます。「管理者ロールを作成」ボタンをクリックします
-
以下のポップアップが出ました
管理者ロールは権限が強いので、実際のシステムで運用する場合は別途最小権限のIAMロールを用意した方が良いみたいです。今回は検証のためそのまま「確認」ボタンをクリックします -
IAMロール作成画面に移動しました
「ユースケース」欄の「サービスまたはユースケース」が「EKS」を、「ユースケース」のラジオボタンが「EKS - Capabilities」を選択していると思いますので、そのまま「次へ」ボタンをクリックします -
ロールにアタッチするポリシーを選択する画面に移ります
「AdministratorAccess」ポリシーにチェックが付いていると思いますので、そのまま「次へ」ボタンをクリックします -
ロール名や信頼ポリシーの設定画面に移ります
そのまま変更せずに「ロールを作成」ボタンをクリックします -
これでIAMロールができました!
IAMロール一覧の画面に移りますので、ちゃんと作成されている事を確認できます -
EKS Capabilitiesの設定画面に戻って、グルグルボタンをクリックすると作成したIAMロールが選択できる様になります
-
続いてKRO用のIAMロールも作成します
作成するIAMロールは認証専用のため、IAMポリシーは付与しないらしいです
ACKがAWSリソースを管理するのに対し、KROは直接AWSリソースを管理しないためIAMポリシーが不要なのですね
「KROロールを作成」ボタンをクリックします -
再度IAMロールの作成画面に移動します
ACKの時と同様に「EKS - Capabilities」ラジオボタンが選択されています。そのまま「次へ」ボタンをクリックします -
許可ポリシーの設定画面に移ります
そのまま、「次へ」ボタンをクリックします -
IAMロール名はデフォルトで入っている
AmazonEKSCapabilityKRORoleをそのまま利用します
確かに許可ポリシーは何も設定されていないですねー そのまま「ロールを作成」ボタンをクリックします -
EKS Capabilitiesの設定画面に戻ると、作成したIAMロールが選択できる様になります。作成したIAMロールを選択して、「次へ」ボタンをクリックします
-
確認画面に移ります。そのまま「作成」ボタンをクリックします
-
これでACK、KRO共に有効化できました! とっても簡単でしたねー
ACK、KROがK8Sリソースにアクセスするための権限を付与する
Capabilityを有効化するだけでは、ACK、KROがK8Sリソースを操作する事はできません。操作できる様にするため、権限を付与する必要があります。
上述の有効化の手順で付与していたIAMポリシーはAWSリソースへのアクセスを制御するもので、K8Sリソースにアクセスするためには別途権限付与が必要なのですよね。
実は検証の当初この対応を漏らしており、結構ハマりました。。。
K8Sリソースへのアクセス制御はEKSアクセスポリシーを付与する事で行います。
ちょっと古いですが、アクセスポリシーについては以前以下のスライドでまとめましたので、宜しければご確認ください。
EKSアクセスポリシーを追加する手順
-
「アクセス」タブをクリックします
-
IAM アクセスエントリの一覧から先程作成したKRO用のIAMロールを選択します
-
「アクセスポリシーを追加」ボタンをクリックします
-
付与するアクセスポリシーを選択します
今回は検証用途のため、強い権限を持つAmazonEKSClusterAdminPolicyポリシーをアクセスの範囲をクラスターで設定します。
実際のシステムで運用する場合は、この権限は用途に応じて調整した方が良いかもです。「アクセスポリシーを追加」ボタンをクリックしますアクセスポリシーが追加されました!
-
同様にACKのIAMロールにも
AmazonEKSClusterAdminPolicyポリシーを追加します
これはこの後のサンプルリソースでPostgreSQL RDSを作成するために必要です
RDSの管理者パスワードをK8Sリソースであるkind:Secret経由で指定するのですが、そのkind:SecretへのアクセスするためにACKのIAMロールにもアクセスポリシーを指定する必要があるのですよね(ここでも結構ハマりました。。。。。)
サンプルリソースを作成してみる
ACK, KROを有効にできましたので、ここからいよいよリソースを作成してみようと思います。
今回は、KROの公式ドキュメントにあるPodとRDSを同時に構築するサンプルを試しみてみようと思います。
ResourceGraphDefinitionを作成する
まずはResourceGraphDefinitionを作成します。
基本サンプルマニフェストそのままですが、RDSの管理者ユーザ・パスワードを指定する記載を追加しています。
管理者パスワードはkind:Secretで指定する必要があるため、事前に以下のコマンドで作成しました。
kubectl create secret generic db-secret --from-literal=password=hogehoge
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: deploymentandawspostgres
spec:
# CRD Definition
schema:
apiVersion: v1alpha1
kind: DeploymentAndAWSPostgres
spec:
applicationName: string
image: string
location: string
# Resources
resources:
- id: dbinstance
template:
apiVersion: rds.services.k8s.aws/v1alpha1
kind: DBInstance
metadata:
name: ${schema.spec.applicationName}-dbinstance
spec:
# need to specify the required fields (e.g masterUsername, masterPassword)
engine: postgres
dbInstanceIdentifier: ${schema.spec.applicationName}-dbinstance
allocatedStorage: 20
dbInstanceClass: db.t3.micro
masterUsername: dbadmin
masterUserPassword:
namespace: default
name: db-secret
key: password
- id: pod
template:
apiVersion: v1
kind: Pod
metadata:
name: ${schema.spec.applicationName}-pod
spec:
containers:
- name: container1
image: ${schema.spec.image}
env:
- name: POSTGRES_ENDPOINT
value: ${dbinstance.status.endpoint.address}
マニフェストの解説
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: deploymentandawspostgres
apiVersionでKROのリソースである事を、kind: ResourceGraphDefinitionでRGDマニフェストである事を指定しています。
また、metadata.nameでこのRGDリソースの名前を指定しています。
spec:
# CRD Definition
schema:
apiVersion: v1alpha1
kind: DeploymentAndAWSPostgres
spec:
applicationName: string
image: string
location: string
ここの部分でカスタムリソースの定義を記載しています。
定義名をkind: DeploymentAndAWSPostgresにしているので、カスタムリソースを作成する際はこれをマニフェストで指定します。
またカスタムリソースを作成する際に指定するパラメータを以下としています。
-
applicationName: カスタムリソースで作成するアプリケーションの名前 -
image: コンテナイメージ -
location: リソースを配置するリージョン等を指定するパラメータでしょうか。★サンプルマニフェストでは、特段このパラメータは使われないみたいです
# Resources
resources:
- id: dbinstance
template:
apiVersion: rds.services.k8s.aws/v1alpha1
kind: DBInstance
metadata:
name: ${schema.spec.applicationName}-dbinstance
spec:
# need to specify the required fields (e.g masterUsername, masterPassword)
engine: postgres
dbInstanceIdentifier: ${schema.spec.applicationName}-dbinstance
allocatedStorage: 20
dbInstanceClass: db.t3.micro
ここの部分で、構築するAWS RDSリソースの定義を記載しています。
ACKを用いて作成するので、対応するKubernetesリソースはkind: DBInstanceになります。
template.metadata.name: ${schema.spec.applicationName}-dbinstanceで、パラメータとして受け取ったアプリケーション名に接尾辞として-dbinstanceを付けたものが、DBInstanceリソースの名前で設定されます。
また、template.spec.dbInstanceIdentifierでも同様に${schema.spec.applicationName}-dbinstanceが指定されているので、RDSのインスタンス名にも同じ名前が設定されそうです。
それ以外ですと、template.spec.engineやtemplate.spec.dbInstanceClassで、構築するRDSインスタンスのDBエンジンやインスタンスクラスを指定していますね。
masterUsername: dbadmin
masterUserPassword:
namespace: default
name: db-secret
key: password
サンプルマニフェストにはここの管理者ユーザ、パスワードを指定する記載を追加しました。
パスワードは予め作成したkind:Secretリソースの情報を記載しています。
- id: pod
template:
apiVersion: v1
kind: Pod
metadata:
name: ${schema.spec.applicationName}-pod
spec:
containers:
- name: container1
image: ${schema.spec.image}
env:
- name: POSTGRES_ENDPOINT
value: ${dbinstance.status.endpoint.address}
続いて構築するPodの定義の記載を見てみます。
template.metadata.nameでPod名を、template.spec.containers[0].imageでイメージ名を指定したパラメータを元に指定する事が分ります。
注目すべきはtemplate.spec.containers[0].env[0]でして、value: ${dbinstance.status.endpoint.address}を指定しています。
これは構築したRDSリソースのエンドポイントを取得したものです。取得したエンドポイントをPOSTGRES_ENDPOINTの環境変数としてPodに指定しています。
RDSリソースのエンドポイントは構築時に払出されるため、従来だとRDSリソースを構築時に払出されたエンドポイントを確認し、それをPodマニフェストに手動で設定する必要がありました。
一方KROを用いる事でその作業を自動化できる訳です。このあたりはKROを使う大きなメリットですね!
絵にすると以下になります。
RGDリソースの作成
RGDリソースを作成してみましょう。
マニフェストファイルを指定してkubectl applyコマンドを実行します。
~ $ kubectl apply -f deploymentdbinstance-rg.yaml
resourcegraphdefinition.kro.run/deploymentandawspostgres created
~ $ kubectl get rgd
NAME APIVERSION KIND STATE AGE
deploymentandawspostgres v1alpha1 DeploymentAndAWSPostgres 31s
ちゃんとRGDリソースが作成できました!
カスタムリソースを作成する
続いて構築したRGDを用いてカスタムリソースを作成してみましょう!
apiVersion: kro.run/v1alpha1
kind: DeploymentAndAWSPostgres
metadata:
name: krosampleapp
spec:
applicationName: krosampleapp
image: nginx
location: ap-northeast-1
マニフェストの解説
apiVersion: kro.run/v1alpha1
kind: DeploymentAndAWSPostgres
metadata:
name: krosampleapp
apiVersion: kro.run/v1alpha1でKROのリソースである事を指定します。
予め作成しているRGDリソースであるkind: DeploymentAndAWSPostgresを記載し、カスタムリソース名をmetadata.nameで指定しています。
spec:
applicationName: krosampleapp
image: nginx
location: ap-northeast-1
specとして、RGDリソースで受け付ける様に定義していたパラメータの値を設定していますね。
カスタムリソースの作成
作成したカスタムリソースのマニフェストを用いてkubectl applyコマンドでリソースを作成します。
~ $ kubectl apply -f kro-sample-app.yaml
deploymentandawspostgres.kro.run/krosampleapp created
~ $ kubectl get deploymentandawspostgres.kro.run
NAME STATE READY AGE
krosampleapp ACTIVE True 5m23s
問題無く作成できたみたいです!
では実際にリソースを作成できているのか確認してみましょう。
RDSが作成されていました!名前も指定通りですね。
Podも作成できてます!
~ $ kubectl get pod
NAME READY STATUS RESTARTS AGE
krosampleapp-pod 1/1 Running 0 35m
Podの環境変数として、RDSのエンドポイントがちゃんと登録されています!
~ $ kubectl exec -ti krosampleapp-pod -- env | grep POSTGRES
POSTGRES_ENDPOINT=krosampleapp-dbinstance.cdmg4ojgrzkl.ap-northeast-1.rds.amazonaws.com
まとめ
今回はEKS CapabilitiesのKROを使ってサンプルリソースを作成してみました。
ACK、KROに指定するEKSアクセスポリシーのところでハマりましたが、、、それ以外は結構すんなり進めました。AWSリソースとK8Sリソース両方に対してのアクセス権限を意識する必要がある点は注意が必要ですね。
実機で試してみる事で、ACK、KROを使うことでプラットフォームエンジニアリングが捗るなと改めて思いました!
ではまた!




























