y-ohgi's blog

TODO: ここになにかかく

kroでテンプレートを元に簡単にKubernetesのオブジェクトを管理

TL;DR

  • k8sのリソースオーケストラーのkro
  • kroで定義したテンプレートを元に簡単にk8sのオブジェクトを作成/管理可能

About

awslabsで新しいOSS、kroがリリースされた。
Introducing kro: Kube Resource Orchestrator | AWS Open Source Blog

ResourceGroupというテンプレートを定義し、それを元に簡単にk8sのオブジェクトを作成/管理できるOSS。
今回はOrbStackを使用してローカルで試しました。

Version

  • awslabs/kro
    • v0.1.0
  • OrbStack
    • 1.8.1
  • kubectl
    • v1.31.2
  • helm
    • v3.16.3

Repository

https://github.com/y-ohgi/learn-k8s/tree/main/kro

How to

まずはkroのインストールを行い、テンプレートとなる ResourceGroup を定義し、オブジェクトの実態となる applications を作成します。

Install kro

kroのバージョンを取得し、環境変数に入れる

export KRO_VERSION=$(curl -sL \
    https://api.github.com/repos/awslabs/kro/releases/latest | \
    jq -r '.tag_name | ltrimstr("v")'
  )

helmでkroをinstall

helm install kro oci://public.ecr.aws/kro/kro \
  --namespace kro \
  --create-namespace \
  --version=${KRO_VERSION}

kroがインストールされていることを確認

$ helm -n kro list
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
kro     kro             1               2024-11-15 20:22:11.251301 +0900 JST    deployed        kro-0.1.0       0.1.0

Create ResourceGroup

kroのテンプレートとなるResourceGroupを定義します。

refs: ResourceGroups | kro

ResourceGroupファイルの作成。
今回は deploymentservice を定義しています。

resourcegroup.yaml

apiVersion: kro.run/v1alpha1
kind: ResourceGroup
metadata:
  name: my-application
spec:
  # kro uses this simple schema to create your CRD schema and apply it
  # The schema defines what users can provide when they instantiate the RG (create an instance).
  schema:
    apiVersion: v1alpha1
    kind: Application
    spec:
      # Spec fields that users can provide.
      name: string
      image: string | default="nginx"
      replicas: integer | default=1
      ingress:
        enabled: boolean | default=false

    status:
      # Fields the controller will inject into instances status.
      deploymentConditions: ${deployment.status.conditions}
      availableReplicas: ${deployment.status.availableReplicas}

  # Define the resources this API will manage.
  resources:
    - id: deployment
      template:
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: ${schema.spec.name} # Use the name provided by user
        spec:
          replicas: ${schema.spec.replicas}
          selector:
            matchLabels:
              app: ${schema.spec.name}
          template:
            metadata:
              labels:
                app: ${schema.spec.name}
            spec:
              containers:
                - name: ${schema.spec.name}
                  image: ${schema.spec.image} # Use the image provided by user
                  ports:
                    - containerPort: 80

    - id: service
      template:
        apiVersion: v1
        kind: Service
        metadata:
          name: ${schema.spec.name}-service
        spec:
          selector: ${deployment.spec.selector.matchLabels} # Use the deployment selector
          ports:
            - protocol: TCP
              port: 80
              targetPort: 80

spec.schema.spec が変数にする形になります。

spec:
  # kro uses this simple schema to create your CRD schema and apply it
  # The schema defines what users can provide when they instantiate the RG (create an instance).
  schema:
    apiVersion: v1alpha1
    kind: Application
    spec:
      # Spec fields that users can provide.
      name: string
      image: string | default="nginx"
      replicas: integer | default=1
      ingress:
        enabled: boolean | default=false

resources が作成するオブジェクト群です。

  resources:
    - id: deployment
  :
    - id: service

この後作成する application で定義した変数が反映されます。

containers:
  - name: ${schema.spec.name}
    image: ${schema.spec.image} # Use the image provided by user

ResourceGroupのapply。

kubectl apply -f resourcegroup.yaml

Create Application

ResourceGroupを元にApplicationを作成します。
ここがkroの魅力で、ResourceGroupで定義したschemaを入力するだけでオブジェクトを作成してくれます。

nginx.yaml

apiVersion: kro.run/v1alpha1
kind: Application
metadata:
  name: nginx-application
spec:
  name: nginx-app
  image: nginx:alpine
  replicas: 2
kubectl apply -f kro/nginx.yaml
kubectl get applications

NAME                STATE    SYNCED   AGE
nginx-application   ACTIVE   True     74s

nginxのPodが2台とserviceが作成されていることを確認。

kubectl get deploy,svc

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-app   2/2     2            2           25s

NAME                        TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
service/kubernetes          ClusterIP   192.168.194.129   <none>        443/TCP   52m
service/nginx-app-service   ClusterIP   192.168.194.147   <none>        80/TCP    22s

新しいApplicationを作成する

同様にhttpdを作成します。 httpd.yaml

apiVersion: kro.run/v1alpha1
kind: Application
metadata:
  name: httpd-application
spec:
  name: httpd-app
  image: httpd:2.4.57-alpine
  # replicas: 3 # replicasを定義しないと、ResourceGroupで定義したデフォルト値の 1 になる
kubectl apply -f httpd.yaml
kubectl get applications

NAME                STATE    SYNCED   AGE
nginx-application   ACTIVE   True     74s
httpd-application   ACTIVE   True     78s

ResourceGroupを元にhttpdのオブジェクトが作成されます。

kubectl get deploy,svc

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-app   2/2     2            2           25s
deployment.apps/httpd-app   1/1     1            1           29s

NAME                        TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
service/kubernetes          ClusterIP   192.168.194.129   <none>        443/TCP   52m
service/nginx-app-service   ClusterIP   192.168.194.147   <none>        80/TCP    22s
service/httpd-app-service   ClusterIP   192.168.194.209   <none>        80/TCP    20s

Uninstall

kubectl delete applications nginx-application httpd-application
kubectl delete resourcegroup my-application
helm uninstall kro -n kro

所感

ResourceGroupではresourceを普段のmanifest通りに書け、そこに任意のimageなどを定義できるプレーンな使用感が楽で良いなと感じました。
サクッと導入しアンインストールでき、ブランチ毎にサクッと検証環境を作る時などに思いツールを入れずに済むのが便利だなという感じで、プロジェクトの初期段階などに初手に使いたいです。