Skip to content
LinkState
Go back

Kubernetes DNAT with nft backend gone sideways

Introduction to Node-Level Service Failure

Kube-proxy and CNI masquerade are two critical components in a Kubernetes cluster that work together to enable pod-to-pod and pod-to-service communication. Kube-proxy is responsible for load-balancing and forwarding traffic to the correct pod, while CNI masquerade is used to NAT (Network Address Translation) the traffic so that it appears to come from the host machine.

Reproducing the Node-Level Service Failure

To reproduce a node-level service failure, we need to set up a Kubernetes cluster with a pod running a service that we can use to test the packet flow.

# Create a Kubernetes cluster
kubeadm init
# Deploy a pod running a simple web server
kubectl create deployment web-server --image=httpd:latest

Next, we need to configure kube-proxy and CNI masquerade to enable packet flow between the pod and the host machine.

# Kube-proxy configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-proxy-config
data:
  config.conf: |
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    mode: "iptables"
# CNI masquerade configuration
{
  "cniVersion": "0.3.1",
  "name": "masquerade",
  "type": "masquerade",
  "args": {
    "mode": "all"
  }
}

Finally, we need to implement host nftables rules to inspect and modify packets as they flow through the host machine.

# Add a table and chain for NAT rules
nft add table ip nat
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# Add a masquerade rule
nft add rule ip nat postrouting masquerade

Troubleshooting the Service Failure

To troubleshoot the service failure, we need to identify the packet flow issues that are causing the problem. We can use tools like tcpdump and nft to capture and inspect packets as they flow through the host machine.

# Capture packets on the eth0 interface
tcpdump -i eth0 -n -vv -s 0 -c 100
# List all nftables rules
nft list ruleset

We can also analyze log files for error messages that may indicate the cause of the service failure.

# Check the kube-proxy log file for errors
kubectl logs -f kube-proxy

Isolating the Exact Translation or Hook

To isolate the exact translation or hook that changed the fate of the packet, we need to understand the packet flow through the host machine.

# Kube-proxy configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-proxy-config
data:
  config.conf: |
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    mode: "iptables"
# CNI masquerade configuration
{
  "cniVersion": "0.3.1",
  "name": "masquerade",
  "type": "masquerade",
  "args": {
    "mode": "all"
  }
}
# Add a table and chain for NAT rules
nft add table ip nat
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# Add a masquerade rule
nft add rule ip nat postrouting masquerade

Code Examples for Troubleshooting

Kube-Proxy Configuration Example

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-proxy-config
data:
  config.conf: |
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    mode: "iptables"

CNI Masquerade Configuration Example

{
  "cniVersion": "0.3.1",
  "name": "masquerade",
  "type": "masquerade",
  "args": {
    "mode": "all"
  }
}

Nftables Rule Example

nft add table ip nat
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule ip nat postrouting masquerade

Scaling Limitations and Considerations

Kube-proxy and CNI masquerade can have a significant performance impact on the host machine, especially at scale. Nftables rules can become complex and difficult to manage at scale. To scale node-level services, it is essential to follow best practices for configuring kube-proxy, CNI masquerade, and host nftables rules.

Advanced Troubleshooting Techniques

ebpf and bpftrace are powerful tools for packet analysis and debugging. Custom nftables hooks can be used to implement additional packet processing and analysis code. Integrating with external monitoring and logging tools can provide additional visibility into packet flow issues and service failures.

Conclusion and Recommendations

To prevent node-level service failures, it is essential to follow best practices for configuring kube-proxy, CNI masquerade, and host nftables rules. Future directions for improving node-level service reliability include improving the performance and scalability of kube-proxy and CNI masquerade, developing more advanced packet analysis and debugging tools, and integrating with external monitoring and logging tools.


Share this post on:

Previous Post
Where VXLAN actually burns CPU in Linux labs
Next Post
ECMP failover across unequal policy domains