kro (Kube Resource Orchestrator) 入門 - kro とは?
本記事は、AWS Containers Advent Calendar 2025 の 5 日目 (12/5) のエントリーです。
本記事で書くこと
2025 年 11 月 30 日 (米国時間) に EKS Capabilities が発表されました!この機能は EKS クラスターに「Argo CD による GitOps」のような環境構築やスケーリングを効率的に行うための機能を追加できるものです。
当該機能の概要についてはこちらの記事を参照いただきたいのですが、本記事では EKS Capabilities の中でサポートされている kro(Kube Resource Orchestrator)に焦点を当てます。
聞き馴染みのない方もいらっしゃるかと思いますので、kro が登場した流れや背景について説明しつつ、実際に kro を試してみたいと思います。
はじめに
Kubernetes を活用する際には、YAML 形式のマニフェストファイルで各種リソースを定義・管理する必要があります。
マニフェストは、Kubernetes クラスター上の「望ましい状態(Desired State)」を宣言的に記述するものです。このファイルには、リソースの種類や名前、レプリカ数、使用するコンテナイメージなどが含まれます。
マニフェストは kubectl apply といったコマンドで Kubernetes API サーバーに送信され、etcd に保存されます。その後、さまざまなコンポーネントが協調して動作し、マニフェストで指定された「望ましい状態」の実現を目指します。これが、Kubernetes におけるマニフェスト適用の基本的な流れです。
しかし、実際の本番運用では、管理するマニフェストの数や内容が増えるにつれて、さまざまな課題に直面することになります。
Kubernetes マニフェスト管理における主な課題

YAML ファイル増加による複雑性: サービスが増えるとマニフェストファイルが増加し、似たような内容の YAML ファイルを管理することの煩雑さが発生します。SaaS におけるマルチプロダクトであったり、マイクロサービスを Kubernetes クラスター上でホスティングしている場合などを想定していただくとわかりやすいかと思います。
設定・環境差分の管理負荷: 上記のような複雑性は、特に環境差分 dev,stg,prod など、複数の環境向けに細かい差分が必要な場合、差分の吸収や上書きする設定が複雑化します。実際の現場では kustomize や Helm などで吸収されているケースが多いのではないでしょうか。
認知負荷の増大と開発者体験の低下
マニフェストの抽象化に対して独自の仕組みが複雑化した際に、開発チーム向けのナレッジシェアやオンボーディングの負荷が増大し、結果として開発者体験の低下につながるリスクがあります。その結果、プラットフォームエンジニアリングの文脈でいうところの認知負荷の増加につながるリスクがあります。
Platform Team によるガバナンスの適用
Platform Team による推奨構成の適用が困難になります。テンプレートを展開した場合でも、変更への追従が難しいという課題があります。
抽象化の実現に向けて
こういった課題に対して、抽象化を実現するための選択肢はさまざまあります。以下のように Helm や kustomize、他にも CUE などを活用して独自の抽象化を実現されているプラットフォームチームは多いのではないでしょうか。

kro は、マニフェストの抽象化を実現する新しいオプションになります。
kro とは
kro は 2024 年 11 月にローンチされた OSS です。
端的に言えば、複数の Kubernetes リソースをグルーピングして、単一のユニットとしてデプロイするための、再利用可能な Kubernetes API を作成するツールです。
Kubernetes リソースの依存関係や構成を管理する抽象化レイヤーを開発チームに対して提供することができます。
実際に kro を使ったマニフェストを apply する流れ
kro を利用する際の流れについて、簡単に説明します。

プラットフォームエンジニアの役割
まず、プラットフォームエンジニアは「ResourceGraphDefinition(RGD)」というカスタムリソースを作成します。
ResourceGraphDefinition は、簡単に言えば、複数の Kubernetes リソースをグループ化して、そのリソースの依存関係やパラメータを定義するリソースです。
例えば、よくあるアプリケーションを動かすために必要な Kubernetes リソースである Deployment、Service、Ingress といった複数の Kubernetes リソースを一括りにした RGD を作成します。
開発者の役割
kro においては、RGD の定義を元に作成するカスタムリソースを「インスタンス」と呼びます。
開発チームがインスタンス (カスタムリソース) を apply すると、kro によって RGD で定義された複数のリソースが Kubernetes クラスターに展開され、開発したアプリケーションを Kubernetes 上で動かすために必要な Kubernetes リソースを作成することができます。
試してみよう!
百聞は一見にしかずなので、実際に kro を使って抽象化されたマニフェストを apply することで、Kubernetes リソースが展開されることを確認してみましょう。本記事では EKS Capabilities の kro を有効化し、簡単な RGD を作成してみます。
EKS Capabilities で kro を有効化する手順については、ドキュメントを参照してください。

まず RGD を作成します。ファイル名を rgd.yaml として、以下の YAML を作ります。この RGD では Web アプリケーションを動かすために必要な Deployment および Service リソースを作成するためのテンプレートとしての役割を果たすことができます。
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: webapplication
spec:
schema:
apiVersion: v1alpha1
kind: WebApplication
group: kro.run
spec:
name: string | required=true
image: string | default="nginx:latest"
replicas: integer | default=3
resources:
- id: deployment
template:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${schema.spec.name}
spec:
replicas: ${schema.spec.replicas}
selector:
matchLabels:
app: ${schema.spec.name}
template:
metadata:
labels:
app: ${schema.spec.name}
spec:
containers:
- name: app
image: ${schema.spec.image}
ports:
- containerPort: 80
- id: service
template:
apiVersion: v1
kind: Service
metadata:
name: ${schema.spec.name}
spec:
selector:
app: ${schema.spec.name}
ports:
- protocol: TCP
port: 80
targetPort: 80
この RGD を apply します。
kubectl apply -f rgd.yaml
apply された RGD のステータスを確認します。
kubectl get rgd webapplication -owide
STATE が Active であることを確認しましょう。
> kubectl get rgd webapplication -owide
NAME APIVERSION KIND STATE TOPOLOGICALORDER AGE
webapplication v1alpha1 WebApplication Active ["deployment","service"] 10s
次に RGD で作成した API を用いてインスタンス (今回は WebApplication) を作成します。以下の YAML を webapp.yaml として保存してください。
apiVersion: kro.run/v1alpha1
kind: WebApplication
metadata:
name: my-app
spec:
name: my-app
replicas: 2
このインスタンスを apply します。
kubectl apply -f webapp.yaml
RGD で定義された Deployment と Service リソースがデプロイされていることが確認できます。
kubectl get deployments,services
> kubectl get deployments,services
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-app 2/2 2 2 2m25s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-app ClusterIP 10.100.67.20 <none> 80/TCP 2m26s
おわりに
このように開発者からみた際に Kubernetes マニフェストが抽象化された形で提供されているのが理解できるかと思います。
kro 自体はまだ登場してから日が浅い OSS なので、これからより成熟していくことが期待されます。EKS Capabilities を活用することで簡単に試すことができるので、冒頭であげたような課題に取り組まれているプラットフォームチームの方は、ぜひお試し頂けますと幸いです!
Discussion