Deploy loxilb-igw¶
Run the gateway as a DaemonSet on the control-plane node, check that the build carries the EPP client, and make its rules survive a restart.
Before you start¶
Pods and EPP from Model Servers & Endpoint Picker are Ready. The gateway node's IP is the VIP, 192.0.2.10 here.
Focus of this page: features must contain epp, and /etc/loxilb must be a host mount.
Topology and execution locations¶
flowchart TD
C["Client<br/>sends to VIP:8080"] --> G["loxilb-igw on the control-plane node<br/>rule: mode 4, eppEndpoint"]
G -->|"ext_proc gRPC :9002<br/>one question per request"| E["Endpoint Picker<br/>Deployment + ClusterIP Service"]
E -.->|"watches"| P["InferencePool<br/>selector → model-server pods"]
E -->|"answers with one pod address"| G
G -->|"forwards to the pod the EPP named, :8000"| V["vLLM pods<br/>one per GPU node"]
O["Operator shell"] -.->|"REST :11111, kubectl, pod :8000/metrics"| G
style G fill:#e1f5fe,stroke:#0288d1,color:#1f2937
style E fill:#fff8e1,stroke:#f9a825,color:#1f2937
style V fill:#e8f5e9,stroke:#43a047,color:#1f2937
| Where | What happens here |
|---|---|
| Operator shell (the control-plane node in this guide) | kubectl, curl against the gateway's REST API on :11111, the harness, pod :8000/metrics reads |
| Client | sends OpenAI-style requests to the gateway VIP, 192.0.2.10:8080 |
| loxilb-igw (DaemonSet, hostNetwork on the control-plane node) | holds the rule, asks the EPP per request, forwards to the pod it names |
| Endpoint Picker (Deployment + ClusterIP Service) | watches the InferencePool, keeps the prefix-cache index, answers over ext_proc gRPC :9002 |
| vLLM pods (one per GPU node) | serve the model on :8000; their metrics are the independent attribution of which pod served a request |
Walkthrough¶
40-loxilb-igw.yaml is a DaemonSet in kube-system pinned to control-plane nodes by node affinity, with hostNetwork: true, privileged: true, the REST API on :11111, and /etc/loxilb mounted from the host at /opt/loxilb/config. Three things to check in it before applying:
- Image.
ghcr.io/loxilb-io/loxilb-inference-gateway:latest, or a release tag. The L4-onlyghcr.io/loxilb-io/loxilbimage does not carry the EPP client. --blacklist. The regular expression names the interfaces the gateway must not attach its eBPF programs to: the CNI's veths and tunnels. The shipped value covers Calico and Flannel. For another CNI, add its interface prefixes.- Node placement. The node affinity selects nodes labelled
node-role.kubernetes.io/control-plane. To run the gateway elsewhere, change the affinity to a label of your own and add the matching toleration.
kubectl apply -f "$MF/40-loxilb-igw.yaml"
kubectl -n kube-system rollout status ds/loxilb-lb
curl -s http://192.0.2.10:11111/netlox/v1/version
{"buildInfo":"...","features":["...","epp","..."],"product":"loxilb-inference-gateway","version":"..."}
features lists what this build carries. The list differs from release to release and usually has several entries; the check is that epp is among them, which is what lets the binary hold an eppEndpoint rule. A build without it accepts the field and ignores it.
curl -s http://192.0.2.10:11111/netlox/v1/version | python3 -c 'import json,sys; f=json.load(sys.stdin)["features"]; print("epp" if "epp" in f else "NO epp", f)'
The /etc/loxilb mount is what makes rules survive a pod restart: every committed change is written to /etc/loxilb/snapshot.json and restored at boot. Without the mount a restart (image change, node reboot, eviction) comes up with no rules. See Configuration persistence & snapshots.
Check your result¶
GET /netlox/v1/version answers with product loxilb-inference-gateway and epp in features; kubectl -n kube-system rollout status ds/loxilb-lb is complete.
Next steps and cleanup¶
Continue with Create the EPP Rule. Restarting the gateway pod reloads eBPF programs on the node's interfaces; see Troubleshooting before doing that on a node that carries other traffic.