「vCluster」で仮想Kubernetesクラスターを構築する

はじめに
3-shakeのSreake事業部に所属する加藤です。第14回目の今回は、Kubernetesクラスター内に仮想Kubernetesクラスターを構築できる「vCluster」について紹介します。
皆さんは、自分だけのKubernetesクラスターを自由に作成したり、破棄したりできる環境がほしいと考えていたりしませんか。
vClusterの概要
vClusterとは
vClusterはKubernetes上で仮想的なクラスターを構築するプロジェクトです。2021年4月にLoft Lab社がOSSとしてリリースを開始し、現在ではOSS版のほか、Enterprise PlanやvCluster Cloudという有償プランも利用可能です。
有償プランの詳細を見ると、企業での運用に必要な認証、他社ツールやクラウドプロバイダーとの統合や、大規模クラスター運用で必要な機能が多くサポートされています。

【出典】vCluster Pricing
vCluster Cloudは2024年11月に発表された、マネージドクラスターの中で仮想クラスターを管理するサービスで、クラウドとオンプレ環境のどちらでも利用できる形で提供されています。
vCluster Cloudも有償プランでは企業での運用に必要な認証、他社ツールやクラウドプロバイダーとの統合や、大規模クラスター運用で必要な機能が多くサポートされています。各料金プランで利用可能な機能一覧はPricingページ下部の「vCluster Cloud」の章を参照してください。
Architecture
vClusterの仮想クラスターはホストクラスターで指定したnamespaceに立ち上がるPodとして構築されます。DeploymentやCRDといったハイレベルなリソースは仮想クラスター内に作成・保存され、PodやServiceといったローレベルなリソースが仮想クラスターで作成されると、syncerというコンポーネントを介してホストクラスターのリソースとして同期されます。
ネットワーク管理のため仮想クラスター内にcorednsのPodが立ち上がりますが、デフォルトの状態ではホストクラスターのスケジューラーが共有されます(Virtual Schedulerを有効化することも可能)。
ホストクラスターと仮想クラスター間のリソース同期
ここでsyncerがホストクラスターと仮想クラスター間で同期する項目について、いくつか見ていこうと思います。
ノード
vClusterはホストクラスターのノードをpsuedoノードとして仮想クラスターを作成します。vcluster.yamlファイルを作成してpsuedoノードを作成せず、実際のホストクラスターのノードをマップさせたり、NodeSelectorでホストクラスターの複数のノードを1つのpsedoノードにマップさせたりすることも可能です(詳細はNodesページを参照)。
試しに、3ノード構成のホストクラスターを作成してみました。
$ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME vc-test Ready control-plane 21m v1.32.0 192.168.49.2 <none> Ubuntu 22.04.5 LTS 6.10.14-linuxkit docker://27.4.1 vc-test-m02 Ready <none> 21m v1.32.0 192.168.49.3 <none> Ubuntu 22.04.5 LTS 6.10.14-linuxkit docker://27.4.1 vc-test-m03 Ready <none> 20m v1.32.0 192.168.49.4 <none> Ubuntu 22.04.5 LTS 6.10.14-linuxkit docker://27.4.1
作成した仮想クラスターのノードを見てみると、作成されたpsuedoノードがホスト側のvc-test-m02ノードにマップしていることが分かります。
$ vcluster create test-cluster1 -n tc1 15:18:02 info Creating namespace tc1 15:18:02 info Create vcluster test-cluster1... 15:18:02 info execute command: helm upgrade test-cluster1 /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/vcluster-0.24.1.tgz-4191263510 --create-namespace --kubeconfig /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/2851582382 --namespace tc1 --install --repository-config='' --values /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/3586232792 15:18:03 done Successfully created virtual cluster test-cluster1 in namespace tc1 15:18:05 info Waiting for vcluster to come up... 15:18:19 info vcluster is waiting, because vcluster pod test-cluster1-0 has status: Init:1/3 15:18:42 done vCluster is up and running 15:18:42 info Starting background proxy container... 15:18:44 done Switched active kube context to vcluster_test-cluster1_tc1_vc-test - Use `vcluster disconnect` to return to your previous kube context - Use `kubectl get namespaces` to access the vcluster $ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME vc-test-m02 Ready <none> 17s v1.32.0 10.111.103.63 <none> Fake Kubernetes Image 4.19.76-fakelinux docker://19.3.12
サービス
OSS版の場合、デフォルトの状態ではサービスが同期されないため、自分で同期したいサービスを設定する必要があります。仮想クラスター内のサービスをホストクラスターや別の仮想クラスターで利用したいとき、またその逆の場合には、vcluster.yamlに定義して仮想クラスター作成時または更新時に適用します。
networking: replicateServices: fromHost: - from: my-host-namespace/my-host-service to: my-virtual-namespace/my-virtual-service・仮想クラスターのサービスをホストクラスターに同期
networking: replicateServices: toHost: - from: my-virtual-namespace/my-virtual-service to: my-host-service
詳細は、Replicate networking servicesを参照してください。
その他同期項目
その他、デフォルトの状態で同期されるものや、デフォルトの状態では同期されないが有効化すれば同期可能なものについては、以下の公式ページを参照してください。
Platform configuration
仮想クラスターの構成をデフォルト設定から変更したい場合には、Platform configurationの変更が必要になります。Platform configurationは大きくInstall settings、Operational settings、Agent settingsの3つに分かれており、Operational settings以外は仮想クラスター作成時またはアップグレード時のみ適用可能な設定です。
クラスター作成時の設定を変更するには、自分でvClusterが使用しているhelmチャートのvalues.yamlファイルを修正し、helmコマンドを実行する知識が必要になります。values.yamlのデフォルト値はplatform Helm chart (loft-sh/loft)で確認できます。
values.yamlのconfigセクション(Operational settingsに該当)はクラスターが作成された後の設定を行う部分で、vcluster.yamlに定義してオーバーライドすることが可能です。configセクションで設定可能なものはloft-sh/loft/chart/values.yamlで確認できます。
詳細はPlatform configurationページを参照してください。
vClusterの基本的な使い方
インストール
筆者の環境はMacなので、Homebrewを使用してvcluster CLIをインストールしました。その他の環境へのインストール方法についてはDeploy vClusterを参照してください。
brew install loft-sh/tap/vcluster-experimental
$ vcluster --version vcluster version 0.24.0
仮想クラスター作成
必要に応じてvcluster.yamlファイルを作成します。以下の例では、仮想クラスターとホストクラスター間でIngressリソースの同期を有効化します(詳細はvcluster.yaml configuration referenceを参照)。
--- sync: fromHost: ingressClasses: enabled: true toHost: ingresses: enabled: true
「myvc1」という仮想クラスターを「vc1」というnamespaceに作成します。
$ vcluster create myvc1 -n vc1 -f vcluster.yaml 16:20:10 info Create vcluster myvc1... 16:20:10 info execute command: helm upgrade myvc1 /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/vcluster-0.24.0.tgz-371407530 --create-namespace --kubeconfig /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/15222157 --namespace vc1 --install --repository-config='' --values /var/folders/zm/g7vnp6sx79z7fmzxpb1kvgbw0000gn/T/3466153873 --values vcluster.yaml 16:20:11 done Successfully created virtual cluster myvc1 in namespace vc1 16:20:13 info Waiting for vcluster to come up... 16:20:27 info vcluster is waiting, because vcluster pod myvc1-0 has status: Init:1/3 16:20:50 done vCluster is up and running 16:20:50 info Starting background proxy container... 16:20:50 done Switched active kube context to vcluster_myvc1_vc1_vc-test - Use `vcluster disconnect` to return to your previous kube context - Use `kubectl get namespaces` to access the vcluste
構築された仮想クラスターを確認すると、クラスター内にcorednsのPodが作成されています。
$ kubectl get pods -A -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-94f599b5-vpq4w 1/1 Running 0 91s 10.244.1.2 vc-test <none> <none> $ kubectl get namespace NAME STATUS AGE default Active 1d07h kube-node-lease Active 1d07h kube-public Active 1d07h kube-system Active 1d07h
ホストクラスターを確認すると、仮想クラスターで使用されているcorednsと仮想クラスターのPodが指定したvc1というnamespaceに作成されており、syncerによりホストクラスターでは「coredns-94f599b5-vpq4w-x-kube-system-x-myvc1」というPodが、仮想クラスター内では「coredns-94f599b5-vpq4w」として扱われていることが分かります。
$ vcluster disconnect 15:10:31 info Successfully disconnected and switched back to the original context: vc-test $ kubectl get pods -n vc1 -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-94f599b5-vpq4w-x-kube-system-x-myvc1 1/1 Running 0 59m 10.244.1.2 vc-test <none> <none> myvc1-0 1/1 Running 0 59m 10.244.2.2 vc-test <none> <none> $ kubectl get namespace NAME STATUS AGE default Active 1d07h ingress-nginx Active 1d07h kube-node-lease Active 1d07h kube-public Active 1d07h kube-system Active 1d07h vc1 Active 59m
vClusterの基本コマンド
# 仮想クラスタの作成(--connect=falseを追加するとクラスタ作成後にkube contextを変更しない) vcluster create {{ クラスター名 }} --namespace {{ namespace }} [--connect=false] # 既存仮想クラスターの設定更新 vcluster create --upgrade {{ クラスター名 }} -n {{ namespace }} -f vcluster.yaml # デフォルトはk3sですが、別なdistroを指定することも可能 vcluster create --upgrade {{ クラスター名 }} -n {{ namespace }} --distro k0s # 接続中の仮想クラスターへの接続を切断してホストクラスターに戻る vcluster disconnect # 仮想クラスター一覧 vcluster list # 仮想クラスターへ接続 vcluster connect {{ クラスター名 }} --namespace {{ namespace }} # 仮想クラスター削除 vcluster delete {{ クラスター名 }} --namespace {{ namespace }}
アプリケーションのデプロイ
作成した仮想クラスターに、以下の設定でdeployment.yamlを作成しました。
・vc1-nginx.yaml--- apiVersion: v1 kind: Service metadata: name: nginx-vc1 namespace: vc1 spec: selector: app: nginx-vc1 ports: - name: http protocol: TCP port: 80 targetPort: 80 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-vc1 namespace: vc1 spec: selector: matchLabels: app: nginx-vc1 replicas: 1 template: metadata: labels: app: nginx-vc1 spec: containers: - name: nginx-container image: nginx:latest ports: - name: http containerPort: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-vc1-ingress namespace: vc1 annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - http: paths: - path: /vc1 pathType: Prefix backend: service: name: nginx-vc1 port: number: 80
上記yamlをデプロイしました。
$ vcluster connect myvc1 -n vc1 17:30:40 done vCluster is up and running 17:30:40 info Starting background proxy container... 17:30:40 done Switched active kube context to vcluster_myvc1_vc1_vc-test - Use `vcluster disconnect` to return to your previous kube context - Use `kubectl get namespaces` to access the vcluster $ kubectl create namespace vc1 namespace/vc1 created $ kubectl apply -f vc1-nginx.yaml service/nginx-vc1 created deployment.apps/nginx-vc1 created ingress.networking.k8s.io/nginx-vc1-ingress created
別ターミナルからデプロイしたアプリケーションを確認すると、無事に接続できました。
$ curl http://127.0.0.1/vc1 -I HTTP/1.1 200 OK Date: Fri, 04 Apr 2025 08:36:35 GMT Content-Type: text/html Content-Length: 120 Connection: keep-alive Last-Modified: Fri, 04 Apr 2025 07:32:04 GMT ETag: "67ef8af4-78" Accept-Ranges: bytes
仮想クラスターの削除
クラスターの削除も短時間で行うことができます。
$ vcluster delete myvc1 -n vc1 17:57:55 info Stopping background proxy... 17:57:55 info Delete vcluster myvc1... 17:57:57 done Successfully deleted virtual cluster myvc1 in namespace vc1 17:57:57 done Successfully deleted virtual cluster namespace vc1 17:57:57 info Waiting for virtual cluster to be deleted... 17:58:08 done Virtual Cluster is deleted
ユースケース
vClusterを使えば、ホストクラスターに複数の仮想クラスターを簡単に構築できることをお分かりいただけたでしょうか。
マルチテナントの実現という観点からも、vClusterはソフトマルチテナントでテナントの分離に必要な複雑なポリシーやアクセスコントロールの設定を1つのNamespaceに集約でき、ハードマルチテナントで必要なテナント毎に必要なリソースを確保したり、共通のリソースを作成したりせずにホストクラスターのリソースを共有できます。
一部のローレベルなリソース(コンテナランタイムやCNIプラグイン等)はホスト環境に依存するため、特定の仮想クラスターで異なるものは利用できないという制限はありますが、チーム内でセルフサービスとして簡単にクラスターを作成・削除できる環境を提供して、アプリケーションのテストやツールの検証、オペレーターのテスト、異なるバージョンでの動作検証の並列化などの目的で使ったり、CI/CDパイプラインに実行環境として組み込むといった用途にはとても適しているように見えます。
PoC的な環境として、短時間でDevlopment/Staging/Production環境を構築するようなことにも向いていそうです。
おわりに
今回は、vClusterを利用して、短時間で軽量な仮想クラスターを構築する方法について解説しました。vClusterで複数クラスターの運用にかかっているリソースや管理の効率化を検討されてみてはいかがでしょうか。
【参考】
・vCluster公式ドキュメントページ
・LoftLabs社
・Kubernetes Namespaces vs. Virtual Clusters
・Kubernetes Multi-Tenancy: Why Virtual Clusters Are The Best Solution
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)
- Kubernetesの基礎
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する
- Kubernetes環境を構築して、実際にコンテナを動かしてみよう
- Project CalicoをKubernetesで使ってみる:構築編
- 「kind」でローカル環境にKubernetesクラスターを構築する
- 「kwok」でKubernetesクラスターをシュミレーションする
- 「Inspektor Gadget」でKubernetesクラスタをデバッグする
- KubernetesのマニフェストをMagnumで実行する
- KubernetesのDiscovery&LBリソース(その1)