Cozystackによる自宅プライベートクラウド環境の構築
この記事はjig.jp Engineers' Blog Advent Calendar 2025 12月15日分の記事です。
はじめに
ミニPC 3台を使用して、Cozystackベースのプライベートクラウド環境を構築しました。
動機は、クラウド破産を気にせず色々試せる環境が欲しかったこと、そして単純に自宅クラスタを構築してみたかったことです。2025年3月にCozystackがCNCF Sandboxプロジェクトに採択されたタイミングで興味を持ち、導入を決めました。
私は普段ECS on FargateやLambdaといったマネージドサービスを使用しており、Kubernetesの運用経験はほぼありません。本記事では、そのような状態から始めた構築手順と、Cloudflare Tunnelでの外部公開方法について紹介します。
Cozystackとは
Cozystackは、Kubernetesベースのフルスタッククラウドプラットフォームです。2025年3月にCNCF Sandboxプロジェクトに採択されました。
通常、Kubernetesクラスタを一から構築する場合、ストレージ(Ceph、Rook)、ネットワーク(Calico、Cilium)、認証基盤(Keycloak、Dex)、VM基盤(KubeVirt)など、数多くのコンポーネントを個別に選定・設定する必要があります。
Cozystackはこれらを統合したパッケージとして提供しています。ストレージ(LINSTO)、ネットワーク(Cilium)、VM基盤(KubeVirt)、Kamaji(マネージドKubernetes)が最初から組み込まれており、個別に構築する手間がありません。
環境構成
Cozystackの公式最小要求スペックは以下の通りです。
| Hosts | 3x Physical hosts |
| CPU | 8 cores |
| RAM | 24 GB |
| Disks | 50 GB SSD + 256 GB SSD |
今回使用したミニPCは以下の3台です。
| ノード名 | IPアドレス | スペック |
|---|---|---|
| node1 | 192.168.100.11 | Intel N150 (4C/4T) / 16GB RAM |
| node2 | 192.168.100.12 | Ryzen 7 PRO 5850U (8C/16T) / 32GB RAM |
| node3 | 192.168.100.13 | Ryzen 7 5825U (8C/16T) / 16GB RAM |
ミニPC購入時点でのドキュメント記載はMinimalで4コア16GB RAMでしたが、現在は8コア24GBに引き上げられています。実際にルートテナントを立てた段階でnode1のCPU使用率が40%に達しており、公式要件が引き上げられた理由が分かりました。

ネットワークは自宅のメインネットワークと分離し、ラボ専用のサブネット(192.168.100.0/24)を用意しました。Cloudflare Tunnel経由でのみ外部公開するため、DMZは設けていません。管理PC(192.168.100.2)からはTailscale経由でのみSSH接続を許可し、ACLでアクセス元を制限しています。
Talos Linuxのセットアップ
Cozystackの構築は、基本的に公式ドキュメントに従って進めました。
最初のステップは、各ノードにTalos Linuxをセットアップすることです。Cozystackは独自にビルドされたTalos Linuxイメージを提供しており、公式ドキュメントではboot-to-talos、PXE、ISOのインストール方法が記載されています。
PXEブート
当初はISOを焼いたUSBメモリでのインストールを試みましたが、各ノードにUSBを挿す手間や、誤ってUSBメモリ自体にOSを書き込んでしまうリスクがあったため、途中からPXEブートに切り替えました。
Cozystack公式ドキュメントのPXEに従い、各ノードと同じネットワーク上でmatchboxとdnsmasqのDockerコンテナを起動しておくことで、電源を入れるだけでネットワークブートし、自動的にセットアップが完了します。
ネットワーク設定
PXEブートに成功すると、画面にSideroのロゴが表示されます。
デフォルトではDHCPでIPアドレスが割り当てられますが、各ノードを識別しやすくするため静的IPに変更しました。VM環境と違い、物理マシンでは面倒ですが3台それぞれにキーボードとモニターを繋げて設定する必要があります。ネットワーク設定はF3キーを押すと設定画面が出てきます。
Cozystackのセットアップ
Talos Linuxクラスタが起動したら、Cozystackをセットアップします。
バンドルの選択
Cozystackは用途に応じて複数のバンドルが用意されています。今回はpaas-fullを選択しました。名前の通りPaaS向けのバンドルですが、KubeVirtによるVM機能、KamajiによるマネージドKubernetesなど、IaaS向けのコンポーネントも含まれています。
バンドルの詳細はこちら、各コンポーネントについてはこちらを参照してください。
設定時の注意点
設定ファイル(cozystack.yaml)のroot-hostとapi-server-endpointには、後で使用するCloudflare Tunnel経由のドメインを設定しました。後から変更するのは手間がかかるため、最初から外部ドメインを設定しておくことをお勧めします。
ストレージ基盤(LINSTOR)やネットワーク(MetalLB)の構成、OIDC認証の設定についても、公式チュートリアルに従って設定を行いました。アクセス制御にはKeycloakと連携したRBACを使用していますが、これにはOIDCのセットアップが必要です。詳細は公式ドキュメントを参照してください。
構築完了後、ダッシュボードとGrafanaにアクセスできます。

CozystackのダッシュボードではGUI操作でアプリケーションの管理が行えます。

また、GrafanaではKubernetes、Flux、ingress、storage、VictoriaMetricsなど、多数のダッシュボードがあらかじめ設定されており、各コンポーネントのリソース使用状況を簡単に監視できます。
Cloudflare Tunnelで外部公開
自宅外からセキュアにアクセスできるようにするため、Cloudflare Tunnelを使用して外部公開を行いました。
Cloudflare Tunnelの選択理由
自宅サーバーを外部公開する方法はいくつかありますが、Cloudflare Tunnelを選択した理由は以下の通りです。
- ポート開放不要: ルーターのポートフォワーディング設定が不要
- 自宅IPの隠蔽: グローバルIPアドレスを隠蔽できる
- DDoS対策: Cloudflareのネットワークで保護される
- 証明書管理不要: HTTPSが自動的に有効化される
Cloudflare Tunnelの実装方法
k8sにおけるCloudflare Tunnelの設定方法は、主に以下の2つがあります。
-
公式の
cloudflared- Deployment/DaemonSetとして手動デプロイ
- トンネルとルーティングを設定ファイルで管理
-
cloudflare-tunnel-ingress-controller- Ingressリソースを監視し、自動的にトンネルを生成・管理
- Kubernetes-nativeな運用が可能
今回は運用の手間を減らすため、後者を選択しました。
cloudflare-tunnel-ingress-controllerの導入
READMEの通りに、まずはhelmでインストールします。
helm repo add strrl.dev https://helm.strrl.dev
helm repo update
helm upgrade --install --wait \
-n cloudflare-tunnel-ingress-controller --create-namespace \
cloudflare-tunnel-ingress-controller \
strrl.dev/cloudflare-tunnel-ingress-controller \
--set cloudflare.apiToken="<API_TOKEN>" \
--set cloudflare.accountId="<ACCOUNT_ID>" \
--set cloudflare.tunnelName="cozystack-tunnel"
API Tokenは、Cloudflareのダッシュボードから作成できます。
API Tokenを作る画面に直接飛べるリンクが便利です。
https://dash.cloudflare.com/profile/api-tokens?permissionGroupKeys=[{"key":"zone","type":"read"},{"key":"dns","type":"edit"},{"key":"argotunnel","type":"edit"}]&name=Cloudflare%20Tunnel%20Ingress%20Controller&accountId=*&zoneId=all
cozy.localドメインの問題と解決
通常のKubernetesクラスタは内部ドメインとしてcluster.localを使用しますが、Cozystackはcozy.localを使用しています。cloudflare-tunnel-ingress-controllerはcluster.localをハードコードしているため、そのままではCozystackのIngressに正しくルーティングできません。
この問題を解決するため、ExternalName Serviceを使用して中継を行いました。
apiVersion: v1
kind: Service
metadata:
name: root-ingress-proxy
namespace: cloudflare-tunnel-ingress-controller
spec:
type: ExternalName
externalName: root-ingress-controller.tenant-root.svc.cozy.local
ports:
- port: 443
targetPort: 443
Ingressでこの中継Serviceを指定します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wildcard-tunnel
namespace: cloudflare-tunnel-ingress-controller
annotations:
cloudflare-tunnel-ingress-controller.strrl.dev/backend-protocol: "https"
spec:
ingressClassName: cloudflare-tunnel
rules:
- host: "*.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: root-ingress-proxy
port:
number: 443
マルチレベルサブドメインのワイルドカード証明書
Cozystackはマルチテナント設計のため、テナントやアプリごとにサブドメインが動的に生成されます(例: app-1.tenant-a.example.com)。
このようなマルチレベルサブドメインのワイルドカード(*.tenant-a.example.com)を公開する場合、Cloudflareの無料のUniversal SSL証明書では対応できません。設定自体は可能ですが、SSL_ERROR_NO_CYPHER_OVERLAPエラーが発生します。
Cloudflareのエッジ証明書には以下の3種類があり、マルチレベルサブドメインに対応しているのは有料プランのみです。
- Universal SSL(無料): マルチレベルサブドメイン非対応
- Advanced Certificate($10/月): マルチレベルサブドメイン対応
- Custom Certificate(Businessプラン以上 $200/月): マルチレベルサブドメイン対応
今回はAdvanced Certificate($10/月)を使用しました。
Cloudflare Dashboardの SSL/TLS → Edge Certificates → Order Advanced Certificate から設定できます。

上記の画面で、Certificate Hostname にマルチレベルサブドメインのワイルドカード(*.tenant.example.com、*.*.example.com など)をSANとして追加します。これにより、全てのサブドメインがHTTPSで公開可能になります。
まとめ
ミニPC 3台(1台あたり4〜5万円)を使用して、Cozystackベースのプライベートクラウド環境を構築しました。ラズパイクラスタに比べると少し値段ははりますが、その分スペックは高く、個人的なアプリケーションを動かすには十分です。消費電力も3台合計でゲーミングPC1台に満たない程度で、電気代は思ったよりかからなさそうです。
Cozystackは、ストレージ、ネットワーク、認証基盤など、通常は個別に構築が必要なコンポーネントを統合してセットアップしてくれるため、構築の手間が大幅に削減されました。日本語の情報はほぼ存在しませんが、公式ドキュメントが充実しているため、Kubernetes未経験でも手順通りに進めれば詰まることはほとんどありませんでした。FluxCDも設定されているため、GitOpsベースのCD環境も組みやすく、体験はとてもよかったです。
一方で、ダッシュボードやリソース作成画面ではKubernetesのマニフェストの情報が直接表示されるため、Kubernetesの知識がある程度必要な印象です。AWSのように気軽に触れる感じではないかもしれません。Cozystackはまだ新しいプロジェクトのため、今後のUI改善に期待したいところです。
最近のメモリ価格上昇の影響で組みにくくはなっていますが、気になる方は構築してみてはいかがでしょうか?
Discussion