上一篇 下一篇 分享链接 返回 返回顶部

SaaS创业团队如何在香港服务器的 Ubuntu 环境中搭建 Kubernetes 集群,并快速实现全球化部署(高阶、实操、带坑位复盘)

发布人:Minchunlin 发布时间:2025-09-14 11:04 阅读量:1097


凌晨 2:40,我和同事阿康在香港将军澳机房对着一排裸露着热插拔托架的 1U 服务器,最后一次确认 BMC 网络、光口链路聚合和 PDU 的冗余。我们这套面向全球的首个生产级 K8s 集群,要在天亮前可用:首批用户在欧洲和东南亚。

我们的目标很清晰:用香港本地高带宽低时延的优势做全球流量的“第一落点”和“智能分发”,配合 Cloudflare 的边缘网络,把 SaaS 的多区域访问体验做对——先快,再稳,再省。下面是我完整的落地过程、参数、脚本、踩坑与复盘。

1. 适用读者与产出物

适用对象:SaaS 初创团队 CTO / 架构师 / SRE / 高阶运维工程师,也照顾新手按步骤操作。

交付结果:一套在香港机房(Ubuntu 22.04/24.04 LTS)落地的高可用 Kubernetes集群,具备:

  • 双活 API 高可用(HAProxy + Keepalived VIP)
  • Cilium CNI( eBPF、可选加密、NetworkPolicy)
  • MetalLB(L2 模式出公网/机房内网负载)
  • Longhorn 分布式块存储(NVMe)
  • Ingress-NGINX + Cloudflare(WAF/CDN/SSL/TLS)
  • cert-manager + ExternalDNS(自动证书与域名)
  • Harbor 私有镜像仓库 + GitHub Actions CI/CD
  • 监控日志链路:kube-prometheus-stack + Loki
  • 备份与容灾:Velero + S3 兼容对象存储(Cloudflare R2/MinIO)
  • 可扩展到多区域的 DNS 智能流量调度

2. 目标架构(文字拓扑)

[Internet Users]
      |
   Cloudflare (Proxy, WAF, CDN, LB, Geo)
      |
  ┌───────────────香港 IDC───────────────┐
  |  VIP(10.0.10.10):6443  <Keepalived+HAProxy>  |
  |      |            \                        |
  |   CP1|CP2|CP3   Workers x N             Storage x M(Longhorn)
  |      |                                     |
  |   Cilium CNI + MetalLB + Ingress-NGINX + cert-manager + ExternalDNS
  |              |                   \
  |            Apps/NS              Harbor/Monitoring/Velero ...
  └──────────────────────────────────────────────────────────────┘
                   |
               R2/MinIO/S3(备份/镜像副本)

3. 资源、版本与参数清单(实配示例)

3.1 服务器规格(样例)

角色 数量 CPU 内存 系统盘 数据盘 网卡 备注
控制面 CP 3 AMD EPYC 7443P(24C) 128GB 2×480GB SSD RAID1 2×10GbE(LACP) 机柜双上联
工作节点 6 AMD EPYC 7313P(16C) 128GB 2×480GB SSD RAID1 2×3.84TB NVMe(Longhorn复用一块) 2×10GbE 根据业务横向扩容
存储节点 3 AMD EPYC 7302P(16C) 128GB 2×480GB SSD RAID1 4×3.84TB NVMe 2×10GbE Longhorn 3 副本策略
  • 操作系统:Ubuntu Server 22.04/24.04 LTS(最小化安装)
  • 时钟同步:chrony(对接机房 NTP)
  • K8s:kubeadm v1.29/1.30(本文以 v1.29.x 为例)
  • 运行时:containerd 1.7+
  • CNI:Cilium 1.15+(eBPF)
  • Ingress:ingress-nginx 1.11+
  • 存储:Longhorn 1.6+
  • 证书:cert-manager 1.14+
  • 监控:kube-prometheus-stack 60.x+
  • 备份:Velero 1.13+

3.2 网络与 IP 规划(示例)

网络 网段 用途
管理网 MGMT 10.0.0.0/24 BMC、SSH、Ansible
业务网 PROD 10.0.10.0/24 节点互联、Pod/Service 出口
存储网 STORAGE 10.0.20.0/24 Longhorn 数据复制(独立物理口/VLAN)
Kubernetes VIP 10.0.10.10 kube-apiserver 虚拟地址(HA)
MetalLB 池 10.0.10.200-10.0.10.250 暴露 LoadBalancer 类型服务

4. 机房基线与 Ubuntu 初始化

4.1 BIOS/BMC/固件与链路

  • 开启 SR-IOV/VT-d/IOMMU,关闭 C-States 过深省电,性能更稳。
  • 固件统一到同一大版本,网卡驱动与固件匹配(Mellanox/Intel)。
  • 业务网与存储网分物理口/VLAN,ToR 交换机做 LACP(802.3ad)。

4.2 Ubuntu 基线脚本(所有节点执行)

# 01-base.sh
set -eux

sudo apt update
sudo apt -y upgrade

# 基础工具
sudo apt -y install htop iotop iftop nvme-cli jq gnupg2 apt-transport-https \
  curl ca-certificates software-properties-common git chrony

# 时钟同步
sudo timedatectl set-timezone Asia/Hong_Kong
sudo sed -i 's/^pool .*/server ntp.hk.example iburst/' /etc/chrony/chrony.conf
sudo systemctl enable --now chrony

# 关闭 swap
sudo swapoff -a
sudo sed -ri 's/^(.*swap.*)$/#\1/g' /etc/fstab

# 内核参数
cat <<'EOF' | sudo tee /etc/sysctl.d/99-k8s.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
vm.swappiness=0
fs.inotify.max_user_watches=524288
fs.inotify.max_user_instances=1024
net.netfilter.nf_conntrack_max=2621440
EOF
sudo modprobe br_netfilter
sudo sysctl --system

# iptables 切回 legacy(避免某些扩展与 nft 冲突)
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy || true
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true

# 禁用 UFW(后续由 Cilium/NetworkPolicy 控制)
sudo systemctl disable --now ufw || true

4.3 containerd 安装与配置

# 02-containerd.sh
set -eux
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
 https://download.docker.com/linux/ubuntu $(. /etc/os-release; echo $UBUNTU_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt -y install containerd.io

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl enable --now containerd

4.4 安装 kubeadm/kubelet/kubectl(锁版本)

# 03-k8s.sh
set -eux
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-1-29.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-1-29.gpg] \
 https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | \
  sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null

sudo apt update
sudo apt -y install kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

5. 控制面高可用:Keepalived + HAProxy

5.1 HAProxy(CP1/CP2/CP3 都装)

sudo apt -y install keepalived haproxy

# /etc/haproxy/haproxy.cfg 关键段
cat <<'EOF' | sudo tee /etc/haproxy/haproxy.cfg
global
  maxconn 100000
  log /dev/log local0

defaults
  mode tcp
  timeout connect 5s
  timeout client  1m
  timeout server  1m

frontend k8s_api
  bind 10.0.10.10:6443
  default_backend k8s_masters

backend k8s_masters
  balance roundrobin
  option tcp-check
  server cp1 10.0.10.11:6443 check fall 3 rise 2
  server cp2 10.0.10.12:6443 check fall 3 rise 2
  server cp3 10.0.10.13:6443 check fall 3 rise 2
EOF

sudo systemctl enable --now haproxy

5.2 Keepalived(使用单播避免 VRRP 组播与机房网络策略冲突)

# /etc/keepalived/keepalived.conf
cat <<'EOF' | sudo tee /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
  state BACKUP
  interface bond0
  virtual_router_id 51
  priority 100
  advert_int 1
  unicast_src_ip 10.0.10.X      # 当前节点IP
  unicast_peer {
    10.0.10.11
    10.0.10.12
    10.0.10.13
  }
  authentication {
    auth_type PASS
    auth_pass k8sVIPpass
  }
  virtual_ipaddress {
    10.0.10.10/24 dev bond0
  }
  track_script {
    chk_haproxy
  }
}

vrrp_script chk_haproxy {
  script "pidof haproxy"
  interval 2
  weight 20
}
EOF

sudo systemctl enable --now keepalived

现场坑 1:某些机房对 VRRP 组播有限制,直接漂 VIP 会失败。用 unicast 模式规避;同时把 virtual_router_id 固定,所有节点一致。

6. kubeadm 初始化与加入

6.1 kubeadm 配置(CP1 上生成并分发)

cat <<'EOF' > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.0.10.11
  bindPort: 6443
nodeRegistration:
  criSocket: "unix:///run/containerd/containerd.sock"

---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: "v1.29.6"
controlPlaneEndpoint: "10.0.10.10:6443"
networking:
  podSubnet: "10.244.0.0/16"   # cilium 会接管
  serviceSubnet: "10.96.0.0/12"
apiServer:
  extraArgs:
    audit-log-maxage: "7"
    audit-log-maxsize: "100"
    audit-log-maxbackup: "10"
controllerManager: {}
scheduler: {}
etcd:
  local:
    dataDir: /var/lib/etcd
EOF

6.2 初始化控制面(CP1)

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

6.3 其余控制面加入(CP2/CP3)

在 CP1 获取 kubeadm join ... --control-plane 命令并在 CP2/CP3 执行(包含 --certificate-key)。

6.4 工作节点加入

在每个 Worker 节点执行 kubeadm join ...(包含 token、discovery-token-ca-cert-hash)。

7. 安装 Cilium(CNI)

# 安装 helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

helm repo add cilium https://helm.cilium.io/
helm repo update

# 可根据 MTU 与机房网络调整 tunneling/encryption
helm install cilium cilium/cilium \
  --version 1.15.5 \
  --namespace kube-system \
  --set kubeProxyReplacement=strict \
  --set k8sServiceHost=10.0.10.10 \
  --set k8sServicePort=6443 \
  --set ipam.mode=kubernetes

现场坑 2(MTU):机房骨干 + Cloudflare + eBPF overlay 时可能出现 Path MTU 降低导致的断续丢包。务必核对 ToR 与上联 MTU,必要时在 Cilium 设置 --set global.mtu=XXXX 并与网卡/交换机一致。

8. MetalLB(L2 模式)

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

cat <<'EOF' | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 10.0.10.200-10.0.10.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metallb-system
spec: {}
EOF

9. Longhorn 分布式存储(NVMe)

helm repo add longhorn https://charts.longhorn.io
helm repo update
kubectl create ns longhorn-system
helm install longhorn longhorn/longhorn -n longhorn-system --version 1.6.1 \
  --set persistence.defaultClassReplicaCount=3 \
  --set defaultSettings.defaultDataPath="/var/lib/longhorn"

现场坑 3:Longhorn 需要独立磁盘或分区。别把系统盘拿来玩;确保存储网有足够带宽(我们放在 10GbE 独立网)。

10. Ingress-NGINX + Cloudflare 适配(Real IP/Proxy Protocol)

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
kubectl create ns ingress-nginx

helm install ingress ingress-nginx/ingress-nginx -n ingress-nginx \
  --set controller.service.type=LoadBalancer \
  --set controller.service.annotations."metallb\.universe\.tf/allow-shared-ip"="ingress" \
  --set controller.config.use-proxy-protocol="true" \
  --set controller.config.real-ip-header="proxy_protocol" \
  --set controller.config.set-real-ip-from="0.0.0.0/0"

现场坑 4:Cloudflare 代理后端时,如果开启 Proxy Protocol,请同时在 Cloudflare LB/Listener 侧开启;否则 NGINX 解析不到真实源 IP。若不使用 Proxy Protocol,可改走 X-Forwarded-For 并维护 Cloudflare IP 段白名单。

11. cert-manager 与 Cloudflare DNS 自动化

helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl create ns cert-manager
helm install cert-manager jetstack/cert-manager -n cert-manager \
  --set crds.enabled=true

# Cloudflare API Token Secret
kubectl -n cert-manager create secret generic cloudflare-api-token-secret \
  --from-literal=api-token='<CF_API_TOKEN>'

# ClusterIssuer(DNS01 验证)
cat <<'EOF' | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dns01
spec:
  acme:
    email: ops@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: acme-account-key
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token-secret
            key: api-token
EOF

12. ExternalDNS(自动创建/更新 DNS 记录)

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update
kubectl create ns external-dns
kubectl -n external-dns create secret generic cloudflare-api-token-secret \
  --from-literal=api-token='<CF_API_TOKEN>'

helm install external-dns external-dns/external-dns -n external-dns \
  --set provider=cloudflare \
  --set env[0].name=CLOUDFLARE_API_TOKEN \
  --set env[0].valueFrom.secretKeyRef.name=cloudflare-api-token-secret \
  --set env[0].valueFrom.secretKeyRef.key=api-token \
  --set domainFilters[0]=example.com \
  --set policy=sync \
  --set txtOwnerId=hk-cluster

13. Harbor 私有镜像仓库(可选)

helm repo add harbor https://helm.goharbor.io
helm repo update
kubectl create ns harbor
helm install harbor harbor/harbor -n harbor \
  --set externalURL=https://harbor.example.com \
  --set expose.type=ingress \
  --set expose.tls.enabled=true \
  --set expose.ingress.className=nginx \
  --set expose.ingress.hosts.core=harbor.example.com \
  --set harborAdminPassword='StrongP@ssw0rd!'

通过 Ingress + cert-manager 自动签发 TLS;镜像推送走 Cloudflare 直连或灰度关闭代理(避免大体积镜像被缓存/限速)。

14. CI/CD:GitHub Actions → Harbor → K8s

.github/workflows/deploy.yml(示例)

name: build-and-deploy
on:
  push:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: harbor.example.com
          username: ${{ secrets.HARBOR_USER }}
          password: ${{ secrets.HARBOR_PASS }}
      - name: Build
        run: |
          docker buildx build --platform linux/amd64 \
            -t harbor.example.com/saas/app:${{ github.sha }} \
            -t harbor.example.com/saas/app:latest \
            --push .
      - name: Kubeconfig
        run: |
          mkdir -p $HOME/.kube
          echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config
      - name: Deploy
        run: |
          sed -i "s#IMAGE_TAG#${{ github.sha }}#g" k8s/deploy.yaml
          kubectl apply -f k8s/namespace.yaml
          kubectl apply -f k8s/deploy.yaml

k8s/deploy.yaml(关键段)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: saas
spec:
  replicas: 4
  selector:
    matchLabels: { app: app }
  template:
    metadata:
      labels: { app: app }
    spec:
      containers:
      - name: app
        image: harbor.example.com/saas/app:IMAGE_TAG
        ports:
        - containerPort: 8080
        resources:
          requests: { cpu: "200m", memory: "256Mi" }
          limits: { cpu: "1", memory: "1Gi" }
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
  namespace: saas
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

15. 监控与日志

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

# kube-prometheus-stack
kubectl create ns monitoring
helm install monitor prometheus-community/kube-prometheus-stack -n monitoring

# Loki + promtail(可选)
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki -n monitoring --set singleBinary=true
helm install promtail grafana/promtail -n monitoring \
  --set "config.clients[0].url=http://loki.monitoring.svc:3100/loki/api/v1/push"

16. 备份与灾备(Velero + R2/MinIO)

# 以 Cloudflare R2 为例(S3 兼容)
export VELERO_ACCESS_KEY_ID=AKIAxxxx
export VELERO_SECRET_ACCESS_KEY=xxxx

velero install \
  --provider aws \
  --plugins velero/velero-plugin-for-aws:v1.8.2 \
  --bucket saas-backup \
  --secret-file ./credentials-velero \
  --backup-location-config s3Url=https://<accountid>.r2.cloudflarestorage.com,region=auto \
  --use-node-agent

策略:每天全量命名空间级备份,关键数据(数据库 PVC)每 6 小时增量,保留 7-14 天;演练跨集群恢复到备用环境(如新加坡/东京)。

17. 安全与治理(建议基线)

  • NetworkPolicy:默认拒绝、按 NS/标签白名单互通(Cilium 原生支持)。
  • 镜像来源白名单:限制为 harbor.example.com 与受信任公共仓库。
  • Admission:Kyverno/Gatekeeper 校验镜像签名、资源限额、禁止特权容器。
  • 密钥管理:Sealed Secrets 或 External Secrets(对接 Vault/ASM)。
  • 审计:apiserver 审计日志 → Loki/对象存储长期保存。

18. 对外发布样例(自动证书 + 自动 DNS)

ingress.yaml(示例,自动颁发 TLS 和 A 记录)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app
  namespace: saas
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-dns01"
    external-dns.alpha.kubernetes.io/hostname: "app.example.com"
spec:
  ingressClassName: nginx
  tls:
  - hosts: [ "app.example.com" ]
    secretName: app-tls
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port: { number: 8080 }
---
apiVersion: v1
kind: Service
metadata:
  name: app-svc
  namespace: saas
spec:
  type: LoadBalancer
  selector: { app: app }
  ports:
  - port: 8080
    targetPort: 8080

ExternalDNS 会写入 app.example.com 到 Cloudflare;cert-manager 通过 DNS01 完成证书签发并维护续期。

19. 全球化部署策略(从香港出发)

第一阶段(香港单区 + 边缘加速)

  • 所有入口走 Cloudflare 代理(缓存静态、Argo 智能路由可选)。
  • 香港集群提供统一 Ingress 出口,MetalLB 分配公网/IDC 地址。
  • 用户就近接入 Cloudflare Anycast,回源到香港。

第二阶段(多区域集群)

  • 在 新加坡/东京/法兰克福 复制同构集群(同样的 Helm 基线)。
  • 使用 Cloudflare Load Balancer + Geo-Steering/Session Affinity,按地理/健康度分配到最近活跃区域。
  • 镜像仓库多区域副本(Harbor + registry 镜像复制;或用公共仓库 + 策略镜像)

数据层根据业务特点选择:

  • 读多写少:各区读本地、写异步到主(例如只在 HK 写主库)
  • 强一致:引入多主/共识(TiDB/CockroachDB/Etcd-Sharded),网络与延迟成本需评估
  • 灾备:Velero 定期把关键命名空间同步备份到所有区域对象存储。

示例延迟(实测参考值,非官方):

地区 直连香港(ms) 走 Cloudflare 回源(ms) 体验
新加坡 35-45 30-40 边缘就近 + 智能路由更稳
东京 45-60 40-55 峰值抖动下降
法兰克福 180-220 160-200 首屏提升 10-20%
洛杉矶 120-150 100-130 峰值拥塞更可控

20. 端口与防火墙白名单(节选)

方向 协议/端口 说明
外网→Ingress TCP/80,443 业务入口
节点间 TCP/2379-2380 etcd
节点间 TCP/10250 kubelet
Pod 网络 多端口 Cilium eBPF/隧道
监控 TCP/9090,3000 Prometheus/Grafana
存储 TCP/9500, 10000-32767 Longhorn 数据/引擎

21. 常见坑位与现场处置

VRRP 组播被机房屏蔽

现象:VIP 不漂移或漂移不稳定

处理:Keepalived 改 unicast,ToR 明确允许该流量,优先独占 VLAN。

MTU 不一致导致连接间歇失败

现象:服务偶发 502/超时、只在部分客户端出现

处理:统一主机、交换机、CNI MTU;Cilium 指定 --set global.mtu=9000/1500 与实际一致。

iptables nft 与 legacy 混乱

现象:部分规则失效、NodePort 不通

处理:按上文切回 legacy(或全栈 nft,但组件要匹配);重启 kubelet 与网络栈。

Cloudflare 代理 + Proxy Protocol 配置不一致

现象:后端拿不到真实 IP、日志全是代理节点

处理:两端一致开启/关闭;或使用 X-Forwarded-For 并维护可信名单。

Longhorn 磁盘误用系统盘

现象:I/O 抖动、系统盘被打满

处理:严格用独立 NVMe;设置磁盘调度 none(NVMe),NUMA 亲和优化。

证书签发速率限制

现象:频繁改域名触发 Let’s Encrypt 速率限制

处理:灰度用 Staging CA;外域名统一走子域与 wildcard。

镜像下载瓶颈

现象:首发时很多节点拉镜像慢

处理:Harbor 开启本地缓存、启用分层复用,机房内部署 registry mirror。

22. 性能与容量基线(我们线上达标参考)

指标 目标线 备注
P99 首字节延迟(亚洲用户) ≤ 300ms Cloudflare 边缘 + 香港回源
单集群 QPS 50k+ 视业务类型不同
部署耗时(CI→上线) ≤ 5 分钟 镜像构建 + 部署滚更
Pod 启动到就绪 ≤ 15 秒 预拉镜像 + Readiness 探针
备份恢复 RTO ≤ 30 分钟 Velero 命名空间级恢复
存储 IOPS(随机读 4k) ≥ 200k/节点 NVMe + Longhorn 三副本

23. 完整“首个业务”上线清单(随手卡)

  •  节点基线 + 审计
  •  kubeadm 初始化 + 加入
  •  Cilium/MetalLB/Ingress 安装
  •  cert-manager/ExternalDNS/Cloudflare 接通
  •  Longhorn 卷就绪 + 读写压力测试
  •  Harbor/CI/CD 通路打通(灰度环境)
  •  监控告警完善,Grafana 看板固定
  •  Velero 全量备份完成一次并演练恢复
  •  WAF/速率限制/限流(Nginx 或 Cloudflare)
  •  HPA 压测与回滚演练

早上 6:10,监控大屏上全是绿勾。第一批欧洲用户打点上报稳定,Cloudflare 边缘命中率爬升到 80% 左右。我们把最后一口冷咖啡倒掉,走出机房时将军澳天边已经泛白。

做全球化,并不一定非要一上来就多区域多活。从香港出发,把一套稳扎稳打、可复制的 Kubernetes 基线打好,配合边缘网络与自动化,把速度、稳定与成本三角平衡出来——这就是我们真实经历过的路线图。

希望这篇“带温度”的教程,能让你在凌晨值守时少踩几个坑,也能更从容地迎接清晨那束“绿灯”。

附录:一键检测脚本(节选)

#!/usr/bin/env bash
# quick-healthcheck.sh
set -e

echo "[*] Node summary"
kubectl get node -o wide

echo "[*] Core addons"
kubectl -n kube-system get ds,deploy | egrep "cilium|coredns|metrics"

echo "[*] Ingress & LB"
kubectl -n ingress-nginx get svc,deploy
kubectl -n metallb-system get ipaddresspools,l2advertisements

echo "[*] Storage"
kubectl -n longhorn-system get po,svc
kubectl get sc,pv,pvc

echo "[*] Certs & DNS"
kubectl -n cert-manager get clusterissuer
kubectl -n external-dns get deploy

echo "[*] Monitoring"
kubectl -n monitoring get po,svc | egrep "prometheus|grafana|alertmanager"

echo "[*] Velero"
kubectl -n velero get po,backup,backupstoragelocations
目录结构
全文