この記事について
GitOpsにおけるOCIレジストリを使ったデリバリーを強力にサポートする、KokumiというOSSを試してみた。
Kokumiとは
KokumiはGitOpsにおける、OCIレジストリからクラスターまでのデプロイを担当するOSSである。
GitOpsではこれまでGitをSingle Source of Truthとし、Gitリポジトリに格納されたマニフェストをクラスターに引き込むのが標準であった。
Argo CDではv3.1で新たに、OCIレジストリからマニフェストを取得できるようになった(リリースブログ)。
OCIレジストリに対応したパッケージを行うことでマニフェストの可搬性が向上するというメリットがあるとされている。
また、アプリケーションのコンテナイメージと同じレジストリを使用すれば、ソースを一本化することができる。
OCIレジストリを使ったGitOpsは、直接的にはGitを使わないことから"Gitless GitOps"と呼ばれることがある。
Helm Chartを使ったデプロイでは、レンダリング済みのマニフェストをソースとすることができるようになる。
これにより、処理系によるばらつきやサブチャートまで辿ったときの変化の可能性を排除し、超厳密な意味でのイミュータビリティを実現できる。
ただし、GitリポジトリからOCIレジストリにマニフェストをpushするためにはCIを個別に構築する必要がある。
また、OCIレジストリはGitと異なりパッケージのバージョン間の履歴が管理できないため、トレーサビリティが損なわれるというデメリットが発生する。
KokumiはGitリポジトリからOCIレジストリへのマニフェストの格納と、Argo CDのapplicationの展開を行うOSSである。
これはOCI利用時のGitリポジトリからArgo CDまでのギャップを補完するものであり、OCIレジストリを使ったGitOpsの課題を解消する可能性がある。
Kokumiは最初のリリースが2026年の2月と最近で、GitHubでも"Kokumi is currently experimental"と注意書きがある。
先日のKubeCon CloudNativeCon Japan 2026のArgo CDのセッションで紹介されており、非常に有望と感じたので試してみた。
試験環境
- Kokumi v0.15.1
- Kubernetes v1.35.0
セットアップ
以下のドキュメントに従って進める。
Kokumiのインストール
以下のマニフェストをapplyする。
Helm Chartは、まだない。
kubectl apply -f https://github.com/kokumi-dev/kokumi/releases/download/0.15.1/install.yaml
kokumi namespaceにcontrollerとserver、regitryが作成される。
❯ k get po -n kokumi
NAME READY STATUS RESTARTS AGE
kokumi-controller-manager-5d645b66c8-xbk5z 1/1 Running 0 18s
kokumi-registry-6c497c6bd7-7bxqh 1/1 Running 0 18s
kokumi-server-66c468c6ff-x4bj9 1/1 Running 0 18s
Argo CDからKokumiのレジストリへの認証
以下のコマンドでシークレットを作成する。
TLSのサポートをしていないため、insecureOCIForceHttpオプションをつける必要があるとのこと。
kubectl -n argocd create secret generic manifests-registry-creds \
--from-literal=type=oci \
--from-literal=url=oci://kokumi-registry.kokumi.svc.cluster.local:5000 \
--from-literal=insecureOCIForceHttp=true \
--dry-run=client -o yaml | \
kubectl label -f - argocd.argoproj.io/secret-type=repo-creds --local -o yaml | \
kubectl apply -f -
検証
レジストリの設定
今回はHelm Chartをソースに使用する。
Helm Chartを格納しているレジストリのシークレットをセットする。
kubectl create secret docker-registry ghcr-creds \
--namespace kokumi \
--docker-server=ghcr.io \
--docker-username=t5693 \
--docker-password=<your-token>
レジストリをKokumiに教えてあげるために、Pantryというリソースを作成する。
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Pantry
metadata:
name: ghcr-my-awesome-app
namespace: kokumi
spec:
url: oci://ghcr.io/t5693/my-awesome-app
secretRef:
name: ghcr-creds
description: Private app chart on GitHub Container Registry
Orderの作成
まずOrderを作成する。Orderには主に以下の項目を指定する。
- source: Helm Chartやバージョン。先程作成した
Pantryを参照する。 - render: Helm Chartに渡すパラメータ。values.yaml相当。
- destination: レンダリングしたマニフェストの格納先のレジストリ。kokumiのクラスター内レジストリを使えるが、外部レジストリでも良い。
Kokumiを使ったデリバリーでは基本的にこのOrderにすべての情報が集約される。
Argo CDのApplicationに相当するものと考えてもよいかもしれない。
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Order
metadata:
name: my-awesome-app
spec:
source:
pantryRef:
name: ghcr-my-awesome-app
version: "0.1.0"
render:
helm:
namespace: my-awesome-app
values:
replicaCount: 3
podLabels:
my-tenant-name: tenant-a
destination:
oci: oci://kokumi-registry.kokumi.svc.cluster.local:5000/preparation/my-awesome-app
Orderがready状態になっていることを確認する。
❯ k get order.delivery.kokumi.dev -n my-awesome-app-a
NAME READY REASON LATEST PREPARATION AGE
my-awesome-app True Ready my-awesome-app-9a0123f3bf81 11s
Orderというリソース名はcert-managerと被っている。
Group名付きでorder.delivery.kokumi.devとするとよい。
Preparationの確認とpromote
Preparationリソースが作成されている。
❯ k get preparation
NAME ORDER READY REASON AGE
my-awesome-app-9a0123f3bf81 my-awesome-app True Ready 56s
Preparationにはsourceのhelm chartや、デプロイ前のマニフェストのハッシュ値が記録されている。
❯ k describe preparation my-awesome-app-9a0123f3bf81
Name: my-awesome-app-9a0123f3bf81
Namespace: kokumi
Labels: delivery.kokumi.dev/auto-deploy=Disabled
delivery.kokumi.dev/order=my-awesome-app
delivery.kokumi.dev/version=0.1.0
Annotations: <none>
API Version: delivery.kokumi.dev/v1alpha1
Kind: Preparation
Metadata:
Creation Timestamp: 2026-09-15T16:00:32Z
Generation: 1
Owner References:
API Version: delivery.kokumi.dev/v1alpha1
Block Owner Deletion: true
Controller: true
Kind: Order
Name: my-awesome-app
UID: e69f400a-ba26-44c4-b955-69ff7fe23a10
Resource Version: 1112363
UID: be220645-f632-420c-adbc-846932768454
Spec:
Artifact:
Digest: sha256:9a0123f3bf815c0e906eaeb83a693b0b11c1293d3a15569eab7800c69c54ae1f
Oci Ref: oci://kokumi-registry.kokumi.svc.cluster.local:5000/preparation/my-awesome-app@sha256:9a0123f3bf815c0e906eaeb83a693b0b11c1293d3a15569eab7800c69c54ae1f
Commit Message: Initial commit
Config Hash: sha256:f3819aa43406bf219fee177d32fe6bf445f54b19967e0043bb3a107323075f01
Git Source:
Tag: 0.1.0
Order Name: my-awesome-app
Renderer:
Digest: sha256:9a0123f3bf815c0e906eaeb83a693b0b11c1293d3a15569eab7800c69c54ae1f
Render Type: Helm
Version: v1.0.0
Source:
Base Digest: sha256:70155cc9d01d07d5a1875f55cb54c0170fc3189b41173c5faa598350bb0b6c19
Oci: oci://ghcr.io/t5693/my-awesome-app
Status:
Conditions:
Last Transition Time: 2026-09-15T16:00:32Z
Message: Preparation is ready for serving
Observed Generation: 1
Reason: Ready
Status: True
Type: Ready
Events: <none>
GUIを表示してみる。
❯ kubectl port-forward svc/kokumi-server 12321:80
Forwarding from 127.0.0.1:12321 -> 8080
Forwarding from [::1]:12321 -> 8080
Handling connection for 12321
Kokumiのカスタムリソースが一覧表示できるようになっている。
いいかんじ。
Preparationのメニューから、レンダリングされたマニフェストを参照できる。
Orderでセットしたvalueもここに反映されている。
ここで表示されるものが、クラスターに適用されるマニフェストそのもの、ということができる。
すべてのtemplateがまとめてひとつのファイルとして表示されるため、templateの数が増えたら確認が大変そう。
OrderのメニューにPromoteボタンがあるので押す。
Orderのマニフェストで spec.autoDeploy: enabled にしておくと自動でデプロイまでされる。
クラスターへのデプロイ
Promoteを行うことで、Servingリソースが作成される。
このリソースは「デプロイされたこと」を記録するためのものらしい。
❯ k get serving
NAME ORDER PREPARATION READY REASON AGE
my-awesome-app my-awesome-app my-awesome-app-9a0123f3bf81 True Deployed 37s
❯ k describe serving my-awesome-app
Name: my-awesome-app
Namespace: kokumi
Labels: <none>
Annotations: <none>
API Version: delivery.kokumi.dev/v1alpha1
Kind: Serving
Metadata:
Creation Timestamp: 2026-09-15T16:38:35Z
Finalizers:
delivery.kokumi.dev/finalizer
Generation: 1
Resource Version: 1125905
UID: a1aad778-a4fb-4ba5-acb1-002d0a3d3ea9
Spec:
Order Name: my-awesome-app
Preparation Name: my-awesome-app-9a0123f3bf81
Preparation Policy:
Type: Manual
Status:
Conditions:
Last Transition Time: 2026-09-15T16:38:35Z
Message: Successfully deployed component
Observed Generation: 1
Reason: Deployed
Status: True
Type: Ready
Deployed Digest: sha256:9a0123f3bf815c0e906eaeb83a693b0b11c1293d3a15569eab7800c69c54ae1f
Observed Generation: 1
Observed Preparation Name: my-awesome-app-9a0123f3bf81
Events: <none>
argocdのnamespceにApplicationが作成された。
❯ k get app -n argocd my-awesome-app
NAME SYNC STATUS HEALTH STATUS
my-awesome-app Synced Healthy
Applicationの中身は以下。
sourceがちゃんとkokumiのOCIレジストリになっている。
リソースのデプロイ先のspec.destination.namespaceがkokumiになっている??
❯ k get app -n argocd my-awesome-app -o yaml | k neat
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
delivery.kokumi.dev/allowed-order: my-awesome-app
labels:
delivery.kokumi.dev/order: my-awesome-app
delivery.kokumi.dev/serving: my-awesome-app
name: my-awesome-app
namespace: argocd
spec:
destination:
namespace: kokumi
server: https://kubernetes.default.svc
project: default
source:
path: .
repoURL: oci://kokumi-registry.kokumi.svc.cluster.local:5000/preparation/my-awesome-app
targetRevision: sha256:4aecf69225c2ab9a1691a24d338842e4a36464a5fc0051a73f97c95dc5a17ef9
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- ServerSideApply=true
kokumiのnamespaceの下にPodができてしまった。
Orderのspec.render.helm.namespaceで指定したnamespaceが無視されているのかもしれない。
❯ k get po -n kokumi
NAME READY STATUS RESTARTS AGE
kokumi-controller-manager-5d645b66c8-xbk5z 1/1 Running 0 120m
kokumi-registry-6c497c6bd7-7bxqh 1/1 Running 0 120m
kokumi-server-66c468c6ff-x4bj9 1/1 Running 0 120m
my-awesome-app-5b96f8cdb9-272xq 1/1 Running 0 2m20s
my-awesome-app-5b96f8cdb9-k64br 1/1 Running 0 2m20s
my-awesome-app-5b96f8cdb9-xkn2v 1/1 Running 0 2m20s
以上で、クラスターへのアプリケーションのデプロイまで確認できた。
まとめ
Kokumiを使って、OCIレジストリを使ったデリバリーを試してみた。
OCIを使ったGitOpsが広まれば今後大きく発展するのではと感じた。
特に、GitとArgo CDの間にちょうどいい具合にはまるデザインがとても素晴らしいと感じた。
開発のスタートから日が浅く、まだまだバグや機能不足が目立つため、プロダクションでの利用はもう少し先になるかもしれない。


