Skip to content

基于 WireGuard 覆盖网络的跨地域 Kubernetes 高可用集群部署指南

方案概述

技术栈

  • 操作系统:Debian 12
  • 容器编排:Kubernetes v1.33.1
  • 覆盖网络:WireGuard(跨地域节点互联)
  • 容器网络:Calico CNI v3.30.1
  • 服务网格:Istio v1.26.1(通过 ArgoCD 部署)
  • 流量入口:Traefik Ingress Controller
  • GitOps:ArgoCD 自动化部署

集群架构

┌─────────────────┬──────────────────┬─────────────────┐
│   亚利桑那      │      英国        │      香港       │
│  173.249.204.114│  104.128.190.41  │ 27.106.126.139  │
│  WG: 10.0.0.1   │  WG: 10.0.0.2    │  WG: 10.0.0.3   │
│  Master1 (主)   │  Master2 (备)    │  Worker1        │
└─────────────────┴──────────────────┴─────────────────┘
            │              │               │
            └──────── WireGuard 覆盖网络 ───────┘
                     负载均衡: 159.138.44.125

架构特点

  • 跨地域高可用:主备 Master 节点分布在不同大洲,确保任意地域故障不影响集群运行
  • 网络安全:WireGuard 加密所有节点间通信,保障数据传输安全
  • GitOps 自动化:ArgoCD 管理所有应用生命周期,实现声明式部署
  • 生产就绪:完整的监控、日志、存储解决方案

部署流程

  1. 系统环境准备
  2. WireGuard 覆盖网络配置
  3. 防火墙安全配置
  4. Kubernetes 环境准备
  5. Master 节点初始化
  6. 其他节点加入集群
  7. Calico 网络插件安装
  8. Traefik 入口控制器部署
  9. ArgoCD GitOps 配置

第一步:系统环境准备

1.1 节点规划

本方案基于以下节点规划进行部署:

节点名称地理位置公网IPWireGuard IP角色配置要求
arizona美国亚利桑那173.249.204.11410.0.0.1Master12C4G+
uk英国104.128.190.4110.0.0.2Master22C4G+
hongkong香港27.106.126.13910.0.0.3Worker12C4G+

节点角色说明

  • Master1(主):集群控制平面主节点,运行 etcd、API Server、Controller Manager、Scheduler
  • Master2(备):控制平面备份节点,提供高可用保障
  • Worker1:工作节点,运行业务负载 Pod

1.2 基础组件安装

在所有节点上执行以下操作,安装必要的基础工具和 WireGuard 组件。

创建 install-base-packages.sh 脚本:

bash
#!/bin/bash
# 基础环境准备脚本

set -e

echo "🚀 开始系统环境准备..."

# 更新系统包
apt update && apt upgrade -y

# 安装必要工具
apt install -y \
    iptables \
    ufw \
    jq \
    curl \
    wget \
    vim \
    net-tools \
    wireguard \
    wireguard-tools

echo "✅ 基础组件安装完成"

执行安装:

bash
chmod +x install-base-packages.sh
sudo ./install-base-packages.sh

软件包说明

  • iptables:防火墙规则管理,Kubernetes 网络依赖
  • ufw:简化的防火墙管理工具
  • jq:JSON 处理工具,脚本中用于解析 Kubernetes 资源
  • wireguard/wireguard-tools:VPN 隧道核心组件
  • net-tools:网络诊断工具集

1.3 系统优化配置

针对 Kubernetes 集群运行环境进行系统级优化。

bash
# 设置时区为上海(可根据实际需要调整)
timedatectl set-timezone Asia/Shanghai

# 配置 SSH 允许 root 登录(可选,根据安全策略决定)
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh

# 禁用不必要的服务以节省资源
systemctl disable --now snapd
systemctl disable --now ufw  # 稍后会重新配置

echo "✅ 系统优化完成"

优化说明

  • 时区配置:统一时区便于日志分析和故障排查
  • SSH 配置:根据实际安全策略调整,生产环境建议使用密钥认证
  • 禁用服务:减少不必要的后台服务,降低资源消耗

第二步:WireGuard 覆盖网络配置

WireGuard 为跨地域的集群节点提供加密的 VPN 隧道,确保所有 Kubernetes 组件间通信的安全性和私密性。与传统 VPN 相比,WireGuard 具有更简单的配置、更高的性能和更强的安全性。

2.1 密钥生成

在每个节点上执行密钥生成脚本,创建 WireGuard 所需的公私钥对。

创建 generate-wg-keys.sh 脚本:

bash
#!/bin/bash
# WireGuard 密钥生成脚本

set -e

echo "🔑 开始生成 WireGuard 密钥..."

# 创建配置目录
sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard

# 生成密钥对
PRIVATE_KEY=$(wg genkey)
PUBLIC_KEY=$(echo "$PRIVATE_KEY" | wg pubkey)

# 保存密钥
echo "$PRIVATE_KEY" | sudo tee /etc/wireguard/private.key > /dev/null
echo "$PUBLIC_KEY" | sudo tee /etc/wireguard/public.key > /dev/null
sudo chmod 600 /etc/wireguard/private.key
sudo chmod 644 /etc/wireguard/public.key

echo "✅ 密钥生成完成"
echo "📋 本节点公钥: $PUBLIC_KEY"
echo ""
echo "💡 请记录此公钥,配置其他节点时需要使用"

执行密钥生成:

bash
chmod +x generate-wg-keys.sh
sudo ./generate-wg-keys.sh

2.2 收集所有节点公钥

在每个节点上查看并记录公钥:

bash
sudo cat /etc/wireguard/public.key

建议使用以下表格记录公钥信息:

节点名称WireGuard IP公钥
arizona10.0.0.1[粘贴亚利桑那节点公钥]
uk10.0.0.2[粘贴英国节点公钥]
hongkong10.0.0.3[粘贴香港节点公钥]

2.3 主网卡检测

在配置 WireGuard 前,需要确定每个节点的主网络接口名称。

创建 detect-interface.sh 脚本:

bash
#!/bin/bash
# 主网卡检测脚本

echo "🔍 检测主网络接口..."

# 获取默认路由的网卡
MAIN_INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n1)

echo "检测到的主网卡: $MAIN_INTERFACE"
echo "网卡详情:"
ip addr show $MAIN_INTERFACE | grep "inet "

echo ""
echo "💡 请在 WireGuard 配置中使用: $MAIN_INTERFACE"

执行检测:

bash
chmod +x detect-interface.sh
./detect-interface.sh

记录每个节点的主网卡名称(通常为 eth0ens3 等)。

2.4 WireGuard 配置

在每个节点上创建 /etc/wireguard/wg0.conf 配置文件。配置中的关键参数说明:

  • Address:本节点在 WireGuard 虚拟网络中的 IP 地址
  • PrivateKey:本节点的私钥
  • ListenPort:WireGuard 监听的 UDP 端口
  • PostUp/PostDown:启动/关闭时执行的 iptables 规则,实现 NAT 转发
  • PublicKey:对端节点的公钥
  • Endpoint:对端节点的公网 IP 和端口
  • AllowedIPs:允许通过隧道的 IP 地址范围
  • PersistentKeepalive:保持连接的心跳间隔(秒),穿透 NAT 必需

亚利桑那节点 (10.0.0.1) 配置

bash
sudo vi /etc/wireguard/wg0.conf

配置内容:

ini
[Interface]
Address = 10.0.0.1/24
PrivateKey = <粘贴亚利桑那节点的私钥>
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <主网卡名称> -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <主网卡名称> -j MASQUERADE

# 对等节点: 英国
[Peer]
PublicKey = <粘贴英国节点的公钥>
Endpoint = 104.128.190.41:51820
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

# 对等节点: 香港
[Peer]
PublicKey = <粘贴香港节点的公钥>
Endpoint = 27.106.126.139:51820
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25

英国节点 (10.0.0.2) 配置

bash
sudo vi /etc/wireguard/wg0.conf

配置内容:

ini
[Interface]
Address = 10.0.0.2/24
PrivateKey = <粘贴英国节点的私钥>
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <主网卡名称> -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <主网卡名称> -j MASQUERADE

# 对等节点: 亚利桑那
[Peer]
PublicKey = <粘贴亚利桑那节点的公钥>
Endpoint = 173.249.204.114:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25

# 对等节点: 香港
[Peer]
PublicKey = <粘贴香港节点的公钥>
Endpoint = 27.106.126.139:51820
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25

香港节点 (10.0.0.3) 配置

bash
sudo vi /etc/wireguard/wg0.conf

配置内容:

ini
[Interface]
Address = 10.0.0.3/24
PrivateKey = <粘贴香港节点的私钥>
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <主网卡名称> -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <主网卡名称> -j MASQUERADE

# 对等节点: 亚利桑那
[Peer]
PublicKey = <粘贴亚利桑那节点的公钥>
Endpoint = 173.249.204.114:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25

# 对等节点: 英国
[Peer]
PublicKey = <粘贴英国节点的公钥>
Endpoint = 104.128.190.41:51820
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

重要提示

  • <主网卡名称> 替换为步骤 2.3 检测到的实际网卡名称
  • 将所有 <粘贴xxx节点的私钥> 替换为步骤 2.1 生成的私钥内容
  • 将所有 <粘贴xxx节点的公钥> 替换为步骤 2.2 收集的公钥内容

2.5 启动和验证 WireGuard

在所有节点上执行以下操作:

bash
# 启动 WireGuard 接口
sudo wg-quick up wg0

# 设置开机自启
sudo systemctl enable wg-quick@wg0

# 检查接口状态
ip addr show wg0

# 查看连接状态
sudo wg

预期输出

  • ip addr show wg0 应显示配置的 WireGuard IP 地址
  • sudo wg 应显示所有对等节点的握手时间和数据传输量

2.6 网络连通性验证

在任意节点上测试与其他节点的连通性:

bash
# 在亚利桑那节点 (10.0.0.1) 上执行
ping -c 3 10.0.0.2  # 测试到英国节点
ping -c 3 10.0.0.3  # 测试到香港节点

所有节点应能够通过 WireGuard IP 互相 ping 通。


第三步:防火墙安全配置

基于最小权限原则设计防火墙规则,确保集群安全运行的同时仅开放必要端口。

3.1 防火墙规则设计

端口协议来源用途说明
10056TCP任意SSH 管理自定义 SSH 端口,避免默认端口扫描
51820UDP任意WireGuardVPN 隧道端口,必须对外开放
6443TCP负载均衡器Kubernetes APIAPI Server 访问端口
80,443TCP任意HTTP/HTTPSWeb 服务访问端口
10.0.0.0/24ALLWireGuard 子网集群内通信允许所有 Kubernetes 内部流量

规则设计原则

  • 默认拒绝所有入站流量
  • 显式允许必要的服务端口
  • WireGuard 子网内流量全部放行(已加密)
  • 限制 API Server 访问来源

3.2 防火墙配置脚本

创建 setup-firewall.sh 脚本:

bash
#!/bin/bash
# Kubernetes 集群防火墙配置脚本 v6.0 (基于 WireGuard 覆盖网络)

set -e

# --- 配置参数 ---
SSH_PORT="10056"
WIREGUARD_PORT="51820"
WIREGUARD_SUBNET="10.0.0.0/24"
LOAD_BALANCER_IP="159.138.44.125"
# --- 配置结束 ---

usage() {
    echo "用法: $0 <role>"
    echo "示例:"
    echo "  sudo $0 master       # 在 master 和 worker 节点上执行"
    echo "  sudo $0 loadbalancer # 在负载均衡器上执行"
    exit 1
}

if [[ $EUID -ne 0 ]]; then
    echo "❌ 错误: 此脚本必须以 root 权限运行。"
    exit 1
fi

if [ -z "$1" ]; then usage; fi

ROLE=$1

echo "🚀 开始为角色 [${ROLE}] 配置防火墙 (WireGuard 模式)..."

# 1. 基础设置
echo "📦 安装和配置 ufw..."
apt-get update >/dev/null && apt-get install -y ufw >/dev/null
ufw default deny incoming >/dev/null
ufw default allow outgoing >/dev/null

# 2. Kubernetes 网络转发策略
echo "🔧 配置 Kubernetes 网络转发策略..."
if grep -q 'DEFAULT_FORWARD_POLICY="DROP"' /etc/default/ufw; then
    sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
    echo "   -> FORWARD 策略已更新为 ACCEPT"
fi

# 3. SSH 访问
echo "🔑 允许 SSH 访问 (端口 ${SSH_PORT})..."
ufw allow ${SSH_PORT}/tcp comment 'Allow SSH access' >/dev/null

# 4. 角色特定规则
case ${ROLE} in
    master)
        echo "🎯 配置 Master/Worker 节点规则..."

        # 允许来自负载均衡器的 API 访问
        echo "   -> 允许负载均衡器 (${LOAD_BALANCER_IP}) 访问 API Server"
        ufw allow from ${LOAD_BALANCER_IP} to any port 6443 proto tcp comment 'Allow LB to reach API Server' >/dev/null

        # 允许 WireGuard 流量
        echo "   -> 允许 WireGuard 流量 (端口 ${WIREGUARD_PORT})"
        ufw allow ${WIREGUARD_PORT}/udp comment 'Allow WireGuard traffic' >/dev/null

        # 允许 WireGuard 子网内的所有流量
        echo "   -> 允许 WireGuard 子网内所有流量 (${WIREGUARD_SUBNET})"
        ufw allow from ${WIREGUARD_SUBNET} comment 'Allow all traffic from WireGuard peers' >/dev/null

        echo "   -> 允许 HTTP/HTTPS 流量"
        ufw allow 80,443/tcp comment 'Allow HTTP/HTTPS' >/dev/null
        ;;

    loadbalancer)
        echo "🎯 配置负载均衡器规则..."
        echo "   -> 允许外部访问 Kubernetes API Server (端口 6443)"
        ufw allow 6443/tcp comment 'Allow external access to K8s API Server' >/dev/null
        ;;

    *)
        echo "❌ 错误: 无效的角色 '${ROLE}'."
        usage
        ;;
esac

# 5. 激活防火墙并显示状态
echo "🔄 重新加载防火墙配置..."
ufw reload >/dev/null

if ! ufw status | grep -q "Status: active"; then
    echo "🔓 启用防火墙..."
    ufw --force enable >/dev/null
fi

echo ""
echo "✅ 防火墙配置完成!"
echo "📊 当前防火墙状态:"
echo "------------------------------------"
ufw status verbose
echo "------------------------------------"
echo ""

3.3 执行防火墙配置

bash
# 1. 保存脚本并赋予权限
chmod +x setup-firewall.sh

# 2. 在 Master 和 Worker 节点上执行
sudo ./setup-firewall.sh master

# 3. 在负载均衡器上执行(如有)
sudo ./setup-firewall.sh loadbalancer

验证防火墙配置

bash
sudo ufw status verbose

确认必要端口已开放,且默认策略为拒绝入站流量。


第四步:Kubernetes 环境准备

安装 Kubernetes 核心组件(kubeadm、kubelet、kubectl)和容器运行时(containerd)。

4.1 环境检查清单

在开始安装前,确认以下环境要求:

  • ✅ 操作系统:Debian 12 或 Ubuntu 20.04+
  • ✅ 内存:至少 2GB(推荐 4GB+)
  • ✅ CPU:至少 2 核心
  • ✅ 网络:WireGuard 网络互通
  • ✅ 权限:root 或 sudo 权限

4.2 节点环境准备脚本

创建 prepare-k8s-node.sh 脚本,在所有 Master 和 Worker 节点上执行:

bash
#!/bin/bash
# Kubernetes 节点环境准备脚本 v6.0

set -e

echo "🚀 开始准备 Kubernetes 节点环境..."

# 1. 系统配置
echo "⚙️ 配置系统参数..."

# 禁用 Swap (Kubernetes 要求关闭 Swap 以确保性能可预测)
echo "   -> 禁用 Swap"
swapoff -a
sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab

# 加载必要的内核模块
echo "   -> 配置内核模块"
tee /etc/modules-load.d/k8s.conf <<EOF >/dev/null
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

# 设置内核参数
echo "   -> 配置内核网络参数"
tee /etc/sysctl.d/k8s.conf <<EOF >/dev/null
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system >/dev/null

# 2. 安装容器运行时 (containerd)
echo "📦 安装容器运行时 containerd..."
apt-get update >/dev/null
apt-get install -y containerd >/dev/null

# 配置 containerd
echo "   -> 配置 containerd"
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml >/dev/null

# 启用 systemd cgroup 驱动 (与 kubelet 保持一致)
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 启动 containerd 服务
systemctl restart containerd
systemctl enable containerd

# 3. 安装 Kubernetes 组件
echo "📦 安装 Kubernetes 组件 (kubeadm, kubelet, kubectl)..."

# 安装必要工具
apt-get install -y apt-transport-https ca-certificates curl gpg >/dev/null

# 添加 Kubernetes 官方 GPG 密钥
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# 添加 Kubernetes 软件源
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list >/dev/null

# 更新软件包列表并安装 Kubernetes 组件
apt-get update >/dev/null
apt-get install -y kubelet kubeadm kubectl >/dev/null

# 锁定版本防止自动更新
apt-mark hold kubelet kubeadm kubectl >/dev/null

echo ""
echo "✅ 节点环境准备完成!"
echo ""
echo "📋 已安装组件版本:"
echo "- containerd: $(containerd --version | awk '{print $3}')"
echo "- kubeadm: $(kubeadm version -o short)"
echo "- kubelet: $(kubelet --version | awk '{print $2}')"
echo "- kubectl: $(kubectl version --client -o json | jq -r '.clientVersion.gitVersion')"
echo ""
echo "🔧 下一步:"
echo "- 如果这是第一个 Master 节点,请运行 Master 初始化脚本"
echo "- 如果这是其他节点,请等待 Master 初始化完成后运行相应的加入脚本"

执行环境准备:

bash
chmod +x prepare-k8s-node.sh
sudo ./prepare-k8s-node.sh

关键配置说明

  1. 禁用 Swap:Kubernetes 要求关闭 Swap 以确保 Pod 的资源限制生效
  2. 内核模块
    • overlay:OverlayFS 文件系统,容器镜像分层存储所需
    • br_netfilter:网桥过滤,支持 iptables 处理桥接流量
  3. 内核参数
    • net.ipv4.ip_forward:启用 IP 转发,Pod 跨节点通信的基础
    • net.bridge.bridge-nf-call-iptables:桥接流量经过 iptables 处理
  4. Systemd Cgroup:确保 containerd 和 kubelet 使用相同的 Cgroup 驱动,避免资源管理冲突

第五步:Master 节点初始化

在第一个 Master 节点(亚利桑那节点)上执行集群初始化。

5.1 初始化配置说明

初始化时使用 WireGuard IP (10.0.0.1) 作为 advertiseAddress,确保所有集群内部通信走加密隧道。

关键配置参数

  • advertiseAddress:本节点 API Server 通告的地址(使用 WireGuard IP)
  • controlPlaneEndpoint:集群控制平面的统一入口(负载均衡器域名)
  • podSubnet:Pod 网络 CIDR 范围(需与 Calico 配置一致)
  • serviceSubnet:Service 网络 CIDR 范围
  • certSANs:API Server 证书的备用名称(包含所有可能的访问地址)

5.2 Master 初始化脚本

创建 init-master1.sh 脚本:

bash
#!/bin/bash
# Master1 节点初始化脚本 v6.1 (WireGuard 基础集群)

set -e

echo "🚀 开始初始化第一个 Master 节点 (WireGuard 模式)..."

# 集群配置参数 - 使用 WireGuard IP 作为 advertiseAddress
MASTER1_IP="10.0.0.1"  # WireGuard IP
LB_DOMAIN="apiserver.k8s.at9.net"
POD_SUBNET="192.168.0.0/16"
SERVICE_SUBNET="10.96.0.0/12"
K8S_VERSION="v1.33.1"

echo "📋 集群初始化配置:"
echo "- Master1 IP: ${MASTER1_IP}"
echo "- 负载均衡器域名: ${LB_DOMAIN}"
echo "- Pod 网络段: ${POD_SUBNET}"
echo "- Service 网络段: ${SERVICE_SUBNET}"
echo "- Kubernetes 版本: ${K8S_VERSION}"
echo ""

# 1. 创建 kubeadm 配置文件 (使用 v1beta4 API 版本)
echo "📝 创建 kubeadm 配置文件..."
tee kubeadm-config.yaml <<EOF >/dev/null
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: ${MASTER1_IP}
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock

---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: ${K8S_VERSION}
controlPlaneEndpoint: "${LB_DOMAIN}:6443"
networking:
  podSubnet: ${POD_SUBNET}
  serviceSubnet: ${SERVICE_SUBNET}
etcd:
  local:
    dataDir: /var/lib/etcd
apiServer:
  extraArgs:
    - name: audit-log-path
      value: "/var/log/kubernetes/audit.log"
    - name: audit-log-maxage
      value: "30"
    - name: audit-log-maxbackup
      value: "3"
    - name: audit-log-maxsize
      value: "100"
  certSANs:
    - "${LB_DOMAIN}"
    - "10.0.0.1"
    - "10.0.0.2"
    - "173.249.204.114"
    - "104.128.190.41"

---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
failSwapOn: false

---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "iptables"
EOF

echo "✅ kubeadm 配置文件创建完成"

# 2. 预拉取镜像 (可选,但推荐)
echo "📥 预拉取 Kubernetes 组件镜像..."
kubeadm config images pull --config kubeadm-config.yaml

# 3. 执行集群初始化
echo "🎯 执行 Kubernetes 集群初始化..."
echo "⏳ 这个过程可能需要几分钟,请耐心等待..."
kubeadm init --config=kubeadm-config.yaml --upload-certs

# 4. 配置 kubectl 访问权限
echo "⚙️ 配置 kubectl 访问权限..."
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 5. 验证初始化结果
echo "🔍 验证集群初始化状态..."
sleep 5
kubectl get nodes
kubectl get pods -n kube-system

# 6. 生成其他节点的加入命令
echo ""
echo "🔑 生成节点加入信息..."

# 生成 Master 节点加入命令
echo ""
echo "==================== Master & Worker 加入命令 (请复制保存) ===================="
echo "📋 以下信息用于其他 Master 节点加入集群:"
echo ""

JOIN_COMMAND=$(kubeadm token create --print-join-command 2>/dev/null)
CERTIFICATE_KEY=$(kubeadm init phase upload-certs --upload-certs 2>/dev/null | tail -n 1)

echo "--- Master 节点加入命令 (使用 WireGuard IP) ---"
echo "${JOIN_COMMAND} \\"
echo "    --control-plane \\"
echo "    --certificate-key ${CERTIFICATE_KEY} \\"
echo "    --apiserver-advertise-address=10.0.0.2 \\"
echo "    --ignore-preflight-errors=NumCPU"

echo ""
echo "--- Worker 节点加入命令 ---"
echo "${JOIN_COMMAND}"

echo ""
echo "📝 说明:"
echo "- 请在 Master2 节点上执行上述完整命令"
echo "- 请在所有 Worker 节点上执行 Worker 加入命令"
echo "- 证书密钥有效期为 2 小时"
echo "- 令牌有效期为 24 小时"

echo "=========================================================================="
echo ""

# 7. 显示后续操作提示
echo "✅ Master1 节点初始化完成!"
echo ""
echo "🔧 后续操作步骤:"
echo "1. 安装 CNI 网络插件 (按教程步骤进行)"
echo "2. 在其他 Master 节点上执行上面的 Master 加入命令"
echo "3. 在 Worker 节点上执行上面的 Worker 加入命令"
echo "4. 通过 ArgoCD 部署 Gateway API + Istio"
echo "5. 验证集群状态和网络连通性"
echo ""
echo "💡 重要提示:"
echo "- 如果令牌过期,可使用 'kubeadm token create --print-join-command' 重新生成"
echo "- 如果证书密钥过期,可使用 'kubeadm init phase upload-certs --upload-certs' 重新生成"
echo "- 网络组件将由 ArgoCD 管理,避免 GitOps 闭环问题"

# 8. 清理临时文件
rm -f kubeadm-config.yaml

echo ""
echo "🎉 基础集群初始化完成!接下来按教程步骤安装网络插件。"

执行初始化:

bash
chmod +x init-master1.sh
sudo ./init-master1.sh

重要提示

  • 请务必保存脚本输出的加入命令,后续步骤需要使用
  • 如果执行失败,可使用 kubeadm reset 清理后重新执行
  • 初始化完成后,集群还不能正常工作,需要安装 CNI 网络插件

第六步:其他节点加入集群

使用步骤 5 中生成的加入命令,在对应节点上执行。

6.1 Master2 节点加入

在英国节点 (10.0.0.2) 上执行包含 --control-plane 参数的 Master 加入命令:

bash
kubeadm join apiserver.k8s.at9.net:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --control-plane \
    --certificate-key <certificate-key> \
    --apiserver-advertise-address=10.0.0.2 \
    --ignore-preflight-errors=NumCPU

参数说明

  • --control-plane:表明加入的是控制平面节点
  • --certificate-key:用于下载加密的证书文件
  • --apiserver-advertise-address:本节点 API Server 通告地址(使用 WireGuard IP)
  • --ignore-preflight-errors=NumCPU:忽略 CPU 核心数检查(低配置服务器可选)

加入成功后,配置 kubectl:

bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

6.2 Worker 节点加入

在香港节点 (10.0.0.3) 或其他 Worker 节点上执行 Worker 加入命令:

bash
kubeadm join apiserver.k8s.at9.net:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

6.3 验证节点加入

在任意 Master 节点上执行:

bash
kubectl get nodes

预期结果:应显示所有节点,状态为 NotReady(因为尚未安装 CNI 网络插件)。

注意事项

  • 确保所有节点的 WireGuard 网络已正常运行
  • 加入前验证与 Master1 节点的网络连通性
  • 证书密钥有效期 2 小时,令牌有效期 24 小时,过期需重新生成

第七步:Calico 网络插件安装

Calico 为 Pod 提供网络连接和网络隔离,配置使用 WireGuard 接口确保所有 Pod 间通信走加密隧道。

7.1 网络组件说明

组件版本作用配置要点
Calicov3.30.1Pod 网络使用 wg0 接口
Pod CIDR192.168.0.0/16Pod IP 范围不与现有网络冲突
IPIP 模式启用跨节点通信适合跨地域部署

网络模式说明

  • IPIP 模式:在 IP 数据包外再封装一层 IP 头,适合跨子网通信
  • wg0 接口:强制 Calico 使用 WireGuard 接口,确保 Pod 流量走加密隧道

7.2 Calico 安装脚本

创建 install-calico.sh 脚本:

bash
#!/bin/bash
# Calico v3.30.1 网络插件安装脚本 v6.0 (WireGuard 模式)

set -e

echo "🕸️ 开始安装并配置 Calico for WireGuard..."

CALICO_VERSION="v3.30.1"

# 1. 检查集群状态
echo "🔍 检查集群状态..."
if ! kubectl get nodes >/dev/null 2>&1; then
    echo "❌ 错误: 无法连接到 Kubernetes 集群"
    echo "请确保:"
    echo "- Master 节点已正确初始化"
    echo "- kubectl 配置正确"
    echo "- API Server 正在运行"
    exit 1
fi

echo "当前集群节点:"
kubectl get nodes -o wide

# 2. 下载 Calico 清单
echo "📥 下载 Calico 清单文件..."
curl https://raw.githubusercontent.com/projectcalico/calico/v3.30.1/manifests/calico.yaml -O

# 3. 优化 CPU 请求(针对低配置服务器)
echo "⚙️ 优化 Calico 资源配置..."
sed -i 's/cpu: 250m/cpu: 100m/g' calico.yaml

# 4. 应用配置
echo "🚀 部署 Calico 到集群..."
kubectl apply -f calico.yaml

echo "⏳ 等待 Pod 创建..."
sleep 15

# 5. (关键) 修改 Calico 以使用 wg0 接口
echo "🔧 修改 Calico DaemonSet 以使用 'wg0' 接口..."
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=wg0

echo "✅ Calico 配置完成!正在滚动更新 Pods..."
echo "⏳ 请在新终端中手动观察 \`kubectl get pods -n kube-system -w\` 直至所有 calico-node Pods 变为 Ready(1/1)"

# 6. 等待 Calico 组件启动
echo ""
echo "⏳ 等待 Calico 组件启动..."
echo "这个过程可能需要几分钟,请耐心等待..."

# 等待 calico-node DaemonSet 就绪
echo ""
echo "📊 监控 Calico Node DaemonSet 启动进度..."
for i in {1..30}; do
    NODES_READY=$(kubectl get daemonset calico-node -n kube-system -o jsonpath='{.status.numberReady}' 2>/dev/null || echo "0")
    NODES_DESIRED=$(kubectl get daemonset calico-node -n kube-system -o jsonpath='{.status.desiredNumberScheduled}' 2>/dev/null || echo "1")

    if [ "$NODES_READY" = "$NODES_DESIRED" ] && [ "$NODES_READY" != "0" ]; then
        echo "✅ Calico Node DaemonSet 启动完成 ($NODES_READY/$NODES_DESIRED)"
        break
    fi

    echo "   进度: $NODES_READY/$NODES_DESIRED 节点就绪 (尝试 $i/30)"
    sleep 10
done

# 等待 calico-kube-controllers 启动
echo ""
echo "📊 监控 Calico Controllers 启动进度..."
for i in {1..20}; do
    if kubectl wait --for=condition=Ready pod -l k8s-app=calico-kube-controllers -n kube-system --timeout=30s >/dev/null 2>&1; then
        echo "✅ Calico Controllers 启动完成"
        break
    fi
    echo "   等待 Calico Controllers 就绪... (尝试 $i/20)"
    sleep 15
done

# 7. 验证网络插件状态
echo ""
echo "🔍 验证 Calico 网络插件状态..."

echo ""
echo "=== Calico 组件状态 ==="
kubectl get pods -n kube-system -l k8s-app=calico-node -o wide
echo ""
kubectl get pods -n kube-system -l k8s-app=calico-kube-controllers -o wide

echo ""
echo "=== 集群节点状态 ==="
kubectl get nodes -o wide

echo ""
echo "=== CoreDNS 状态 ==="
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide

# 8. 测试网络连通性
echo ""
echo "🧪 测试集群网络连通性..."
kubectl run test-calico --image=busybox --rm -i --restart=Never --timeout=60s --command -- /bin/sh -c "
echo '🌐 网络连通性测试:'
echo '1. 测试 DNS 解析:'
nslookup kubernetes.default.svc.cluster.local
echo ''
echo '2. 测试外网连通性:'
ping -c 3 8.8.8.8
echo ''
echo '✅ 网络测试完成!'
" 2>/dev/null || echo "⚠️ 网络测试跳过 (这是正常的,可能因为网络策略限制)"

# 9. 显示安装结果摘要
echo ""
echo "📋 Calico 安装状态摘要"
echo "=========================================="
echo "Calico 版本: ${CALICO_VERSION}"
echo "Pod 网络段: 192.168.0.0/16"
echo "安装模式: IPIP 模式"

# 统计就绪状态
READY_NODES=$(kubectl get nodes --no-headers 2>/dev/null | grep -c Ready || echo "0")
TOTAL_NODES=$(kubectl get nodes --no-headers 2>/dev/null | wc -l || echo "0")
echo "就绪节点: ${READY_NODES}/${TOTAL_NODES}"

CALICO_PODS=$(kubectl get pods -n kube-system -l k8s-app=calico-node --no-headers 2>/dev/null | wc -l || echo "0")
CALICO_READY=$(kubectl get pods -n kube-system -l k8s-app=calico-node --no-headers 2>/dev/null | grep -c Running || echo "0")
echo "Calico Node: ${CALICO_READY}/${CALICO_PODS} Running"

CONTROLLER_READY=$(kubectl get pods -n kube-system -l k8s-app=calico-kube-controllers --no-headers 2>/dev/null | grep -c Running || echo "0")
echo "Calico Controller: ${CONTROLLER_READY}/1 Running"

echo "=========================================="

# 10. 清理临时文件
rm -f calico.yaml

# 11. 最终状态判断和建议
echo ""
if [ "$READY_NODES" -eq "$TOTAL_NODES" ] && [ "$CALICO_READY" -gt 0 ] && [ "$CONTROLLER_READY" -eq 1 ]; then
    echo "✅ Calico 网络插件安装成功!"
    echo ""
    echo "🔧 下一步操作:"
    echo "1. 等待所有系统组件完全启动"
    echo "2. 部署测试应用验证网络功能"
    echo "3. 安装 Traefik 入口控制器"
    echo "4. 配置 ArgoCD GitOps 自动化部署"
else
    echo "⚠️ Calico 安装可能存在问题,请检查:"
    echo "- 检查组件日志: kubectl logs -n kube-system -l k8s-app=calico-node"
    echo "- 检查节点状态: kubectl describe nodes"
    echo "- 检查防火墙配置是否正确"
fi

echo ""
echo "🎉 Calico 网络插件安装脚本执行完成!"

执行 Calico 安装:

bash
chmod +x install-calico.sh
sudo ./install-calico.sh

关键步骤说明

  1. 下载官方 Manifest:确保使用官方维护的稳定版本
  2. 优化资源请求:降低 CPU 请求以适配低配置服务器
  3. 配置 wg0 接口:强制 Calico 使用 WireGuard 接口,确保流量走加密隧道
  4. 滚动更新:修改配置后自动触发 Pod 重启

第八步:Traefik 入口控制器部署

Traefik 作为集群流量入口,提供 HTTP/HTTPS 负载均衡和反向代理功能。

8.1 Traefik 部署概述

部署目标

  • 在自建 Kubernetes 集群上部署高可用 Traefik Ingress 控制器
  • 将服务稳定暴露到公网 IP 地址
  • 提供自动服务发现和负载均衡功能
  • 支持后续的 HTTPS 证书自动管理

技术架构

Internet → [Public IPs] → Traefik LoadBalancer → Kubernetes Services → Pods

8.2 环境准备和前置条件

环境要求检查清单

  • ✅ Kubernetes 集群正常运行(已完成步骤 1-7)
  • ✅ Calico 网络插件正常工作
  • ✅ kubectl 已配置并可管理集群
  • ✅ 具备集群管理员权限
  • ✅ 公网 IP 地址已准备(本例:173.249.204.114, 104.128.190.41)

安装 Helm 包管理器

bash
#!/bin/bash
# Helm 安装脚本

echo "📦 安装 Helm 包管理器..."

bash <(curl -s -L https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3)

# 验证安装
helm version

echo "✅ Helm 安装完成"

8.3 Traefik 核心部署流程

创建 deploy-traefik.sh 部署脚本:

bash
#!/bin/bash
# Traefik 入口控制器部署脚本 v6.0 (裸金属集群)

set -e

echo "🚀 开始部署 Traefik 入口控制器..."

# 配置参数
NAMESPACE="traefik"
RELEASE_NAME="traefik"
PUBLIC_IPS=("173.249.204.114" "104.128.190.41")  # 替换为实际的公网IP

# 1. 环境检查
echo "🔍 检查集群环境..."
if ! kubectl cluster-info >/dev/null 2>&1; then
    echo "❌ 错误: 无法连接到 Kubernetes 集群"
    exit 1
fi

echo "当前集群节点状态:"
kubectl get nodes -o wide

# 2. 添加 Traefik Helm 仓库
echo "📦 配置 Traefik Helm 仓库..."
helm repo add traefik https://traefik.github.io/charts
helm repo update

echo "✅ Helm 仓库配置完成"

# 3. 创建命名空间
echo "📁 创建 ${NAMESPACE} 命名空间..."
kubectl create namespace ${NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -

# 4. 创建 Traefik 配置文件
echo "📝 生成 Traefik 配置..."
cat > traefik-values.yaml <<EOF
# Traefik v3 配置文件 - 裸金属集群优化版

# 全局配置
globalArguments:
  - "--global.checknewversion=false"
  - "--global.sendanonymoususage=false"

# 部署配置
deployment:
  enabled: true
  replicas: 2
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - traefik
        topologyKey: kubernetes.io/hostname

# 资源配置
resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

# 服务配置 - 关键:LoadBalancer 模式
service:
  enabled: true
  type: LoadBalancer
  annotations: {}
  labels: {}
  spec:
    externalTrafficPolicy: Local  # 保持源IP
  loadBalancerSourceRanges: []

# 端口配置
ports:
  web:
    port: 8000
    expose: true
    exposedPort: 80
    protocol: TCP
  websecure:
    port: 8443
    expose: true
    exposedPort: 443
    protocol: TCP
    tls:
      enabled: true
  traefik:
    port: 9000
    expose: false  # 安全考虑,不对外暴露管理端口
    protocol: TCP

# Ingress 配置
providers:
  kubernetesingress:
    enabled: true
    allowExternalNameServices: true
    publishedservice:
      enabled: true
      pathOverride: "${NAMESPACE}/${RELEASE_NAME}"

# 日志配置
logs:
  general:
    level: INFO
  access:
    enabled: true
    format: json

# 健康检查
ping:
  enabled: true

# 指标配置
metrics:
  prometheus:
    enabled: true
    addEntryPointsLabels: true
    addServicesLabels: true

# 安全配置
securityContext:
  capabilities:
    drop: [ALL]
  readOnlyRootFilesystem: true
  runAsGroup: 65532
  runAsNonRoot: true
  runAsUser: 65532

podSecurityContext:
  fsGroup: 65532
EOF

echo "✅ 配置文件生成完成"

# 5. 使用 Helm 部署 Traefik
echo "🚀 部署 Traefik 到集群..."
helm install ${RELEASE_NAME} traefik/traefik \
  --namespace ${NAMESPACE} \
  --values traefik-values.yaml \
  --wait --timeout=300s

echo "⏳ 等待 Traefik Pod 启动..."
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=traefik -n ${NAMESPACE} --timeout=300s

# 6. 为 LoadBalancer 服务注入公网 IP
echo "🔧 配置公网 IP 地址..."

# 构建 IP 列表
IP_LIST=""
for ip in "${PUBLIC_IPS[@]}"; do
    if [ -z "$IP_LIST" ]; then
        IP_LIST="{\"ip\": \"$ip\"}"
    else
        IP_LIST="$IP_LIST, {\"ip\": \"$ip\"}"
    fi
done

# 应用 IP 补丁
kubectl patch svc ${RELEASE_NAME} -n ${NAMESPACE} --subresource=status -p \
"{\"status\":{\"loadBalancer\":{\"ingress\":[$IP_LIST]}}}"

echo "✅ 公网 IP 配置完成"

# 7. 触发配置更新以感知 IP 变化
echo "🔄 更新 Traefik 配置..."
helm upgrade ${RELEASE_NAME} traefik/traefik \
  --namespace ${NAMESPACE} \
  --values traefik-values.yaml \
  --reuse-values

echo "⏳ 等待配置更新完成..."
sleep 30

# 8. 验证部署状态
echo ""
echo "🔍 验证 Traefik 部署状态..."

echo "=== Traefik Pod 状态 ==="
kubectl get pods -n ${NAMESPACE} -o wide

echo ""
echo "=== Traefik Service 状态 ==="
kubectl get svc -n ${NAMESPACE} -o wide

echo ""
echo "=== LoadBalancer 外部 IP ==="
EXTERNAL_IPS=$(kubectl get svc ${RELEASE_NAME} -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
if [ -n "$EXTERNAL_IPS" ]; then
    echo "✅ 外部 IP: $EXTERNAL_IPS"
else
    echo "⚠️ 外部 IP 尚未分配,请稍后再次检查"
fi

# 9. 测试 Traefik 可访问性
echo ""
echo "🧪 测试 Traefik 访问性..."
for ip in "${PUBLIC_IPS[@]}"; do
    echo "测试 IP: $ip"
    if curl -s --connect-timeout 5 -o /dev/null -w "%{http_code}" "http://$ip/" | grep -q "404"; then
        echo "  ✅ HTTP 访问正常 (404 表示 Traefik 正在运行但无路由)"
    else
        echo "  ⚠️ HTTP 访问异常,请检查防火墙和网络配置"
    fi
done

# 10. 显示后续操作建议
echo ""
echo "📋 Traefik 部署状态摘要"
echo "======================================"
echo "命名空间: ${NAMESPACE}"
echo "发行版名称: ${RELEASE_NAME}"
echo "副本数量: 2 (高可用)"
echo "外部 IP: ${PUBLIC_IPS[*]}"
echo "HTTP 端口: 80"
echo "HTTPS 端口: 443"
echo "======================================"

echo ""
echo "🔧 后续操作建议:"
echo "1. 创建测试 Ingress 验证功能"
echo "2. 配置域名 DNS 解析指向外部 IP"
echo "3. 部署应用并创建对应的 Ingress 资源"
echo "4. 可选:配置 cert-manager 实现 HTTPS 自动证书管理"

echo ""
echo "🔍 故障排查命令:"
echo "- 查看 Pod 日志: kubectl logs -n ${NAMESPACE} -l app.kubernetes.io/name=traefik"
echo "- 查看服务状态: kubectl describe svc ${RELEASE_NAME} -n ${NAMESPACE}"
echo "- 查看 Ingress 状态: kubectl get ingress -A"

# 11. 清理临时文件
rm -f traefik-values.yaml

echo ""
echo "✅ Traefik 入口控制器部署完成!"

8.4 执行 Traefik 部署

bash
# 1. 创建并执行部署脚本
chmod +x deploy-traefik.sh

# 2. 执行部署 (注意替换脚本中的公网IP)
sudo ./deploy-traefik.sh

8.5 部署验证和测试

创建测试应用验证 Traefik 功能:

yaml
# test-traefik.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 50m
            memory: 64Mi
          limits:
            cpu: 100m
            memory: 128Mi

---
apiVersion: v1
kind: Service
metadata:
  name: test-app-service
  namespace: default
spec:
  selector:
    app: test-app
  ports:
  - port: 80
    targetPort: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-app-ingress
  namespace: default
spec:
  ingressClassName: traefik
  rules:
  - host: test.at9.net  # 替换为实际域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: test-app-service
            port:
              number: 80

应用测试配置:

bash
kubectl apply -f test-traefik.yaml

# 验证部署状态
kubectl get pods,svc,ingress

部署完成检查清单

  • ✅ Traefik Pod 运行正常 (Ready 状态)
  • ✅ LoadBalancer Service 获得外部 IP
  • ✅ 通过外部 IP 可访问 Traefik (返回 404 正常)
  • ✅ 测试 Ingress 创建和访问正常
  • ✅ 日志无明显错误信息

第九步:ArgoCD GitOps 配置

将所有 Kubernetes 资源交由 ArgoCD 管理,实现完整 GitOps 自动化部署。

9.1 安装 ArgoCD

bash
# 创建专属命名空间
kubectl create namespace argocd

# 应用官方 Manifest
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

9.2 获取初始登录密码

bash
# 获取 ArgoCD 初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

9.3 配置 Ingress 访问

创建 argocd-ingress.yaml 文件:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
spec:
  ingressClassName: traefik
  rules:
  - host: argocd.at9.net  # 替换为实际域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 80

应用 Ingress:

bash
kubectl apply -f argocd-ingress.yaml

9.4 配置 ArgoCD 信任上游代理

由于 TLS 终止在 Traefik 层,需要配置 ArgoCD 信任上游代理:

bash
kubectl patch configmap argocd-cmd-params-cm -n argocd --type merge -p '{"data":{"server.insecure":"true"}}'

重启服务使配置生效:

bash
kubectl rollout restart deployment/argocd-server -n argocd

9.5 配置 Git 仓库连接

生成 SSH 部署密钥

bash
ssh-keygen -t rsa -b 4096 -f ./argocd-deploy-key

添加 Deploy Key 到 Git 仓库

  1. 将公钥(.pub 文件内容)添加到目标仓库的 Settings > Security > Deploy keys
  2. 不要勾选 Allow write access(只读权限即可)

在 ArgoCD UI 中注册仓库

  1. 访问 ArgoCD Web 界面(通过配置的域名)
  2. 使用 admin 和获取的密码登录
  3. 导航至 Settings > Repositories
  4. 点击 CONNECT REPO USING SSH
  5. 选择 VIA SSH
  6. 填写表单:
    • Repository URLgit@github.com:htazq/k8s.git(必须为 SSH 格式)
    • SSH Private Key:粘贴私钥文件全部内容
  7. 点击 CONNECT,确认仓库状态显示 ✅ Successful

9.6 创建根应用 (App of Apps)

在 ArgoCD UI 中创建第一个应用,配置如下:

yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  source:
    path: argocd
    repoURL: git@github.com:htazq/k8s.git
    targetRevision: main
    directory:
      recurse: true
  sources: []
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
    - PruneLast=true
    retry:
      limit: 2
      backoff:
        duration: 5s
        maxDuration: 3m0s
        factor: 2

配置说明

  • automated.prune:自动删除不在 Git 中的资源
  • automated.selfHeal:自动修复与 Git 不一致的资源
  • syncOptions.CreateNamespace:自动创建命名空间
  • retry:同步失败时的重试策略

总结

至此,一个基于 WireGuard 覆盖网络的跨地域 Kubernetes 高可用集群已部署完成,具备以下特性:

  • 跨地域高可用:Master 节点分布在不同大洲,任意地域故障不影响集群运行
  • 网络安全:所有节点间通信通过 WireGuard 加密隧道,保障数据传输安全
  • 完整的网络方案:Calico CNI + Traefik Ingress,支持 Pod 网络和外部访问
  • GitOps 自动化:ArgoCD 管理所有应用生命周期,实现声明式部署和自动同步
  • 生产就绪:完整的监控、日志、安全配置

后续可根据业务需求通过 ArgoCD 部署服务网格(Istio)、监控系统(Prometheus)、日志聚合(EFK Stack)等组件。

用心记录,持续学习 | CNB