网络 (networking)

networking 类承载集群所有进出流量的基础设施:内部由 MetalLB 分配 LoadBalancer IP、Traefik 做七层 ingress 路由;控制面 API 由 kube-vip 暴露在固定 VIP;公网流量则经两条 Cloudflare Tunnel 进入,域名记录由 External-DNS 自动维护。这些组件一旦异常,外部访问会整体不可达,属于集群的关键路径。

流量路径

集群内的入站流量遵循固定链路:MetalLB(L2 模式)为 LoadBalancer 类型的 Service 从地址池分配一个局域网 VIP,并通过 ARP 在节点上应答;Traefik 的 Service 拿到其中的 192.168.88.221,作为唯一 ingress 入口,按 Host 头把请求路由到各服务的 Ingress。所以链路是 MetalLB(L2 LB IP)到 Traefik(ingress)再到后端服务。

控制面是另一条独立链路:kube-vip 以 ARP 模式在三个 master 上选主并持有 API VIP 192.168.88.99:6443,kubectl 和集群组件都连这个地址而非某个具体 master 的 IP。

公网方向不走 NodePort 或对外暴露 LB IP,而是由 Cloudflare Tunnel 主动外连建立隧道:公网请求经 Cloudflare 边缘 进入 cloudflared,再转发到集群内的 Traefik(http://traefik.kube-system.svc.cluster.local:80),复用同一套 ingress 路由。

组件清单

  • Name
    metallb
    Description
    L2 模式负载均衡器,metallb-system namespace。controller Deployment(quay.io/metallb/controller:v0.16.1,钉在 workload=infra)分配 LB IP,speaker DaemonSet(quay.io/metallb/speaker:v0.16.1)在每个节点做 ARP 应答。带 cert-manager 自签证书的 validating webhook。深度说明见 MetalLB 深度页
  • Name
    traefik
    Description
    k3s 内置 ingress controller,kube-system namespace,通过 helmchartconfig-traefik.yaml(HelmChartConfig)覆盖 k3s 默认值:强制 service.ipFamilyPolicy: SingleStack(否则 PreferDualStack 让 MetalLB 无法分配 IPv4 VIP),并把副本限定在 worker 节点、按 hostname 软打散一节点一副本。
  • Name
    kube-vip
    Description
    kube-system 里的 DaemonSet(ghcr.io/kube-vip/kube-vip:v1.2.0),仅调度到 control-plane 节点,hostNetwork: true。ARP 模式(vip_arp=true)配合 leader election 持有控制面 VIP 192.168.88.99,端口 6443,svc_enable=false(不接管 Service LB,那是 MetalLB 的活)。Prometheus 指标在 :2112
  • Name
    cloudflare-tunnel
    Description
    account-A 隧道(tunnel id 79da7b14),cloudflare-tunnel namespace,cloudflared Deployment 3 副本、hostNetwork、metrics 在 :2000。路由 k3s-api.yldm.tech*.yldm.tech*.yldm.aidunaifen.games 及其子域到 Traefik 或 API。凭据走 ExternalSecret tunnel-credentials
  • Name
    cloudflare-tunnel-yldm
    Description
    account-B(Evan@yldm.tech 账号)隧道(tunnel id 2b822c22),cloudflare-tunnel-yldm namespace,cloudflared 2 副本、metrics 在 :2001(与 A 隧道错开 host 端口以便同节点共存)。额外路由 pve.yldm.tech(Proxmox Web UI 192.168.88.68:8006)、*.fluxa.cashkamify.store 及其子域。dunaifen.games 仍留在 A 隧道。
  • Name
    external-dns
    Description
    external-dns namespace,单副本 Deployment(registry.k8s.io/external-dns/external-dns:v0.21.0workload=infra),监听 --source=ingress--source=service 自动写 Cloudflare DNS。domain-filter 限 yldm.tech / yldm.ai / dunaifen.games,并用 zone-id-filter 锁定 live zone(同名 zone 在新旧两个账号都存在,不锁会写到失效的旧 zone)。Cloudflare API token 来自 ExternalSecret cloudflare-api-token(Vault external-dns/cloudflare)。

LoadBalancer IP 池

MetalLB 的 default-pool 自动分配 192.168.88.220-192.168.88.230autoAssign: true),由 L2Advertisement 在二层广播。当前在用的几个 LB IP:

IP用途
192.168.88.220gitea-ssh
192.168.88.221Traefik ingress
192.168.88.222游戏服务器

公网入口与 DNS

公网域名解析到 Cloudflare,由 Cloudflare Tunnel 把流量送进集群,而不暴露家宽公网 IP。两条隧道按 Cloudflare 账号 / zone 归属拆分:yldm.tech / yldm.ai / fluxa.cash / kamify.store 走 account-B 的 cloudflare-tunnel-yldmdunaifen.games(DNF 私服门户)仍走 account-A 的 cloudflare-tunnel

cloudflared 的隧道配置只在启动时读取、无热重载,所以两个 Deployment 都带 reloader.stakater.com/auto: "true" 注解,让 ConfigMap 或凭据变更时自动滚动重启(否则改了 ConfigMap 也不生效)。每个 Pod 都有 wait-for-ingress initContainer,先等 Traefik 的 DNS 可解析再启动。

DNS 记录由 External-DNS 维护:它读取集群里 Ingress 和带 external-dns.alpha.kubernetes.io/* 注解的 Service,按需在 Cloudflare 创建/更新记录。例如 kube-vip 旁的 k3s-api ExternalName Service 就靠这套注解把 k3s-api.yldm.tech 指向隧道的 cfargotunnel.com 目标并开启 Cloudflare 代理。

整体流量入口在 集群架构 也有图示,控制面 VIP 与节点调度见 节点与调度

评论