如何使用Traefik负载均衡多主节点Kubernetes API Server?
Great question—yes, you absolutely can use Traefik to load-balance your 3-node kube-apiserver HA setup, and you have flexible options depending on whether you need to handle internal cluster traffic, external client traffic, or both. Let’s break this down step by step to clear up your confusion:
Core Answer
You don’t have to run Traefik outside your cluster—running it internally works perfectly for distributing API requests across your 3 control plane nodes. External deployment is only necessary if you need to expose the apiserver to clients outside the cluster and prefer not to use a NodePort/LoadBalancer service for Traefik.
Option 1: Run Traefik Inside the Cluster (Best for Internal Traffic)
This setup is ideal for routing traffic from cluster components (kubelets, kube-proxy, pods) to your apiservers. We’ll use Traefik as a DaemonSet (so every node has a local Traefik instance) and configure it to forward requests to your 3 control plane nodes.
Step 1: Deploy Traefik in the Cluster
First, deploy Traefik with appropriate permissions (a ClusterRole that lets it access endpoints, nodes, and other K8s resources). Use a DaemonSet for maximum availability and low latency (local node traffic doesn’t need to cross the cluster network).
Step 2: Define Your Apiserver Endpoints
Since your control plane nodes aren’t typically labeled for K8s service selectors, create a manual Endpoints resource to point to your 3 apiserver IPs:
apiVersion: v1 kind: Endpoints metadata: name: kube-apiserver-ha namespace: kube-system subsets: - addresses: - ip: 192.168.1.100 # Replace with your control plane node 1 IP - ip: 192.168.1.101 # Replace with your control plane node 2 IP - ip: 192.168.1.102 # Replace with your control plane node 3 IP ports: - port: 6443 name: https
Then create a corresponding ClusterIP Service to abstract these endpoints:
apiVersion: v1 kind: Service metadata: name: kube-apiserver-ha namespace: kube-system spec: ports: - port: 6443 targetPort: 6443 protocol: TCP name: https type: ClusterIP
Step 3: Configure Traefik to Route to the Apiserver Service
Use Traefik’s custom IngressRoute resource (for v2+) to route traffic to your apiserver service. Make sure to handle TLS correctly—you can either let Traefik terminate TLS (using the apiserver’s certificate) or use passthrough mode (Traefik forwards traffic without touching TLS, letting clients validate the apiserver’s cert directly).
Here’s an example with TLS passthrough (simpler for apiserver traffic):
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: kube-apiserver-ingressroute namespace: kube-system spec: entryPoints: - websecure # Ensure Traefik is configured to listen on this entry point (port 6443) routes: - match: Host(`kube-apiserver.cluster.local`) # Use a custom internal domain kind: Rule services: - name: kube-apiserver-ha port: 6443 tls: passthrough: true # Critical—lets the client and apiserver handle TLS directly
Step 4: Update Cluster Component Configs
Update your kubeconfig files, kubelet configs, and other cluster components to point to Traefik’s service address (e.g., https://kube-apiserver-ha.kube-system.svc.cluster.local:6443) instead of individual apiserver IPs. All requests will now be load-balanced across your 3 control plane nodes.
Option 2: Run Traefik Outside the Cluster (For External Clients)
If you need external users (developers with kubectl, CI/CD tools) to access your apiserver, you can run Traefik on a dedicated external node (or nodes) to forward traffic to your control plane.
Step 1: Install Traefik on an External Node
Run Traefik as a Docker container or systemd service. For example, with Docker:
docker run -d \ --name traefik-apiserver-lb \ -p 6443:6443 \ -v $PWD/traefik.yml:/etc/traefik/traefik.yml \ -v $PWD/dynamic.yml:/etc/traefik/dynamic.yml \ traefik:v2.10
Step 2: Configure Traefik Static Settings (traefik.yml)
Set up the entry point for 6443 and enable file-based dynamic configuration:
entryPoints: websecure: address: ":6443" providers: file: filename: /etc/traefik/dynamic.yml
Step 3: Configure Dynamic Routing (dynamic.yml)
Define a router that forwards traffic to your 3 control plane nodes:
http: routers: kube-apiserver-router: entryPoints: - websecure rule: "Host(`your-cluster-api.example.com`)" # External domain for your apiserver service: kube-apiserver-service tls: passthrough: true # Again, let client and apiserver handle TLS services: kube-apiserver-service: loadBalancer: servers: - url: "https://192.168.1.100:6443" - url: "https://192.168.1.101:6443" - url: "https://192.168.1.102:6443"
Step 4: Update External Kubeconfigs
Have external users update their kubeconfig files to point to the external Traefik node’s IP/domain (e.g., https://your-cluster-api.example.com:6443).
Key Notes to Avoid Pitfalls
- TLS Trust: Ensure clients (internal components or external users) trust the apiserver’s certificate. If using TLS passthrough, they’ll need the apiserver CA cert in their trust store.
- Traefik HA: For internal deployment, DaemonSet ensures Traefik runs on every node—no single point of failure. For external deployment, run multiple Traefik nodes and use a hardware LB to load-balance between them.
- Performance: Internal Traefik deployment has lower latency since traffic stays within the cluster. External deployment is only needed if you can’t expose Traefik via a LoadBalancer/NodePort service.
内容的提问来源于stack exchange,提问作者jesusofsuburbia

