Host-Reachable Services

This guide explains how to configure Cilium to enable services to be reached from the host namespace in addition to pod namespaces.

Note

Host-reachable services for TCP and UDP requires a v4.19.57, v5.1.16, v5.2.0 or more recent Linux kernel. Note that v5.0.y kernels do not have the fix required to run host-reachable services with UDP since at this point in time the v5.0.y stable kernel is end-of-life (EOL) and not maintained anymore. For only enabling TCP-based host-reachable services a v4.17.0 or newer kernel is required. The most optimal kernel with the full feature set is v5.8.

Note

Make sure you have Helm 3 installed. Helm 2 is no longer supported.

Setup Helm repository:

  1. helm repo add cilium https://helm.cilium.io/

Deploy Cilium release via Helm:

  1. helm install cilium cilium/cilium --version 1.10.2 \
  2. --namespace kube-system \
  3. --set hostServices.enabled=true

If you can’t run 4.19.57 but have 4.17.0 available you can restrict protocol support to TCP only:

  1. helm install cilium cilium/cilium --version 1.10.2 \
  2. --namespace kube-system \
  3. --set hostServices.enabled=true \
  4. --set hostServices.protocols=tcp

Host-reachable services act transparent to Cilium’s lower layer datapath in that upon connect system call (TCP, connected UDP) or sendmsg as well as recvmsg (UDP) the destination IP is checked for an existing service IP and one of the service backends is selected as a target, meaning, while the application is assuming its connection to the service address, the corresponding kernel’s socket is actually connected to the backend address and therefore no additional lower layer NAT is required.

Verify that it has come up correctly:

  1. $ kubectl -n kube-system get pods -l k8s-app=cilium
  2. NAME READY STATUS RESTARTS AGE
  3. cilium-crf7f 1/1 Running 0 10m

Limitations

  • The kernel eBPF cgroup hooks operate at connect(2), sendmsg(2) and recvmsg(2) system call layers for connecting the application to one of the service backends. In the v5.8 Linux kernel, a getpeername(2) hook for eBPF has been added in order to also reverse translate the connected sock addresses for application’s getpeername(2) calls in Cilium. For kernels older than v5.8 such reverse translation is not taking place for this system call. For the vast majority of applications not having this translation at getpeername(2) does not cause any issues. There is one known case for libceph where its monitor might return an error since expected peer address mismatches.