mcpField
K
kh-assistant

kh-assistant

github.com/mysticaltech云与 DevOps3.9k91 次安装7 周前更新
代码仓库

关于 kh-assistant

kh-assistant 是面向 terraform-hcloud-kube-hetzner 的专家 Agent 技能,用于回答集群部署与运维问题。它会优先匹配专门技能,并依据项目文档和最新发布信息提供指引。

主要功能

  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 助手

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.xmigrate-v2-to-v3审计并重写 v2 合约、保留状态,并强制执行受保护基础设施的计划门禁/migrate-v2-to-v3
升级或加固运行中的集群、模块/提供程序、k3s/RKE2,或安全地替换节点upgrade-cluster将模块收敛与运行时部署分开,并验证 Terraform 和 Kubernetes 的健康状况/upgrade-cluster
诊断无法访问的节点、SSH/cloud-init 故障或卡住的资源配置debug-node使用 Hetzner 救援模式挂载并检查节点,无需通过 SSH 连接节点/debug-node
使用 Terraform 和 OpenTofu 验证模块更改test-changes针对提供的测试根配置运行格式化、验证、兼容性、示例和计划门禁/test-changes
实现 GitHub issue(仅限维护者)fix-issue获取并验证 issue、实现根因修复、测试,并保留贡献者署名/fix-issue <number>
对 GitHub issue 进行分类并回复(仅限维护者)triage-issue检查证据和重复问题、对报告进行分类,并起草适当的回复/操作/triage-issue <number>
审查 pull request(仅限维护者)review-pr对不受信任的贡献进行安全性、兼容性、回归和代码质量审查/review-pr <number>
同步项目文档(仅限维护者)sync-docs确保 variables.tf、生成的/参考文档、示例、迁移文档和技能保持一致/sync-docs
准备或执行发布(仅限维护者)prepare-release验证发布内容和版本;仅在维护者明确授权发布时才打标签/推送/prepare-release
在运行中的 v3 矩阵中验证高风险更改(仅限维护者)running-stabilization-loop迭代运行、诊断、修复并重新运行 k3s/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 默认使用上游 stable 通道;如果需要可复现性或保留 v2 次版本,请固定版本/通道
节点操作系统全新节点池默认使用 Leap Micro;现有 MicroOS 节点池仍受支持,并会在常规 v2 升级中保留
插件版本未设置插件版本输入项时,将使用经过审核的确定性模块矩阵;latest 是选择上游浮动版本行为的显式选项

关键规则

必须遵守 — 绝不可违反
规则说明
至少 1 个控制平面control_plane_nodepools 必须至少包含一个 count >= 1 的条目
仅使用受支持的操作系统新节点默认使用 Leap Micro;MicroOS 仅用于旧版支持/升级。绝不要建议使用 Ubuntu、Debian 或其他通用操作系统映像。
网络区域覆盖范围network_region 必须包含所有节点位置
高可用时控制平面数量必须为奇数使用 1、3 或 5 个,绝不要使用 2 或 4 个(法定人数要求)
自动扩缩器是独立的autoscaler_nodepools 独立于 agent_nodepools
始终使用最新版本始终获取并使用最新的发行标签
需要避免的常见错误
错误正确做法
control_plane_nodepools 为空至少配置一个,且 count >= 1
为实现“高可用”配置 2 个控制平面使用 3 个(法定人数要求为奇数)
建议使用 Ubuntu/Debian默认使用 Leap Micro;仅对旧版或明确指定的节点池使用 MicroOS
位置不在 network_region 中network_region 必须涵盖所有位置
混淆自动扩缩器与 Agent自动扩缩器节点池完全独立
使用旧版本务必先检查最新版本
在 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 专用 Networks 之间无法路由
将外部 Tailscale 钩子当作节点传输方式集群传输使用 node_transport_mode = "tailscale";仅将 node_connection_overrides 用于用户自有的运维访问
将 Cloudflare Mesh/WARP 当作受支持的节点传输方式kube-hetzner 管理的安全节点传输使用 Tailscale;Cloudflare Access/Tunnel 仅用于外部运维人员/应用访问
假设单个 Hetzner Network 可以容纳超过 100 个节点分散到多个 Hetzner Networks,并统计所有连接,包括控制平面、静态 Agent、自动扩缩器 max_nodes、NAT 路由器和负载均衡器
承诺在单个项目中静态分布 1 万个节点Hetzner 分布组每组可容纳 10 台服务器,每个项目最多 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
在低信任节点上启用内置镜像仓库镜像仅用于信任级别相同的集群;提醒用户注意凭据共享和标签投毒
因单个工作负载被拒绝而全局禁用 SELinux遵循 docs/selinux.md:收集 AVC,尝试使用 udica,最后才考虑设置每个节点池的 selinux = false
假设 RKE2 控制平面需要 8GB 内存v3 按规格预留的 kubelet 资源使 4GB cx23 控制平面可行;生产环境仍应为工作负载预留充足空间
拆除时手动删除云资源首先使用 scripts/destroy.sh;scripts/cleanup.sh 是强制清理的后备方案,会清理令牌所属的整个 HCloud 项目
v3 拓扑速查
需求建议
小型开发环境单个控制平面、一个小型 Agent 节点池;非必要时不配置入口
常规高可用3 个控制平面、至少 2 个 Agent、一个主 Hetzner Network
仅限专用网络在主 Network 上配置 NAT 路由器和专用控制平面负载均衡器
安全 API/SSH设置 node_transport_mode = "tailscale",并关闭公共 API/SSH 防火墙来源
受 Cloudflare 保护的运维人员/应用访问在 kube API、SSH、Rancher、Grafana 或入口前使用用户管理的 Cloudflare Access/Tunnel;节点传输仍使用 Hetzner 专用网络或 Tailscale
超过 100 个 Cloud 节点使用 Tailscale 节点传输方式,并为每 100 个节点的预算配置一个外部 Hetzner Network 分片
1 万节点参考配置优先采用自动扩缩器的 Tailscale 多网络方案;参考 examples/tailscale-node-transport/massive-10000-nodes.tf.example
Cilium Gateway API使用 Cilium,设置 enable_kube_proxy = false 和 cilium_gateway_api_enabled = true
大量拉取镜像仅在可信集群上设置 embedded_registry_mirror.enabled = true

常见问题目录

v3.0.0 中的回归问题已在 v3.0.1 中修复
  • 零 Agent 集群的 apply 后计划失败(#2236、#2238): v3.0.0 中设置了 agent_nodepools = [] 的集群在后续计划时会因 no change found for terraform_data.agents 而失败。请升级到 v3.0.1 或更高版本;该版本通过单个 Agent ID 聚合器传递就绪状态触发器,升级时不会替换或重新运行安装后就绪检查。
  • 静态 Agent 被分配到错误的子网(#2239): v3.0.0 会将主网络中的静态 Agent 分配到控制平面子网。v3.0.1 或更高版本恢复了按节点池分配地址的行为。在 v3.0.0 上首次创建的集群需要按照发行说明执行滚动 Agent 迁移:对一个 Agent 执行 cordon/drain,针对该 Agent 执行 apply,使其原地分离并重新连接专用 NIC,并重启 k3s/RKE2 配置;确认它在目标子网上处于 Ready 状态后,取消 cordon,然后继续处理其他 Agent。如果接口映射没有恢复,请重启以便 kh-rename-interface.service 进行验证。从 v2.x 升级的常规集群会保留 v2 的 IP 公式,不受影响。
常见错误模式
错误原因解决方案
cannot sum empty listcontrol_plane_nodepools 为空或所有数量均为 0至少添加一个数量 >= 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 是否与现有 CIDR 重叠
cloud-init failed缺少 Leap Micro/MicroOS 快照、区域错误、架构错误或发行版标签错误使用 packer 在正确的区域和架构中重新创建快照,并选择 k3s/RKE2 SELinux 变体
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 示例中当前采用的最低配置。在基于大小设置 kubelet 预留资源后,RKE2 + Leap Micro cx23 控制平面配置已在实际环境中验证,详见 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 中的精确工作流。

核心规则:

  • 编辑前备份状态。
  • 使用 MIGRATION.md 重写仅适用于 v2 的输入。
  • 谨慎反转正向 / 负向布尔值。
  • 保留首次应用的兼容性冻结,除非运维人员有意选择更改拓扑 / 运行时:k3s_channel = "stable" 是 v3 默认值,但 v2 升级通常会固定为 k3s_channel = "v1.33" 或 k3s_version;未设置的附加组件版本将采用经过审查且确定性的默认值;network_subnet_mode 保持为 per_nodepool;node_transport_mode 保持为 hetzner_private。
  • 移除 network_id = 0;在 v3 中,省略或设为 null 表示主 Network。
  • 移除控制平面的 network_id;控制平面始终使用主 Network。
  • 对于安全的 Tailnet 访问或私有多网络扩展,优先选择 node_transport_mode = "tailscale"。对于 v2 到 v3 的升级,请在基础升级后,通过单独且经过审计的计划引入大规模多网络扩展。Tailscale 模式会让 Kubernetes 节点 IP 保持在 Hetzner 私有地址上,并可在禁用 Tailscale 子网路由 SNAT 的情况下通告节点私有 /32 路由。Tailscale 模式下的活动 Agent / 自动扩缩器节点池必须设置 network_scope = "primary" 或 network_scope = "external",以便在计划阶段发现无效的同根外部 Network 配置并报错。
  • 暂时不要建议将 Calico 与 Tailscale 节点传输模式搭配使用。Flannel 是首个受支持的方案;Cilium 在此传输模式下仍明确属于实验性功能。
  • 对于 Cloudflare,只推荐用于 kube API、SSH、Rancher、Grafana 或入口流量的外部 Access / Tunnel 模式。不要建议将 Cloudflare Mesh / WARP 用作 kube-hetzner 节点传输方式,也不要虚构 Cloudflare 提供商输入项。
  • 运行 terraform fmt -recursive、terraform init -upgrade、terraform validate 和 terraform plan -out=v3-upgrade.tfplan。
  • 运行 MIGRATION.md 中受保护的 hcloud 禁止销毁检查关卡;其中包含 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
}
生产级高可用配置(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 网络的私有集群时使用。不要将较旧的外部覆盖网络模式用于 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 模式要求每个启用的 Agent/自动扩缩容节点池都显式设置 network_scope = "primary" 或 "external"。省略或设为 null network_id 时使用 "primary";搭配外部 network_id 时使用 "external",包括同一根模块中的 hcloud_network.*.id。
  • 在此版本中,Tailscale 节点传输不支持设置 cluster_ipv6_cidr / service_ipv6_cidr;Tailscale 集群应将 IPv6 Pod/Service CIDR 留空。
  • 使用外部 network_scope 节点池时,Tailnet ACL 必须自动批准所通告的 Hetzner 节点私有 /32 路由。
  • 此模块会为节点/CNI 流量禁用 Tailscale 子网路由 SNAT。
  • 首先支持 Flannel VXLAN;Cilium 需要启用实验性标志;Calico 不受支持。
  • 单主网络集群可使用 Hetzner 托管私有 LB;外部 network_scope 节点池需要公共 LB 目标,或使用非 Hetzner/私有替代方案。
  • 此模块的 NAT 路由器仅向主 Hetzner 网络提供出站流量;外部网络上的 Tailscale 节点池需要公共出站流量或外部引导路径。
  • 大型示例位于 examples/tailscale-node-transport/large-scale-200.tf.example 和 examples/tailscale-node-transport/massive-10000-nodes.tf.example。
  • 200 节点静态示例包含 3 个控制平面 + 97 个主网络 Agent + 100 个位于同一外部网络的 Agent;两个网络都恰好达到 Hetzner 的 100 个连接上限,placement group 会自动分片为 21 个组。
  • 10,000 个总节点的参考配置为 3 个控制平面 + 7 个静态系统 Agent + 90 个主网络自动扩缩容工作节点 + 99 个外部网络 * 每个网络 100 个自动扩缩容工作节点。这是配额/设计参考,并非可随意采用的默认配置。
  • 大型集群推荐的暴露模型会关闭公共 Kubernetes API 和 SSH,不使用公共托管 Web 入口(除非明确要求),并依赖 Tailnet 访问。节点仍可保留公共 IPv4/IPv6,用于 Tailscale 引导和直接 UDP/41641 WireGuard 连接;要实现真正无公共 IP 的多网络集群,每个外部网络都需要私有出站流量和外部 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!

评论

支持 Markdown