节点与调度

yldm 是一个 K3s HA 集群(v1.33.5+k3s1),由 3 个 master + 4 个 worker 共 7 台虚拟机组成,分布在 4 台 Proxmox VE 主机上。物理层之上的 VM 拓扑由 pve-infra 用 Terraform 管理;本页讲的是 K3s 这一层的节点角色和工作负载怎么落到哪个节点上。

节点拓扑

4 台 PVE 主机各承载若干 K3s 节点,外加 Synology NAS 上以 Docker 运行的 corosync-qnetd 提供 PVE 集群第 5 票仲裁(ffsplit 算法),合计 5 票,可容忍任意 2 节点同时离线。下表是 7 个 K3s 节点的分布、配置与标签。

主机名IP宿主 PVE配置 (核/内存/盘)角色节点标签
k8s-master1192.168.88.101PVE1 (N100)2c / 6GB / 100GBControl Planeworkload=system
k8s-master2192.168.88.102PVE2 (N100)2c / 6GB / 100GBControl Planeworkload=system
k8s-master3192.168.88.103PVE3 (i9-12900H)2c / 6GB / 100GBControl Planeworkload=system
k8s-worker1192.168.88.111PVE1 (N100)4c / 20GB / 100GBCI/CD Workerworkload=cicd
k8s-worker2192.168.88.112PVE2 (N100)4c / 20GB / 300GBApp Workerworkload=app
k8s-worker3192.168.88.113PVE3 (i9-12900H)12c / 48GB / 500GBDatabase + Infra Workernode-role=database, workload=infra
k8s-worker4192.168.88.114PVE4 (N100)4c / 8GB / 100GBApp Workerworkload=app

控制平面是 master1/2/3 三节点(etcd 3 成员)。worker3 是配置最高的节点(12c/48GB/500GB),独占数据库层与基础设施层两类职责。PVE4 与 NAS QDevice 是 2026-06 新增;同期旧的 pve3 infra 节点合并进 worker3 后销毁,新的 worker4(app)落在 pve4 上。集群物理资源合计约 32 线程 / 144GB 内存。

workload 调度键

workload 是主要调度键,单值,取值固定为以下五种之一:

  • Name
    system
    Description
    三个 master 节点,承载 K3s 控制面(etcd / API server)。
  • Name
    cicd
    Description
    worker1,专跑 GitHub Actions Runner(ARC v2,scale-set yldm-backend-runners,2-12 副本)。
  • Name
    app
    Description
    worker2 + worker4 两节点,承载 app 与 platform 命名空间的业务微服务。
  • Name
    database
    Description
    worker3,由 node-role=database 标记,仅数据库层 StatefulSet 使用(PV 钉在本节点本地盘)。
  • Name
    infra
    Description
    worker3,由 workload=infra 标记,承载全部基础设施组件。

k3s 内置组件的调度定制方式不一:traefik 走 Git 管理的 applications/networking/traefik/helmchartconfig-traefik.yaml(worker 间软打散,HPA 2-5 副本);coredns / metrics-server 则是集群内直接 patch 成 workload: infra,k3s 重启可能回到默认值,属已知事项。

worker3 双职责

worker3 同时打了 node-role=databaseworkload=infra 两个标签,因此一个节点承担两类职责:

  • 数据库层(local-path,PV 钉本节点):PostgreSQL 主从、Redis、MongoDB、RabbitMQ、Meilisearch ×2、MinIO(800GB)、NATS、Consul、Tempo。
  • 基础设施层workload=infra,可调度):GitOps(ArgoCD 全家桶)、监控日志(Prometheus / Grafana / Loki / Alertmanager / kube-state-metrics)、网络(MetalLB controller / Cloudflare Tunnel / External-DNS / Cert-Manager)、安全(Vault / External-Secrets / Dex OIDC / Kyverno)、备份(Velero)。

因为有状态数据库的 PV 通过 local-path 钉死在 worker3 本地盘,这些 StatefulSet 无法漂移到其他节点 —— worker3 是集群的单点,宕机处置另见运维手册。数据层细节参见 集群架构 - 数据层

app 层双节点

worker2 与 worker4 都打 workload=app,构成应用层的双节点:

  • app 命名空间:magicbox、aidict、creativestore、kubepocket、myetc、kamify 等。
  • platform 命名空间:analytics、auth、commerce、engagement、gateway、management、media、notification、scheduler、social、user。

多副本服务通过反亲和分布在这两个节点上,单节点故障不再让某服务全部副本一起挂掉。这是 2026-06 加入 worker4(pve4)后才有的能力 —— 在此之前 app 层只有 worker2 单节点。

反亲和与 PDB 规则

两条调度硬约定,新增或修改服务时必须遵守:

  • Name
    多副本 — podAntiAffinity
    Description
    多副本服务必须配 podAntiAffinity,并带上 matchLabelKeys: pod-template-hash,避免滚动更新时新副本被旧副本挤到同一节点,保证副本真正打散在 worker2 / worker4 上。
  • Name
    单副本 — PDB maxUnavailable: 1
    Description
    单副本服务的 PodDisruptionBudget 一律用 maxUnavailable: 1。不要用 minAvailable: 1 —— 那会让节点 drain 永久卡死(PR #895)。

评论