网络 (networking)
networking 类承载集群所有进出流量的基础设施:内部由 MetalLB 分配 LoadBalancer IP、Traefik 做七层 ingress 路由;控制面 API 由 kube-vip 暴露在固定 VIP;公网流量则经两条 Cloudflare Tunnel 进入,域名记录由 External-DNS 自动维护。这些组件一旦异常,外部访问会整体不可达,属于集群的关键路径。
applications/networking/<service>/,其中 kube-vip 与 traefik 实际部署在 kube-system namespace、metallb 在 metallb-system,cloudflare-tunnel 与 external-dns 各有自己的 namespace。流量路径
集群内的入站流量遵循固定链路: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-systemnamespace。controllerDeployment(quay.io/metallb/controller:v0.16.1,钉在workload=infra)分配 LB IP,speakerDaemonSet(quay.io/metallb/speaker:v0.16.1)在每个节点做 ARP 应答。带 cert-manager 自签证书的 validating webhook。深度说明见 MetalLB 深度页。
- Name
- traefik
- Description
- k3s 内置 ingress controller,
kube-systemnamespace,通过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 持有控制面 VIP192.168.88.99,端口 6443,svc_enable=false(不接管 Service LB,那是 MetalLB 的活)。Prometheus 指标在:2112。
- Name
- cloudflare-tunnel
- Description
- account-A 隧道(tunnel id
79da7b14),cloudflare-tunnelnamespace,cloudflaredDeployment 3 副本、hostNetwork、metrics 在:2000。路由k3s-api.yldm.tech、*.yldm.tech、*.yldm.ai、dunaifen.games及其子域到 Traefik 或 API。凭据走 ExternalSecrettunnel-credentials。
- Name
- cloudflare-tunnel-yldm
- Description
- account-B(Evan@yldm.tech 账号)隧道(tunnel id
2b822c22),cloudflare-tunnel-yldmnamespace,cloudflared2 副本、metrics 在:2001(与 A 隧道错开 host 端口以便同节点共存)。额外路由pve.yldm.tech(Proxmox Web UI192.168.88.68:8006)、*.fluxa.cash、kamify.store及其子域。dunaifen.games仍留在 A 隧道。
- Name
- external-dns
- Description
external-dnsnamespace,单副本 Deployment(registry.k8s.io/external-dns/external-dns:v0.21.0,workload=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 来自 ExternalSecretcloudflare-api-token(Vaultexternal-dns/cloudflare)。
LoadBalancer IP 池
MetalLB 的 default-pool 自动分配 192.168.88.220-192.168.88.230(autoAssign: true),由 L2Advertisement 在二层广播。当前在用的几个 LB IP:
| IP | 用途 |
|---|---|
| 192.168.88.220 | gitea-ssh |
| 192.168.88.221 | Traefik ingress |
| 192.168.88.222 | 游戏服务器 |
公网入口与 DNS
公网域名解析到 Cloudflare,由 Cloudflare Tunnel 把流量送进集群,而不暴露家宽公网 IP。两条隧道按 Cloudflare 账号 / zone 归属拆分:yldm.tech / yldm.ai / fluxa.cash / kamify.store 走 account-B 的 cloudflare-tunnel-yldm,dunaifen.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 代理。