サイボウズのKubernetesプラットフォームを支えるOSS: ③AccurateによるNamespace管理のセルフサービス化

この記事は、CYBOZU SUMMER BLOG FES '25の記事です。

こんにちは!クラウド基盤本部 PDX(Platform Developer Experience)チームのびきニキ(@BkNkbot)です。 今回は連載「サイボウズのKubernetesプラットフォームを支えるOSS」の3回目として、ソフトマルチテナンシー環境でテナント管理を行うKubernetesコントローラーの「Accurate」について紹介します。

サイボウズのKubernetesクラスタの現状

サイボウズでは1つのKubernetesクラスタを複数のテナント(Kubernetesクラスターリソースへのアクセス権を持つ開発チームの集まり)で共有しています。 この共有のやり方には種類がいくつかあるので、まずは本題に入る前に弊社の現状を紹介します。

マルチテナンシー

複数のユーザーが同じサーバーやアプリケーションなどのシステムやサービスを共有して使う方式をマルチテナンシーと呼びます。 この記事においては、1つのKubernetesクラスターを複数のテナントで共有することを指しています。

マルチテナンシーモデル

マルチテナンシーには大きく2つの形があります。

  • ソフトマルチテナンシー: 1つのclusterを共有し、Namespace, RBAC, NetworkPolicy, ResourceQuota, Pod Securityなどの設定で論理的に隔離する方式。
  • ハードマルチテナンシー: clusterやControl Planeを分離(例:クラスタ単位の分割、kube-apiserver等の仮想クラスタ、専用ノード / ネットワーク)し、強い境界を持たせる方式。

サイボウズでは、ソフトマルチテナンシーを採用しています。

Accurateとは

Accurateは、大規模なマルチテナンシー環境の運用支援をするKubernetesコントローラーです。 Kubernetes上でNamespaceに親子関係を持たせ、親Namespaceから子Namespaceへリソースやラベル、アノテーションを正確に継承・伝搬させることができます。

Accurateでは、テナントユーザー自身が子Namespaceの作成・削除を実行できるように、専用のカスタムリソースとkubectlプラグインを提供しています。 あるNamespaceを「親」とし、その下に複数の「子」Namespaceを階層構造でぶら下げることで、親で設定したアクセス制御やポリシーを子にも適用するといった使い方も可能です。 これにより、クラスタ管理者の介在なしにテナントユーザー自身でも(権限を付与されている箇所に関しては)Namespaceを管理できるようになります。

生まれた背景

Accurateが生まれた背景には、既存のマルチテナンシー管理ツールであるHierarchical Namespace Controller (以下、HNC)に対する当時(Accurate開発を開始した2021年ごろ)の課題感がありました。 HNCはKubernetes公式のSIGが開発したOSSで、Namespaceを親子階層で管理し、RBACやNetworkPolicyなどを親から子へ伝搬できる便利なコントローラーです。 しかし、当時のHNCは基本的に「全てのリソースがカスタムアノテーションを付けない限り子Namespaceへ伝搬する設計(通称オプトアウト方式)」1になっており、この挙動がサイボウズのユースケースにはマッチしませんでした。

たとえば「子Namespaceに特定のSecretのみ共有したい」といったケースがあるとします。 このとき、HNCではSecretが自動生成された場合にカスタムアノテーションを付けづらく、意図せず全ての子NamespaceにSecretがコピーされてしまう恐れがあります。 これらの課題を解決するために、以下の特徴を持つAccurateを開発しました。ちなみに、Accurateは「リソースの伝搬を正確に制御できる」というところから名前が付けられています。

  • オプトイン方式での安全な伝播: リソースは基本的に子Namespaceに伝搬されない。特定のアノテーションを付けたリソースのみを伝搬し、不要なリソースの拡散を防止
  • Namespace-scoped resources(Namespace内に含まれるリソース)を伝搬: どんなNamespace-scoped resourcesでも伝搬対象にできる(種類は設定で制御可能)
  • 専用のカスタムリソースやプラグイン、補助機能
    • SubNamespace:テナントユーザー自身がカスタムリソースを使って子 Namespace を作成・削除できる。クラスタ管理者の介在なしにテナントユーザー自身でも環境構築が可能。
    • Template Namespace:Namespace の設定を雛形化し、新規 Namespace 立ち上げ時に共通のものはすぐに設定できる

1: その後のHNCは、デフォルトでRBAC のみ伝搬され、SecretやConfigmapは伝搬されないように改善されました。

基本的な使い方

説明ばかりしていてもイメージが掴めないと思うので、どんなことができるか触ってみましょう。

# demo用のE2E環境を初期設定する
git clone https://github.com/cybozu-go/accurate
cd accurate
go install github.com/aquaproj/aqua/v2/cmd/aqua@latest
cd e2e
PATH=$(cd ..; pwd)/bin:$PATH
KUBECONFIG=$(pwd)/.kubeconfig
export KUBECONFIG
make start
# Root Namespaceを設定する
kubectl create ns root1
kubectl accurate ns set-type root1 root

# 設定状況を確認する
kubectl accurate list

# 以下のように表示される
# ❯ kubectl accurate list
# └── root1
# 子のNameSpace(通称SubNameSpace)を設定する
kubectl accurate sub create sub1 root1

# 設定状況を確認する
kubectl accurate list

# 以下のように表示される
# ❯ kubectl accurate list
# └── root1
#     └── sub1
# 伝播したいリソースを作成する
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  namespace: root1
  name: secret
  annotations:
    accurate.cybozu.com/propagate: update
type: Opaque
stringData:
  foo: bar
EOF

# 伝播されていることを確認
kubectl get secrets -n root1
kubectl get secrets -n sub1
# template Namespace で共通した設定を使う
# template Namespaceの作成
kubectl create ns template1
kubectl accurate ns set-type template1 template

# root1 Namespaceでtemplate1をテンプレートとして利用するように設定する
kubectl accurate template set root1 template1

# 伝播したいリソースを作成する
cat << EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: template1 # 先ほど作成したtemplate1を指定する
  name: admin
  annotations:
    accurate.cybozu.com/propagate: update
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
subjects:
- kind: Group
  name: foo
  apiGroup: rbac.authorization.k8s.io
EOF

# templateを利用したNameSpace、そしてその子孫にもリソースが正しく伝播していることを確認する
kubectl get rolebinding -n template1
kubectl get rolebinding -n root1
kubectl get rolebinding -n sub1

どう利用しているか

弊社では、各プロダクトチームやサービス単位で親Namespaceを割り当てており、その下ならチームが自分たちで子Namespaceを作成・削除してもよいことにしています。

たとえば「team-cybozu」という親Namespaceの下に「cybozu-argocd」「cybozu-dev」等の子Namespaceをチームメンバーだけで追加することができます。

また、これらには親から共通のRBAC設定(テナントチームに管理者権限を与えるRoleBinding)やResourceQuota, imagePullSecretなどが自動的に伝搬されます。

この際、クラスタ管理者は予め親Namespaceに適切なRoleBindingを作成し、それにaccurate.cybozu.com/propagate=updateアノテーションを付けておくと、子Namespaceにもその権限が自動付与されるように設定できます。

├── team-cybozu # 親NameSpace(「cybozu-argocd」「cybozu-dev」「cybozu-monitoring」を子として持つ)、ここを始点にして子に共通設定等が伝播する
│   ├── cybozu-argocd # 子NameSpace(「team-cybozu」を親に持つ)
│   ├── cybozu-dev # 一例として、team-cybozuメンバーは「dev-xxxx-test-app」という検証用NSをそれぞれで作成・削除することができる
│   └── cybozu-monitoring # team-cybozuメンバーは以下にある「team-pdx」の子NameSpaceは親が違うため自由に作成できない
└── team-pdx 
    └── pdx-dev

テナントユーザー自身がNamespaceを管理できることで、プラットフォームチームの運用負荷軽減と各チームの素早い環境構築にも寄与しています。

また、Accurateと組み合わせて、Argo CDのマルチテナンシー運用を支援する別途開発のコントローラー「Cattage」も用いています。 Cattageについては第4回の記事で紹介予定ですので、次回もぜひご覧ください!

一般的なソフトウェアとしての利用可能性

Accurateはサイボウズ社内だけでなく、もちろん外部組織においても有用なユースケースがあると考えています。 たとえば、一つのKubernetesクラスタを複数チームで共有する会社のケースです。

大規模な企業内プラットフォームでは、プロジェクトごとにクラスタを分ける代わりに、一つのクラスタ内でNamespaceで論理分離する方がリソース効率が良い場合があります。

しかし、それを実現するためには「各チームにクラスター全体の管理者権限を渡さず」に 「Namespace単位で適切に権限委譲」し、「共通ポリシーを継続的に適用する仕組み」が必要です。 Accurateはまさにこのニーズに応えるもので、開発者にNamespace管理を委譲しつつセキュリティと統制を保つ手段として活用できると思います。

また、2025年4月17日にHNCがアーカイブされたことを受け、HNCの代替としてAccurateを検討した組織2もありそうです。 実際にHNCがアーカイブされる際にも、Kubernetes Organization Member から AccurateがHNCとよく似たプロジェクトであると触れられていました。 サイボウズ以外の組織でAccurateが利用されていることもあり、本格的に利用して継続的にコントリビュートしてくれる海外のユーザーもいます。

2: 以下参考 - https://ca-srg.dev/1d94358b43f78002917fc30c657b53bd

おわりに

本記事では、サイボウズが開発・運用しているKubernetesコントローラー「Accurate」について紹介しました。

便利な OSS でも開発体制や利用者数の変化によって、突然アーカイブされてしまうことがあります。 その点、自社開発の場合は私たち自身の基盤で使い続ける前提で開発・メンテナンスされるため、長期的に安心して利用できます。 自社開発したツールをOSS化することは、社外利用者との調整などで苦労するデメリットもありますが、ツール自体のサイロ化を防ぐことができ、健全な開発を維持することができるメリットが大きいと考えています。 また、自社ツールをOSS化することで社内メンバーがよりOSSを身近に感じることができ、他のOSSに対するコントリビュートを促す効果もあります。

もしこの記事でAccurateに興味を持たれた方がいれば、ぜひ触ってみてください。よければコントリビュートもお待ちしています!