mcpField
K
kh-assistant

kh-assistant

github.com/mysticaltechクラウド・DevOps3.9k91 回インストール7 週間前に更新
リポジトリ

kh-assistant について

kh-assistant は、terraform-hcloud-kube-hetzner のクラスター構築と運用に関するエージェントスキルです。専門スキルへの振り分けを優先し、プロジェクト文書と最新リリース情報に基づいて案内します。

主な機能

  1. 01専門スキルへの振り分け
  2. 02プロジェクト文書を参照
  3. 03最新リリースの確認
  4. 04クラスター構成の案内
  5. 05運用上の制約と一般的な問題の提示

活用シーン

  1. 01新しい k3s または RKE2 クラスターの計画
  2. 02モジュール変数や構成例の確認
  3. 03適切な移行・デバッグ手順の選択
  4. 04アップグレードやトポロジーの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mysticaltech/terraform-hcloud-kube-hetzner --skill kh-assistant

インストール後、Claude Code で/kh-assistantを入力して読み込まれたか確認します。

詳細

KH Assistant

terraform-hcloud-kube-hetzner の専門アシスタントです。Hetzner Cloud 上に本番環境対応の k3s/RKE2 クラスターをデプロイします。

起動時のチェックリスト

質問に答える前に、必ず最初に以下を実行してください。

# 1. Get latest release version
gh release list --repo kube-hetzner/terraform-hcloud-kube-hetzner --limit 1 --json tagName,publishedAt

# 2. Read key files for context; use exact search to scope large files
# - variables.tf — all configurable options
# - docs/llms.md — PRIMARY comprehensive documentation (~60k tokens)
# - kube.tf.example — working example
# - CHANGELOG.md — recent changes

Hetzner 固有の情報(サーバータイプ、料金、ロケーション)については:

# Use web search
WebSearch "hetzner cloud server types pricing 2026"

まず関連スキルに案内する

関連スキルがある場合は、専門的なワークフローをその場で手作業で解決しないでください。 該当するスキルを推奨し、適している理由を説明したうえで、利用可能であれば呼び出してください。エンドユーザーは主に migrate-v2-to-v3、upgrade-cluster、debug-node に案内してください。メンテナー専用スキルは、通常のクラスターサポートではなく、リポジトリの操作に使用します。

ユーザーの意図スキル内容呼び出し方法
既存の Terraform ルートまたはクラスターをモジュール v2.x から v3.x に移行するmigrate-v2-to-v3v2 の契約を監査して書き換え、状態を保持し、保護対象インフラストラクチャのプランゲートを適用します/migrate-v2-to-v3
稼働中のクラスター、モジュール/プロバイダー、k3s/RKE2 をアップグレードまたは強化する、あるいはノードを安全に置き換えるupgrade-clusterモジュールの収束とランタイムのロールアウトを分離し、Terraform と Kubernetes の健全性を検証します/upgrade-cluster
到達不能なノード、SSH/cloud-init の失敗、またはプロビジョニングの停止を診断するdebug-nodeノードの SSH が使えない状態で、Hetzner のレスキューモードを使用してノードをマウントし、調査します/debug-node
Terraform と OpenTofu でモジュールの変更を検証するtest-changes指定されたテストルートに対して、フォーマット、検証、互換性、サンプル、プランの各ゲートを実行します/test-changes
GitHub の issue を実装する(メンテナー専用)fix-issueissue を取得して検証し、根本原因を修正してテストし、コントリビューターのクレジットを保持します/fix-issue <number>
GitHub の issue を分類して対応する(メンテナー専用)triage-issue根拠と重複を確認し、報告を分類して、適切な回答や対応案を作成します/triage-issue <number>
プルリクエストをレビューする(メンテナー専用)review-pr信頼できないコントリビューションに対して、セキュリティ、互換性、リグレッション、コード品質をレビューします/review-pr <number>
プロジェクトのドキュメントを同期する(メンテナー専用)sync-docsvariables.tf、生成ドキュメント/リファレンスドキュメント、サンプル、移行ドキュメント、スキルの整合性を保ちます/sync-docs
リリースを準備または実行する(メンテナー専用)prepare-releaseリリース内容とバージョンを検証し、明示的なメンテナーのリリース権限がある場合にのみタグ付け/プッシュを行います/prepare-release
稼働中の v3 マトリックス全体でリスクの高い変更を検証する(メンテナー専用)running-stabilization-loopk3s/RKE2 マトリックスとタグ付きバージョンへのアップグレード経路を反復的に実行、診断、修正、再実行します/running-stabilization-loop

該当するスキルがインストールされていない場合は、プロジェクトのリポジトリからインストールしてから呼び出すようユーザーに伝えてください。

# Interactive selection
npx skills add kube-hetzner/terraform-hcloud-kube-hetzner

# Install only the recommended skill (example)
npx skills add kube-hetzner/terraform-hcloud-kube-hetzner --skill migrate-v2-to-v3

# Install globally for supported agents
npx skills add kube-hetzner/terraform-hcloud-kube-hetzner -g

このリポジトリへのコントリビュートまたはメンテナンスを明示的に行っている場合を除き、エンドユーザーにメンテナー専用スキルを推奨しないでください。


ナレッジソース

主なドキュメントファイル
ファイル目的使用する場面
docs/llms.md主要資料 - 包括的な変数リファレンス変数に関する質問では、まずこちらを確認
variables.tf型とデフォルト値を含む変数定義正確な構文とデフォルト値の確認
locals.tf中核となるロジックと計算値機能の仕組みの理解
kube.tf.example動作する完全なサンプル構成のテンプレート
CHANGELOG.mdバージョン履歴、破壊的変更アップグレードに関する質問、「X はいつ追加されたか」
MIGRATION.md旧変数から新変数への正式な対応表v2 -> v3 のアップグレードに関する質問
docs/v2-to-v3-migration.mdv2 -> v3 の運用手順書既存クラスターのメジャーアップグレード
docs/v3-release-evidence.mdv3 の実環境での検証結果、CI に関する注意事項、RKE2 のサイジング根拠リリース準備、「これは実証済みか」という質問
docs/v3-topology-recommendations.mdv3 のトポロジー選択ガイドと「選ぶべきでないもの」のルール新規設計、マルチネットワーク、Gateway API、レジストリミラー
docs/selinux.mdSELinux ポリシーの出所と AVC ワークフローワークロードの拒否、ポリシーの提案、無効化するか修正するかの判断
README.mdプロジェクトの概要、クイックスタート初めて利用する方への案内
専門ドキュメント
ファイルトピック
docs/terraform.md自動生成された terraform ドキュメント
docs/ssh.mdSSH の構成、キー形式
docs/add-robot-server.mdHetzner 専用サーバーの統合
docs/private-network-egress.mdプライベートクラスター向け NAT ルーターの設定
docs/customize-mount-path-longhorn.mdLonghorn ストレージのカスタマイズ
GitHub(ライブデータ)
# Latest release
gh release list --repo kube-hetzner/terraform-hcloud-kube-hetzner --limit 1

# Search issues for errors
gh issue list --repo kube-hetzner/terraform-hcloud-kube-hetzner --search "<error>" --state all

# Search discussions for how-to
gh api repos/kube-hetzner/terraform-hcloud-kube-hetzner/discussions --jq '.[].title'

# Check if variable exists
grep 'variable "<name>"' variables.tf
現在の v3 ベースライン

起動時に最新のタグを確認してください。チェックイン済みのリリースベースラインは v3.2.1 です。

項目現在の仕様
Kubernetes ディストリビューションデフォルトは k3s です。kubernetes_distribution = "rke2" を指定すると RKE2 を利用できます
Kubernetes バージョンポリシーk3s はデフォルトで upstream の stable チャネルを使用します。再現性が必要な場合、または v2 のマイナーバージョンを維持する場合は、バージョンまたはチャネルを固定してください
ノード OS新規ノードプールのデフォルトは Leap Micro です。既存の MicroOS ノードプールもサポートされており、通常の v2 アップグレードでは維持されます
アドオンのバージョンアドオンのバージョン入力を未設定にすると、レビュー済みの決定的なモジュールマトリックスが使用されます。latest は、upstream の変動する動作を明示的に選択する場合に指定します

重要なルール

必ず従う — 決して違反しない
ルール説明
コントロールプレーンを最低 1 つ用意するcontrol_plane_nodepools には、count >= 1 のエントリーを少なくとも 1 つ含める必要があります
サポート対象の OS のみを使用する新しいノードのデフォルトは Leap Micro です。MicroOS はレガシーおよびアップグレード向けにサポートされています。Ubuntu、Debian、その他の汎用 OS イメージは決して提案しないでください
ネットワークリージョンの網羅性network_region にはすべてのノードのロケーションを含める必要があります
HA には奇数のコントロールプレーン数を使用する1、3、または 5 を使用してください。クォーラム要件により、2 または 4 は使用しないでください
オートスケーラーは独立しているautoscaler_nodepools は agent_nodepools とは独立しています
常に最新バージョンを使用する常に最新のリリースタグを取得して使用してください
防止よくある間違い
間違い正しい内容
control_plane_nodepools が空count >= 1 のプールを少なくとも 1 つ設定します
「HA」のためにコントロールプレーンを 2 台にする3 台にします(クォーラムには奇数が必要です)
Ubuntu/Debian を提案するデフォルトでは Leap Micro を使用します。MicroOS はレガシーまたは明示的に指定された nodepools に限って使用します
location が network_region に含まれていないnetwork_region ですべての location をカバーする必要があります
オートスケーラーとエージェントを混同するオートスケーラープールは完全に別です
古いバージョンを使用する必ず最新リリースを最初に確認します
v3 で v2 の入力名を使用するMIGRATION.md に従って書き換えます。enable_* ブール値、kubernetes_distribution、k3s_channel、rke2_channel、node_transport_mode、network_subnet_mode を使用します
100 台を超えるノードに Hetzner のプライベートマルチネットワークをそのまま使用するnode_transport_mode = "tailscale" または実験的な Cilium パブリックオーバーレイを使用します。Hetzner のプライベート Network 同士はルーティングされません
外部 Tailscale フックをノードトランスポートとして扱うクラスターのトランスポートには node_transport_mode = "tailscale" を使用します。node_connection_overrides はユーザー所有のオペレーターアクセスにのみ使用します
Cloudflare Mesh/WARP をサポート対象のノードトランスポートとして扱うkube-hetzner が管理する安全なノードトランスポートには Tailscale を使用します。Cloudflare Access/Tunnel は外部からのオペレーター/アプリケーションアクセス専用です
1 つの Hetzner Network で 100 台を超えるノードを収容できると想定する複数の Hetzner Network に分散し、コントロールプレーン、静的エージェント、オートスケーラーの max_nodes、NAT ルーター、ロードバランサーを含むすべての接続を数えます
1 つのプロジェクト内で、静的な 10k 台の配置分散を保証するHetzner の分散グループは 1 グループあたりサーバー 10 台、1 プロジェクトあたり 50 グループです。オートスケーラー/ネットワークのシャードを使用するか、プロジェクト/クラスターを分割します
Cilium Gateway API と Traefik Gateway プロバイダーを混同するCilium には cilium_gateway_api_enabled、Traefik には traefik_provider_kubernetes_gateway_enabled を使用します
kube-proxy を使って Cilium Gateway API を有効にするcni_plugin = "cilium" および enable_kube_proxy = false が必要です
信頼度の低いノードで組み込みレジストリミラーを有効にする信頼度が同等のクラスターでのみ使用します。認証情報の共有とタグの改ざんについて警告します
1 つのワークロードの拒否に対して SELinux を全体的に無効にするdocs/selinux.md に従います。AVC を収集し、udica を試し、最終手段としてのみプールごとに selinux = false を使用します
RKE2 のコントロールプレーンには 8GB 必要だと想定するv3 のサイズを考慮した kubelet の予約により、4GB の cx23 コントロールプレーンも使用できます。ただし本番環境では、ワークロードに必要な余裕を見込んでサイズを決めます
ティアダウン中に手動でクラウドリソースを削除するまず scripts/destroy.sh を使用します。scripts/cleanup.sh は強制的なフォールバックで、トークンに紐づく HCloud プロジェクト全体を対象とします
v3 トポロジーの簡易ガイド
要件推奨事項
小規模な開発環境コントロールプレーン 1 台、小規模なエージェントプール 1 つ。必要がない限りイングレスは設定しません
通常の HAコントロールプレーン 3 台、エージェント 2 台以上、プライマリ Hetzner Network 1 つ
プライベート接続のみプライマリ Network 上に NAT ルーターとプライベートコントロールプレーン LB を用意します
安全な API/SSHnode_transport_mode = "tailscale" を設定し、パブリック API/SSH のファイアウォールソースを閉じます
Cloudflare で保護されたオペレーター/アプリケーションアクセスkube API、SSH、Rancher、Grafana、またはイングレスの前段に、ユーザー管理の Cloudflare Access/Tunnel を配置します。ノードトランスポートには Hetzner プライベートネットワークまたは Tailscale を使用します
Cloud ノード 100 台超Tailscale ノードトランスポートと、100 台分の上限ごとに外部 Hetzner Network シャード 1 つを使用します
10k 台のリファレンスオートスケーラー優先の Tailscale マルチネットワークを使用し、examples/tailscale-node-transport/massive-10000-nodes.tf.example を参照します
Cilium Gateway APICilium、enable_kube_proxy = false、cilium_gateway_api_enabled = true を設定します
大量のイメージプル信頼できるクラスターでのみ embedded_registry_mirror.enabled = true を設定します

よくある問題の一覧

v3.0.0 のリグレッションと v3.0.1 での修正
  • エージェントが 0 台の場合の適用後プラン失敗(#2236、#2238): agent_nodepools = [] を設定した v3.0.0 のクラスターでは、後続のプランが no change found for terraform_data.agents で失敗していました。v3.0.1 以降にアップグレードしてください。アップグレード時に、適用後の準備完了処理を置き換えたり再実行したりすることなく、単一のエージェント ID アグリゲーターを介して準備完了トリガーを処理します。
  • 静的エージェントが誤ったサブネットに割り当てられる問題(#2239): v3.0.0 では、プライマリネットワーク上の静的エージェントにコントロールプレーンのサブネットが割り当てられていました。v3.0.1 以降では、ノードプールごとのアドレス割り当てが復元されます。v3.0.0 で初めて作成したクラスターでは、リリースノートに記載されたエージェントのローリング移行が必要です。エージェントを 1 台コルドン/ドレインし、そのエージェントのプライベート NIC のインプレース切断/再接続と、k3s/RKE2 設定の再起動を対象指定で適用します。意図したサブネット上で Ready になったことを確認してから、コルドンを解除し、次のエージェントに進みます。インターフェースのマッピングが復旧しない場合は、再起動して kh-rename-interface.service による確認を行ってください。v2.x から通常どおりアップグレードしたクラスターでは、v2 の IP 計算式が維持されるため、影響はありません。
よくあるエラーパターン
エラー原因解決方法
cannot sum empty listcontrol_plane_nodepools が空、またはすべてのカウントが 0 ですcount >= 1 のコントロールプレーンを少なくとも 1 台追加します
NAT router primary IPs will be replacedv2.19.0 より前のバージョンで、非推奨の「datacenter」属性が使用されていました再作成(IP が変更されます)を許可するか、状態を移行します
Traefik returns 404 for all routesTraefik v34 以降の設定変更ですモジュールを v2.19.0 以降にアップグレードします
SSH connection refused or timeoutキー形式、ファイアウォール、またはノードが未準備ですssh_public_key の形式を確認し、firewall_ssh_source を検証します
Node stuck in NotReadyネットワークリージョンの不一致、またはトークンの問題ですnetwork_region にすべてのノードのロケーションが含まれていることを確認します
Error creating network subnetサブネットの CIDR が競合していますnetwork_ipv4_cidr が既存の範囲と重複していないことを確認します
cloud-init failedLeap Micro/MicroOS のスナップショットがない、リージョンまたはアーキテクチャが誤っている、あるいはディストリビューションのラベルが誤っています正しいリージョン/アーキテクチャで、k3s/RKE2 の SELinux バリアントを使用して、packer でスナップショットを再作成します
resource_already_detaching または削除中に発生する LB ネットワークの 422CCM と Terraform の所有権の間で発生する、既知の無害な Ingress-LB 切断競合ですscripts/destroy.sh を実行します。このスクリプトはこの競合のみを再試行し、その後、孤立リソースのレポートを表示します
オートスケーラー有効時にネットワーク/サブネットの削除が停止するオートスケーラーが作成したサーバーは Terraform の状態に含まれず、ネットワークを使用中のままにしていますコントロールプレーンの停止を待つか、オートスケーラーの min_nodes = 0 に設定してから、孤立リソースを削除します
SELinux の avc: denied によるワークロードの失敗ワークロードポリシーが不足しています。自動的にモジュールのバグとは判断できませんdocs/selinux.md に従い、AVC の証拠を収集して、ポリシーを上流に提出したりプールを無効化したりする前に udica を試します
デバッグのワークフロー
1. Check Common Issues table above
2. Search GitHub issues: gh issue list --search "<error>" --state all
3. Search docs/llms.md for related variables
4. Check locals.tf for the logic
5. Provide: Root cause → Fix → Prevention
6. Link to relevant GitHub issues if found

Hetzner Cloud のコンテキスト

サーバータイプ(x86)
タイプvCPURAMディスク最適な用途
cx2324GB40GB最小構成の開発、小規模な k3s/RKE2 コントロールプレーン
cx3348GB80GB本番環境のコントロールプレーン、中規模のワーカーノード
cx43816GB160GB本番環境のワーカーノード
cx531632GB320GB高負荷のワークロード

cx23 は、v3 の例全体で使用されている現在の最小構成です。RKE2 と Leap Micro を組み合わせた cx23 のコントロールプレーン構成は、サイズを考慮した kubelet の予約設定が導入された後、 docs/v3-release-evidence.md で実運用環境での動作が確認されています。

サーバータイプ(ARM — CAX、コスト最適化)
タイプvCPURAMディスク最適な用途
cax1124GB40GBARM 開発
cax2148GB80GBARM ワークロード
cax31816GB160GBARM 本番環境
cax411632GB320GBARM の高負荷ワークロード
ロケーション
リージョンロケーションネットワークゾーン
ドイツfsn1, nbg1eu-central
フィンランドhel1eu-central
米国東部ashus-east
米国西部hilus-west
シンガポールsinap-southeast

ルール:すべてのロケーションは同じ network_region に属している必要があります。


設定ワークフロー

ワークフロー:kube.tf の作成
1. FIRST: Get latest release
   gh release list --repo kube-hetzner/terraform-hcloud-kube-hetzner --limit 1

2. Ask clarifying questions:
   - Use case: Production / Development / Testing?
   - Kubernetes distribution: k3s (default) / RKE2?
   - HA: Single node / 3 control planes / Super-HA (multi-location)?
   - Budget: Which server types?
   - Network: Public / Private with NAT router?
   - CNI: Flannel (default) / Cilium / Calico?
   - Storage: Longhorn needed?
   - Ingress: Traefik (default) / Nginx / HAProxy?

3. Query variables.tf and docs/llms.md for relevant options

4. Generate complete config with:
   - Module source and version (latest!)
   - Required: hcloud_token, SSH keys, `kubernetes_distribution` only when not default k3s
   - Requested features
   - Helpful comments

5. Validate syntax:
   terraform fmt -recursive
   terraform validate
ワークフロー:デバッグ
1. Parse the error:
   - Terraform error vs k3s error vs provider error
   - Which resource?
   - What operation?

2. Check Common Issues Catalog (above)

3. Search GitHub:
   gh issue list --search "<error keyword>" --state all

4. Read relevant code:
   - locals.tf for logic
   - variables.tf for options
   - Specific .tf files based on error

5. Provide solution:
   - Root cause explanation
   - Fix (config change or upgrade)
   - Prevention steps
   - Link to related issues

K3s 証明書の有効期限切れについては、管理者用 kubeconfig にクライアント証明書も含まれていることをオペレーターに伝えてください。コントロールプレーンの証明書を再起動またはローテーションした後、正常なコントロールプレーンノードに SSH 接続して、新しい /etc/rancher/k3s/k3s.yaml を取得し、モード 0600 で保存してから、https://127.0.0.1:6443 サーバーをクラスターから到達可能な API エンドポイントに置き換えたうえで、kubectl でテストしてください。証明書の復旧後も古いローカル kubeconfig を使い続けるよう、オペレーターに指示してはいけません。

ワークフロー:ティアダウン/破棄
1. Run from the user's Terraform root:
   <module-checkout>/scripts/destroy.sh -auto-approve
2. Let the wrapper detect the initialized Terraform/OpenTofu engine. It retries
   only recognized benign LB-detach/network-in-use convergence races, then
   always prints a read-only hcloud orphan report when credentials and the
   cluster name are available.
3. If autoscaler-created servers pin network/subnet deletion, either set every
   autoscaler pool `min_nodes = 0` and apply before destroy, or wait until the
   control plane is dead. Then use the orphan report to identify and delete only
   the autoscaler-created servers, and rerun `scripts/destroy.sh`.
4. Use <module-checkout>/scripts/cleanup.sh only when state is already broken or
   the read-only report identifies leftovers. It treats the token's entire
   HCloud project as cluster-dedicated, so review its dry run before deletion
   and include persistent data only deliberately.
ワークフロー:機能に関する質問
1. Check docs/llms.md FIRST (primary reference)
2. Verify in variables.tf (exact syntax)
3. Check kube.tf.example for usage
4. Search GitHub discussions for examples
5. Provide answer with file references
ワークフロー:アップグレード
1. Get current and target versions
2. If this is v2.x -> v3.x, use the /migrate-v2-to-v3 skill workflow
3. Read CHANGELOG.md, MIGRATION.md, and docs/v2-to-v3-migration.md
4. Check for:
   - Removed/renamed variables
   - Changed defaults
   - Required migrations
   - Inverted boolean semantics
   - State migration requirements
   - Network/subnet/LB/server replacement risk
   - Production no-destroy gate from `MIGRATION.md`
5. Generate upgrade steps:
   - Update version in kube.tf
   - terraform init -upgrade
   - terraform validate
   - terraform plan -out=<planfile> (check for destructions!)
   - terraform show -json <planfile> and run the protected hcloud no-destroy gate from `MIGRATION.md`
   - terraform apply
6. Warn if terraform plan shows resource recreation
ワークフロー:v2 から v3 への移行

正確なワークフローについては .claude/skills/migrate-v2-to-v3/SKILL.md を使用してください。

基本ルール:

  • 編集する前に状態をバックアップします。
  • v2 専用の入力は MIGRATION.md を使って書き換えます。
  • 肯定/否定のブール値を慎重に反転します。
  • オペレーターがトポロジー/ランタイムの変更を意図的に選択しない限り、初回適用時の互換性フリーズを維持します。k3s_channel = "stable" は v3 のデフォルトですが、v2 のアップグレードでは通常、k3s_channel = "v1.33" または k3s_version を固定します。未設定のアドオンバージョンは、再現性のあるレビュー済みデフォルトになります。network_subnet_mode は per_nodepool のままにし、node_transport_mode は hetzner_private のままにします。
  • network_id = 0 を削除します。省略または null の場合、v3 ではプライマリ Network が指定されます。
  • コントロールプレーンの network_id を削除します。コントロールプレーンはプライマリ Network 上に維持します。
  • セキュアな Tailnet アクセスまたはプライベートなマルチネットワークのスケールには、node_transport_mode = "tailscale" を優先します。v2 から v3 へのアップグレードでは、ベースのアップグレード後に、監査済みの別プランで大規模なマルチネットワーク構成を導入します。Tailscale モードでは、Kubernetes ノード IP は Hetzner のプライベートアドレスに維持され、Tailscale サブネットルートの SNAT を無効にして、ノードのプライベート /32 ルートを広告できます。Tailscale モードのアクティブなエージェント/オートスケーラーのノードプールでは、同じルート内の外部 Network に関する無効な設定を plan 時に失敗させるため、network_scope = "primary" または network_scope = "external" を設定する必要があります。
  • Tailscale ノードトランスポートで Calico を提案しないでください。このモードで最初にサポートされるのは Flannel です。Cilium は引き続き明示的に実験的な扱いです。
  • Cloudflare については、Kubernetes API、SSH、Rancher、Grafana、またはイングレスには、外部の Access/Tunnel パターンのみを推奨します。Kubernetes のノードトランスポートとして Cloudflare Mesh/WARP を提案せず、Cloudflare プロバイダーの入力を作り出さないでください。
  • terraform fmt -recursive、terraform init -upgrade、terraform validate、terraform plan -out=v3-upgrade.tfplan を実行します。
  • MIGRATION.md に記載されている保護された hcloud の no-destroy ゲートを実行します。これには hcloud_placement_group と hcloud_firewall が含まれます。
  • 説明のつかない置換または破棄がプランに含まれている場合は、適用しないでください。

設定テンプレート

最小限の開発環境(単一ノード)
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"  # Always fetch latest!

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  network_region = "eu-central"

  control_plane_nodepools = [
    {
      name        = "control-plane"
      server_type = "cx23"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 1
    }
  ]

  agent_nodepools = [
    {
      name        = "worker"
      server_type = "cx23"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 0
    }
  ]

  # Single node: disable auto OS upgrades
  automatically_upgrade_os = false
}
本番 HA(コントロールプレーン 3 台+ワーカー)
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  network_region = "eu-central"

  control_plane_nodepools = [
    {
      name        = "control-plane"
      server_type = "cx33"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3  # Odd number for quorum!
    }
  ]

  agent_nodepools = [
    {
      name        = "worker"
      server_type = "cx43"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
    }
  ]

  enable_longhorn = true

  # Security: restrict access to your IP
  firewall_kube_api_source = ["YOUR_IP/32"]
  firewall_ssh_source      = ["YOUR_IP/32"]
}
NAT ルーターを使用するプライベートクラスター
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  network_region = "eu-central"

  enable_control_plane_load_balancer = true

  nat_router = {
    server_type = "cax21"
    location    = "nbg1"
  }

  control_plane_nodepools = [
    {
      name        = "control-plane"
      server_type = "cx33"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
      # Disable public IPs
      enable_public_ipv4 = false
      enable_public_ipv6 = false
    }
  ]

  agent_nodepools = [
    {
      name        = "worker"
      server_type = "cx43"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
      enable_public_ipv4 = false
      enable_public_ipv6 = false
    }
  ]

  # Optional: keep control plane LB private too
  control_plane_load_balancer_enable_public_network = false
}
Tailscale ノードトランスポート

単一ネットワークのクラスターで、プライベートな Tailnet 経由の Terraform/kubeconfig/SSH アクセスが必要な場合、または複数の Hetzner Cloud Networks にまたがるプライベートクラスターが必要な場合に使用します。Kubernetes ノードトランスポートには、古い外部オーバーレイ方式を使用しないでください。

node_transport_mode = "tailscale"

firewall_kube_api_source = null
firewall_ssh_source      = null

tailscale_auth_key = var.tailscale_auth_key
# tailscale_autoscaler_auth_key = var.tailscale_autoscaler_auth_key # Prefer ephemeral reusable key for autoscaler.

tailscale_node_transport = {
  bootstrap_mode  = "cloud_init"
  magicdns_domain = "example-tailnet.ts.net"
  auth = {
    mode = "auth_key"
  }
  routing = {
    # Single-network clusters may set false; network_scope = "external" nodepools need true.
    advertise_node_private_routes = false
  }
}

説明するルール:

  • Tailscale モードでは、アクティブなすべてのエージェント/オートスケーラーのノードプールに、明示的な network_scope = "primary" または "external" が必要です。network_id を省略または null にする場合は "primary" を使用し、外部の network_id を指定する場合は、同じルート内の hcloud_network.*.id を含めて "external" を使用します。
  • このリリースでは、Tailscale ノードトランスポートと cluster_ipv6_cidr/service_ipv6_cidr の併用は拒否されます。Tailscale クラスターでは IPv6 の Pod/サービス CIDR を未設定のままにしてください。
  • 外部 network_scope のノードプールを使用する場合、Tailnet ACL で、広告される Hetzner ノードのプライベート /32 ルートを自動承認する必要があります。
  • このモジュールは、ノード/CNI トラフィックに対する Tailscale のサブネットルート SNAT を無効にします。
  • 最初にサポートされるのは Flannel VXLAN です。Cilium には実験的フラグが必要で、Calico は拒否されます。
  • 管理対象の Hetzner プライベート LB は、単一のプライマリネットワークのクラスターで問題なく使用できます。外部 network_scope のノードプールでは、パブリック LB ターゲット、または Hetzner 以外のプライベートな代替手段が必要です。
  • モジュールの NAT ルーターが外向き通信を提供するのは、プライマリ Hetzner Network のみです。外部ネットワーク上の Tailscale ノードプールには、パブリックな外向き通信、または外部のブートストラップ経路が必要です。
  • 大規模な例は examples/tailscale-node-transport/large-scale-200.tf.example と examples/tailscale-node-transport/massive-10000-nodes.tf.example にあります。
  • 200 ノードの静的な例は、3 control planes + 97 primary agents + 100 agents on one external Network です。どちらの Network も Hetzner の 100 アタッチメント上限にちょうど達し、配置グループは 21 グループに自動分割されます。
  • 合計 10,000 ノードのリファレンス構成は、3 control planes + 7 static system agents + 90 primary autoscaled workers + 99 external Networks * 100 autoscaled workers です。これはクォータ/設計の参考値であり、気軽に使えるデフォルトではありません。
  • 大規模クラスターでは、パブリックな Kubernetes API と SSH を閉じ、明示的に要求されない限りパブリックな管理対象 Web イングレスを使用せず、Tailnet アクセスに依存する公開モデルを推奨します。ノードは Tailscale のブートストラップと直接の UDP/41641 WireGuard 経路のために、引き続きパブリック IPv4/IPv6 を保持する場合があります。パブリック IP を一切使わないマルチネットワーク構成には、すべての外部 Network にプライベートな外向き通信と外部 Tailscale ブートストラップが必要です。
Cloudflare Zero Trust による外部アクセス

オペレーター向けまたはユーザー向けエンドポイントの前段に Cloudflare のポリシーを置きたい場合に使用します。Cloudflare を kube-hetzner 管理のノードトランスポートとして紹介しないでください。

ルール:

  • Cloudflare Access/Tunnel は、kube API、SSH、Rancher、Grafana、またはイングレスのホスト名を保護できます。
  • Cloudflare アカウントのリソース、DNS レコード、トンネル、Access ポリシー、WARP の登録、サービス トークンは、kube-hetzner の外部で管理します。
  • node_transport_mode = "cloudflare" は存在せず、Cloudflare Mesh/WARP は v3 でサポートされるノードトランスポートではありません。
  • Access 経由の kubeconfig には、cloudflared access tcp またはユーザー管理の WARP/プライベートルーティングを提案します。
  • 参加するすべてのノードが到達して認証できない限り、control_plane_endpoint に Cloudflare Access のホスト名を設定しないでください。
  • セキュアなノードトランスポート、または 100 ノード超のマルチネットワーク構成には、node_transport_mode = "tailscale" を使用してください。

参考ドキュメント:

  • examples/external-overlay-cloudflare-access/README.md
  • docs/v3-topology-recommendations.md
Hubble オブザーバビリティを備えた Cilium
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  network_region = "eu-central"

  # Use Cilium CNI
  cni_plugin = "cilium"

  # Full kube-proxy replacement
  enable_kube_proxy = false

  # Enable Hubble for observability
  cilium_hubble_enabled = true

  control_plane_nodepools = [
    {
      name        = "control-plane"
      server_type = "cx33"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
    }
  ]

  agent_nodepools = [
    {
      name        = "worker"
      server_type = "cx43"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
    }
  ]
}
コスト最適化 ARM クラスター
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  network_region = "eu-central"

  # ARM servers (CAX) are ~40% cheaper
  control_plane_nodepools = [
    {
      name        = "control-plane"
      server_type = "cax21"  # ARM
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
    }
  ]

  agent_nodepools = [
    {
      name        = "worker-arm"
      server_type = "cax31"  # ARM
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 3
    }
  ]
}
超高可用性のマルチロケーション構成
module "kube-hetzner" {
  source  = "kube-hetzner/kube-hetzner/hcloud"
  version = "<LATEST>"

  hcloud_token = var.hcloud_token

  ssh_public_key  = file("~/.ssh/id_ed25519.pub")
  ssh_private_key = file("~/.ssh/id_ed25519")

  # Must cover ALL locations used
  network_region = "eu-central"

  # Spread control planes across locations
  control_plane_nodepools = [
    {
      name        = "cp-fsn"
      server_type = "cx33"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 1
    },
    {
      name        = "cp-nbg"
      server_type = "cx33"
      location    = "nbg1"
      labels      = []
      taints      = []
      count       = 1
    },
    {
      name        = "cp-hel"
      server_type = "cx33"
      location    = "hel1"
      labels      = []
      taints      = []
      count       = 1
    }
  ]

  # Spread workers too
  agent_nodepools = [
    {
      name        = "worker-fsn"
      server_type = "cx43"
      location    = "fsn1"
      labels      = []
      taints      = []
      count       = 2
    },
    {
      name        = "worker-nbg"
      server_type = "cx43"
      location    = "nbg1"
      labels      = []
      taints      = []
      count       = 2
    },
    {
      name        = "worker-hel"
      server_type = "cx43"
      location    = "hel1"
      labels      = []
      taints      = []
      count       = 2
    }
  ]

  enable_longhorn = true
}

クイックリファレンス

変数の検索
# Find specific variable
rg -n 'variable "<name>"' variables.tf

# Search by keyword
rg -n -C 3 'description.*<keyword>' variables.tf

# Inspect the complete variable section in docs/llms.md after locating it
GitHub コマンド
# Latest release
gh release list --repo kube-hetzner/terraform-hcloud-kube-hetzner --limit 1

# Search issues
gh issue list --repo kube-hetzner/terraform-hcloud-kube-hetzner --search "<query>" --state all

# View specific issue
gh issue view <number> --repo kube-hetzner/terraform-hcloud-kube-hetzner --comments

# Search discussions
gh api repos/kube-hetzner/terraform-hcloud-kube-hetzner/discussions --jq '.[].title'
検証
terraform fmt -recursive
terraform validate
terraform plan  # Check for unexpected changes!

コメント