mcpField
M
migrate-v2-to-v3

migrate-v2-to-v3

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

关于 migrate-v2-to-v3

面向运维人员的迁移技能,用于将现有 kube-hetzner Terraform 配置从 v2 升级到 v3。流程强调备份状态、审慎修改配置,并在执行 apply 前检查计划中的破坏性基础设施替换。

主要功能

  1. 01审计 v2 配置参数
  2. 02映射为 v3 参数名称
  3. 03指导状态备份与验证
  4. 04检查计划中的破坏性变更
  5. 05提示 Kubernetes 升级选项

适用场景

  1. 01为现有集群准备 v3 升级
  2. 02查找已弃用的 v2 模块参数
  3. 03升级前审查资源替换风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mysticaltech/terraform-hcloud-kube-hetzner --skill migrate-v2-to-v3

安装后在 Claude Code 中输入/migrate-v2-to-v3确认已加载。

详细介绍

将 kube-hetzner v2 迁移到 v3

目的

安全地将现有 kube-hetzner 集群从 v2.x 迁移到 v3.x。

此技能面向实际用户的 Terraform 根目录,而非全新集群。其优先事项是保留基础设施,并让 Terraform 验证失败具有可操作性。

权威参考资料

编辑前请阅读:

  1. docs/v2-to-v3-migration.md - 运维迁移手册
  2. docs/v3-release-evidence.md - v2.21 -> v3 升级实证
  3. MIGRATION.md - 权威的新旧变量映射表
  4. CHANGELOG.md - v3 升级说明和版本背景
  5. variables.tf - v3 输入契约和验证规则的准确内容
  6. kube.tf.example - 当前 v3 配置示例
  7. scripts/v2_to_v3_migration_assistant.py - 静态配置和计划审计
  8. docs/selinux.md - SELinux 策略、AVC 证据和按节点池设置的回退方案
  9. scripts/destroy.sh 和 scripts/cleanup.sh - 拆除和孤立资源清理

安全规则

  • 除非用户在审查计划后明确要求,否则绝不运行 terraform apply。
  • 更改模块版本前,始终备份状态。
  • v3 升级计划中出现 destroy、replace 或 forces replacement 时,绝不能忽略。
  • 不允许 K3s 通道策略悄然变更。MIGRATION.md 说明,v2 的 k3s_channel 默认值为 v1.33;v3 的默认值则为 stable,同时自动 Kubernetes 升级仍默认启用。用户必须在首次 v3 应用前作出选择。
  • 将对 hcloud_network、hcloud_network_subnet、hcloud_server、hcloud_load_balancer、hcloud_primary_ip、hcloud_placement_group、hcloud_volume 或 hcloud_firewall 的替换视为阻断项,直到得到解释。
  • 对生产环境的原地升级,MIGRATION.md 是面向运维人员的安全契约。其禁止销毁的 jq 门禁是权威标准;不得放宽或缩略。
  • 迁移期间或之后,绝不能在列表中间重新排序或插入控制平面或 Agent 节点池。节点资源地址以索引为键;除非用户有意规划状态迁移或蓝绿重建,否则只能追加。
  • 不得通过绕过验证来“修复”v3 验证错误。应修正配置。
  • 对自定义网络、仅私有网络、Robot/vSwitch 或多网络集群,如果原地升级计划无法明确证明安全,优先建议采用蓝绿方案。

必需输入

确定以下信息:

  • Terraform 根目录路径。
  • 当前模块来源和版本。
  • 目标 v3 标签。
  • Kubernetes 发行版意图:保留 k3s,还是将 RKE2 重建/迁移与基础 v2 -> v3 模块升级分开规划。
  • K3s 版本/通道意图:固定 k3s_version、设置 k3s_channel = "v1.33",或明确接受 v3 的 stable。
  • 节点是否在 ssh_public_key/ssh_additional_public_keys 之外配置了带外 root SSH 密钥。
  • Terraform 是否能够通过 SSH 连接到所有现有节点,以运行 terraform_data.initial_readiness,包括仅私有网络、NAT 和堡垒机拓扑。
  • 这是否为生产环境中的运行集群。
  • 是否使用 NAT 路由器、仅私有节点、Robot/vSwitch、自动扩缩器、Cilium、Longhorn 或外部网络。
  • SELinux 工作负载拒绝是否属于当前故障的一部分。如果是,请收集 AVC 证据并遵循 docs/selinux.md,而不要全局禁用 SELinux。

工作流

1. 检查当前根目录

在用户的 Terraform 根目录中运行:

terraform version
terraform providers
rg -n 'module "kube-hetzner"|source\\s*=|version\\s*=' .

查找仅适用于 v2 的输入项:

uv run python /path/to/kube-hetzner/scripts/v2_to_v3_migration_assistant.py --root .
rg -n 'kubernetes_distribution_type|k3s_token|secrets_encryption|initial_k3s_channel|install_k3s_version|initial_rke2_channel|install_rke2_version|automatically_upgrade_k3s|sys_upgrade_controller_version|additional_k3s_environment|kubeapi_port|k3s_registries|k3s_kubelet_config|k3s_audit_policy_config|k3s_audit_log_path|k3s_audit_log_maxage|k3s_audit_log_maxbackup|k3s_audit_log_maxsize|k3s_exec_server_args|k3s_exec_agent_args|k3s_global_kubelet_args|k3s_control_plane_kubelet_args|k3s_agent_kubelet_args|k3s_autoscaler_kubelet_args|subnet_amount|placement_group_disable|block_icmp_ping_in|disable_hetzner_csi|load_balancer_disable_ipv6|load_balancer_disable_public_network|use_control_plane_lb|combine_load_balancers|control_plane_lb_type|control_plane_lb_enable_public_interface|control_plane_lb_enable_public_network|lb_hostname|robot_ccm_enabled|hetzner_ccm_use_helm|enable_hetzner_ccm_helm|cilium_loadbalancer_acceleration_mode|enable_wireguard|k8s_config_updates_use_kured_sentinel|keep_disk_agents|keep_disk_cp|use_private_bastion|disable_kube_proxy|disable_network_policy|disable_selinux|k3s_prefer_bundled_bin|placement_group_compat_idx|disable_ipv4|disable_ipv6|autoscaler_disable_ipv4|autoscaler_disable_ipv6|existing_network_id|enable_x86|enable_arm|k3s_encryption_at_rest|autoscaler_labels|autoscaler_taints|extra_kustomize_' .

助手应作为首轮报告的主要来源。如果根目录使用了不常见的格式、Terragrunt、生成的 HCL 或拆分的 tfvars,则可将 rg 命令作为手动交叉检查。

2. 备份
terraform state pull > "terraform-state-before-kube-hetzner-v3-$(date +%Y%m%d%H%M%S).json"
find . -maxdepth 1 -name '*.tf' -print

如果直接编辑用户配置,请保留一份已修改 .tf 文件的副本。

3. 重写配置

完整映射请参阅 MIGRATION.md。关键转换:

  • 重命名与发行版无关的输入,例如将 k3s_token 改为 cluster_token,将 kubernetes_distribution_type 改为 kubernetes_distribution。
  • 反转否定布尔值:
    • 将 disable_kube_proxy 改为 enable_kube_proxy
    • 将 disable_network_policy 改为 enable_network_policy
    • 将 disable_selinux 改为 enable_selinux
    • 将节点池的 disable_ipv4/disable_ipv6 改为 enable_public_ipv4/enable_public_ipv6
    • 将 autoscaler_disable_ipv4/disable_ipv6 改为 autoscaler_enable_public_ipv4/autoscaler_enable_public_ipv6
  • 将 existing_network_id = ["123"] 替换为 existing_network = { id = 123 }。
  • 将 enable_x86/enable_arm 替换为 enabled_architectures。
  • 移除控制平面的 network_id;控制平面仅使用主网络。
  • 移除 network_id = 0;在 v3 中,主网络应省略或设为 null。
  • 对常规的就地 v2 升级,保留默认值 network_subnet_mode = "per_nodepool";此设置与已发布的 v2 子网资源相符。仅对新集群或有意更改子网拓扑时,才使用 network_subnet_mode = "shared"。
  • 将 placement_group_compat_idx 替换为 placement_group_index。
  • 将 extra_kustomize_* 替换为 user_kustomizations。
  • 移除 enable_iscsid、k3s_encryption_at_rest、autoscaler_labels 和 autoscaler_taints。
  • 移除 hetzner_ccm_use_helm / enable_hetzner_ccm_helm;v3 始终通过 HelmChart 清单安装 Hetzner CCM。
  • 重写配置时,不要调整现有节点池的顺序,也不要插入节点池。只能追加新节点池。如果用户想更改列表顺序,请停止操作,并将其作为单独的状态迁移或蓝绿设计问题处理。
4. 先确定首次应用的意图

在首次应用 v3 前,先确定以下事项:

  • Kubernetes 通道策略。MIGRATION.md 说明了默认值的静默变更:v2 使用 k3s_channel = "v1.33",v3 使用 k3s_channel = "stable",且 automatically_upgrade_kubernetes 仍默认启用。让用户准确选择以下一项:
    • 固定 k3s_version
    • 设置 k3s_channel = "v1.33",以保留 v2 的次版本通道
    • 明确接受跟随 stable
  • 插件版本策略。v2 中未设置或浮动的插件版本会解析为上游最新版本。v3 中未设置的插件版本会使用 kube-hetzner 审核过的确定性默认版本矩阵。升级计划可能会显示一次性的插件版本变更。若要保留浮动行为,必须显式设置为 latest。
  • SSH 授权密钥策略。首次应用 v3 时, terraform_data.ssh_authorized_keys 会协调 /root/.ssh/authorized_keys。默认情况下,会保留未知的带外密钥,同时撤销已从 ssh_public_key 或 ssh_additional_public_keys 中移除的模块管理密钥。只有当用户希望严格替换为恰好包含模块管理密钥时,才设置 ssh_authorized_keys_exclusive = true。
  • 节点可达性。terraform_data.initial_readiness 会通过 SSH 连接到每个现有控制平面节点和 Agent 节点。仅使用私有网络、NAT 或堡垒机的运维人员必须确保 Terraform 在应用前能够连接到所有节点。

已验证的 2026-07-04/05 标准在线升级,仅需切换模块源,并在首次 v3 计划中设置 k3s_channel = "v1.33"。

5. 初始化并验证
terraform fmt -recursive
terraform init -upgrade
terraform validate -no-color
tmpdir="$(mktemp -d)"
rsync -a --exclude .git --exclude .terraform --exclude .terraform-tofu ./ "$tmpdir"/
(cd "$tmpdir" && tofu init -backend=false -input=false && tofu validate -no-color)
rm -rf "$tmpdir"

terraform validate 会检查模块是否已加载。v3 的跨变量迁移防护由 terraform_data.validation_contract 强制执行,因此,保存的 terraform plan 是验证无效组合和替换风险所必需的依据。

如果验证失败,请在更改配置前查看 variables.tf 中的变量和验证块。

6. 计划
terraform plan -out=v3-upgrade.tfplan
terraform show v3-upgrade.tfplan
terraform show -json v3-upgrade.tfplan > v3-upgrade-plan.json
uv run python /path/to/kube-hetzner/scripts/v2_to_v3_migration_assistant.py --root . --plan-json v3-upgrade-plan.json --strict

严格审计器还会阻止单独分离服务器与网络,并标记已更改或未知的内联私有/公共网络配置。没有服务器替换并不能证明 IP/MAC 得到保留、来宾系统路由持续有效,或滚动发布满足仲裁安全要求。请遵循 MIGRATION.md#network-and-ssh-transition-limits;保留现有 SSH 端口,并在迁移前比较 Cilium 的有效值。

如果有 jq,请列出破坏性操作:

terraform show -json v3-upgrade.tfplan \
  | jq -r '.resource_changes[]? | select(.change.actions | index("delete")) | "\(.address): \(.change.actions | join(","))"'

对于正在进行的 v2 -> v3 迁移,请运行受保护基础设施检查。Terraform 替换会显示为包含 delete 的操作列表。该检查仅输出阻止继续的资源;任何输出都意味着必须停止:

terraform show -json v3-upgrade.tfplan \
  | jq -r '
      .resource_changes[]?
      | select(.type as $type | [
          "hcloud_server",
          "hcloud_network",
          "hcloud_network_subnet",
          "hcloud_load_balancer",
          "hcloud_volume",
          "hcloud_primary_ip",
          "hcloud_placement_group",
          "hcloud_firewall"
        ] | index($type))
      | select(.change.actions | index("delete"))
      | "\(.address): \(.type) \(.change.actions | join(","))"
    '

完成 v2 重命名后,计划必须显示 hcloud_server、hcloud_network、hcloud_network_subnet、hcloud_load_balancer、hcloud_volume、hcloud_primary_ip、hcloud_placement_group 和 hcloud_firewall 的 destroy/replace 操作为零。如果列出了其中任何类型,请停止并排查,然后再执行 apply。

不要因首个 v3 计划中以下预期操作而惊慌中止:

  • 因添加触发器键而重新运行一次幂等的 k3s/RKE2 kustomization
  • 新增用于就绪检查、SSH authorized-key reconcile、验证器和销毁清理的 terraform_data 资源
  • 原地更新服务器标签,例如 kube-hetzner/os
  • 防火墙规则更新
7. 解读特殊情况
  • 从 v2.19 之前的集群替换 NAT 路由器主 IP,可能需要在应用前迁移状态。
  • existing_network 与 vswitch_id 组合使用时,不能由模块管理 expose_routes_to_vswitch;请将其设为 false,或手动启用路由公开。
  • 仅使用私有网络的集群需要可用的 NAT/堡垒机/控制平面加入路径。
  • 多网络公共 Overlay 是仅供实验室使用的预览功能。它要求设置 multinetwork_mode = "cilium_public_overlay"、 enable_experimental_cilium_public_overlay = true 和 cni_plugin = "cilium";在实时数据平面的端到端测试通过前,不要建议在生产升级中使用。
  • Tailscale 节点传输已通过静态验证并纳入计划矩阵覆盖,但 Hetzner/Tailscale 实时端到端测试仍待完成。评估时请使用 node_transport_mode = "tailscale",并单独审核计划;不要仅凭静态检查认证生产拓扑。
  • Tailscale 模式会将 Kubernetes 节点 IP 保留在 Hetzner 私有地址上,并可在禁用 Tailscale 子网路由 SNAT 的情况下,公开节点私有 /32 路由。单网络集群可以禁用路由通告;外部 network_scope = "external" 节点池必须启用路由通告和 Tailnet 自动批准。
  • 外部 Agent/自动扩缩容器 Network ID 必须是正数的 Hetzner Network ID。 省略或设为 null 表示使用主 Network。在 Tailscale 模式下,活动的 Agent/自动扩缩容器节点池还必须设置 network_scope = "primary" 或 network_scope = "external",以便同一根目录中的外部 Network ID 能在 terraform plan 期间通过验证。
  • 首次原地应用 v2 到 v3 升级时,不要同时添加新的可选 v3 功能,例如 cilium_gateway_api_enabled、 embedded_registry_mirror、新的 Tailscale 多网络分片,或外部 Cloudflare Access/Tunnel 路由,除非操作员明确接受蓝绿/拓扑变更迁移。先完成干净升级,再通过单独审核的计划添加这些功能。
  • Cloudflare Access/Tunnel 仅适用于外部访问模式。不要虚构 Cloudflare 提供商输入,也不要在迁移期间建议使用 Cloudflare Mesh/WARP 作为 kube-hetzner 节点传输方式。
  • v3 默认仍启用 SELinux。对于工作负载拒绝,请使用 docs/selinux.md:收集 AVC 行,优先尝试 udica 生成的工作负载策略;只有在有可复现的 AVC 证据时,才建议上游模块策略;仅将每个节点池的 selinux = false 作为最后手段。
  • 如果用户之后要销毁集群,请从 Terraform 根目录运行 scripts/destroy.sh。它只会针对已知的无害 ingress-LB 分离竞态自动重试 (双重 CCM 与 Terraform 所有权冲突导致的 resource_already_detaching/422),然后生成只读孤立资源报告,列出未标记的主 IP、 不在状态中的自动扩缩容节点,以及名称完全匹配的托管 LB。只有在报告显示仍有遗留资源或状态已损坏后,才将 scripts/cleanup.sh 作为强制回退方案使用。它会将令牌所属的整个 HCloud 项目视为专用于该集群;请先审核试运行结果,并仅在有意为之时包含持久化数据。
  • 自动扩缩容器创建的服务器不在 Terraform 状态中,可能阻止删除网络/子网。只有在控制平面关闭后才删除这些孤立资源;或者先将自动扩缩容器节点池缩容至 min_nodes = 0。在 Cluster Autoscaler 仍运行时提前删除,可能会导致这些服务器重新创建。
  • 如果在迁移后添加 Cilium Gateway API,必须设置 cni_plugin = "cilium" 和 enable_kube_proxy = false。
  • 如果在迁移后添加内嵌注册表镜像,请提醒用户节点之间具有相同的信任级别,关键镜像应使用摘要。
8. 报告

返回迁移报告:

## kube-hetzner v2 -> v3 migration report

- Terraform root:
- Source version:
- Target version:
- Terraform/OpenTofu version:
- hcloud provider version:
- K3s channel/version intent:
- Kubernetes distribution intent:
- Addon version intent:
- SSH authorized_keys policy:
- SELinux intent and AVC evidence, if relevant:
- Inputs changed:
- Inputs removed:
- Manual state actions:
- Validation result:
- Plan result:
- Protected hcloud delete/replace gate:
- Replacements/destroys:
- Expected first-apply actions:
- Blockers:
- Recommendation:

应用策略

仅在用户明确批准且计划报告中没有未解释的破坏性操作后,才运行:

terraform apply v3-upgrade.tfplan

评论

支持 Markdown