跳到主要内容

代码走读

这一页按文件类型解释项目代码。目标是看完后能知道每个文件负责什么、被谁调用、失败时从哪里查。

根目录

文件作用
README.md仓库首页,说明项目目标、技术栈、目录和快速入口
plan.md从 0 到完全体的复现手册和问题记录
Makefile把 Terraform、Ansible、脚本、检查命令封装成统一入口
.gitignore排除真实变量、state、kubeconfig、token、生成产物
docs指向 website/docs 的软链接

Makefile

Terraform 入口:

aliyun-init:
cd aliyun && terraform init

aliyun-plan:
cd aliyun && terraform fmt -recursive && terraform validate && terraform plan -out=tfplan

这里把 fmtvalidateplan 放在同一个 target 中。每次生成计划前先保证格式和语法通过。

输出入口:

aliyun-output:
mkdir -p generated/aliyun
cd aliyun && terraform output -json > ../generated/aliyun/terraform-output.json

generated/ 是 Terraform 到脚本之间的边界。脚本不直接读取 state,而是读取稳定的 output JSON。

Ansible 入口:

ansible-inventory:
scripts/render-ansible-inventory.sh

ansible-site: ansible-inventory
ANSIBLE_CONFIG=ansible/ansible.cfg ansible-playbook ansible/playbooks/site.yml

Ansible 负责节点系统初始化、WireGuard underlay 和 kubeadm。Terraform output 先渲染成 ansible/inventory/generated.yml,再由 playbook 使用。

Cilium 配置入口:

render-configs:
scripts/render-kubeadm-config.sh aliyun
scripts/render-kubeadm-config.sh tencent
scripts/render-cilium-values.sh aliyun
scripts/render-cilium-values.sh tencent

这一步把云资源输出转成 kubeadm 和 Helm 能用的配置。

Terraform root modules

aliyun/main.tftencent/main.tf 的结构一致:

module "vpc" {
source = "../modules/aliyun-vpc"
}

module "security_group" {
source = "../modules/aliyun-security-group"
}

module "ecs" {
source = "../modules/aliyun-ecs"
}

module "lb" {
source = "../modules/aliyun-lb"
}

module "vpn" {
source = "../modules/aliyun-vpn"
}

调用顺序表达依赖关系:先网络,再安全组,再节点,再负载均衡,VPN 作为可选路线。

Terraform variables

变量文件提供默认值和校验:

variable "clustermesh_api_node_port" {
type = number
default = 32379

validation {
condition = var.clustermesh_api_node_port >= 30000 && var.clustermesh_api_node_port <= 32767
error_message = "clustermesh_api_node_port must be in the Kubernetes NodePort range 30000-32767."
}
}

端口校验提前阻止无效 NodePort 进入计划阶段。

Terraform outputs

outputs 只暴露脚本需要的信息:

output "master_public_ips" {
description = "Master public IPs."
value = module.ecs.master_public_ips
}

这些 output 会被 jq 读取:

jq -r '.master_public_ips.value[0]' generated/aliyun/terraform-output.json

安全组模块

安全组规则来自变量组合:

locals {
mesh_cidrs = distinct(concat([var.local_vpc_cidr, var.peer_vpc_cidr], var.clustermesh_lb_allowed_cidrs))
}

这样同一组规则能覆盖本地 VPC、对端 VPC 和额外允许来源。WireGuard 端口由 wireguard_port 控制。

节点模块

节点模块使用 node_groups 批量创建 master 和 worker。输出实例 ID 给 LB,输出公网和私网 IP 给脚本。

节点模块不做系统初始化,因为 containerd、kubeadm、WireGuard 属于节点运行时过程,交给 Ansible 更容易保证幂等性和批量执行。

Ansible

scripts/render-ansible-inventory.sh 读取两云 Terraform outputs,生成分组 inventory:

  • aliyun_mastersaliyun_workers
  • tencent_masterstencent_workers
  • mastersworkersk8s_nodes

ansible/playbooks/site.yml 串联三个阶段:

- import_playbook: bootstrap.yml
- import_playbook: underlay.yml
- import_playbook: kubeadm.yml

roles 分工:

  • common:swap、内核模块、sysctl 和基础包。
  • containerd:安装 containerd,启用 systemd cgroup,配置 pause 镜像。
  • kubernetes_packages:安装并 hold kubelet、kubeadm、kubectl。
  • wireguard_underlay:生成节点级 full-mesh WireGuard 配置。
  • kubeadm_cluster:初始化每个云的第一个 master,并加入 worker。

LB 模块

API LB 后端只绑定 master:

master_instance_ids = module.ecs.master_instance_ids

Cluster Mesh LB 后端绑定所有节点:

all_instance_ids = module.ecs.all_instance_ids

因为 Cluster Mesh API 通过 NodePort 暴露,所有节点都可以作为入口。

WireGuard 脚本

scripts/setup-wireguard-underlay.sh 做四件事:

  1. 读取两云 output。
  2. 登录每台节点安装 WireGuard。
  3. 为每个节点生成或读取 key。
  4. 写入 full-mesh peer 配置并启动 wg-quick@wg0

关键输入:

ALIYUN_OUTPUT="${ALIYUN_OUTPUT:-generated/aliyun/terraform-output.json}"
TENCENT_OUTPUT="${TENCENT_OUTPUT:-generated/tencent/terraform-output.json}"
WG_PORT="${WG_PORT:-51820}"
WG_CIDR_PREFIX="${WG_CIDR_PREFIX:-10.255.0}"

kubeadm 渲染脚本

scripts/render-kubeadm-config.sh 从 output 中读取:

cluster_name="$(jq -r '.cluster_name.value' "${TF_OUTPUT}")"
pod_cidr="$(jq -r '.pod_cidr.value' "${TF_OUTPUT}")"
service_cidr="$(jq -r '.service_cidr.value' "${TF_OUTPUT}")"
api_lb="$(jq -r '.k8s_api_lb_public_ip.value' "${TF_OUTPUT}")"

然后写出 generated/<cloud>/kubeadm-config.yamlcontrolPlaneEndpoint 使用 LB 地址,证书 SAN 包含 LB 和 master 私网 IP。

Cilium 安装脚本

scripts/install-cilium.sh 使用 Helm:

helm upgrade --install cilium cilium/cilium \
--namespace kube-system \
--version "${version}" \
--values "${OUT_DIR}/cilium-values.yaml" \
--kube-context "${context}"

安装后立即执行:

cilium status --context "${context}" --wait

这样脚本失败会停在 Cilium 未健康的阶段,不会继续执行 Cluster Mesh。

Cluster Mesh 脚本

scripts/enable-clustermesh.sh 先启用两边 Mesh,再把 NodePort patch 到固定端口:

kubectl --context "${context}" -n kube-system patch service clustermesh-apiserver \
--type='json' \
-p="[{\"op\":\"replace\",\"path\":\"/spec/ports/0/nodePort\",\"value\":${NODE_PORT}}]"

连接时使用:

cilium clustermesh connect \
--context "${ALIYUN_CONTEXT}" \
--destination-context "${TENCENT_CONTEXT}" \
--destination-endpoint "${TENCENT_ENDPOINT}" \
--allow-mismatching-ca

文档站

website/docusaurus.config.ts 控制站点标题、导航、构建配置。website/sidebars.ts 控制 docs 左侧目录。

验证命令:

cd website
npm run build

如果构建失败,先看断链、front matter、sidebar id 是否一致。