kubernetes: IPVS is not working with hostport
Is this a BUG REPORT or FEATURE REQUEST?
Choose one: BUG REPORT
Versions
kubeadm version (use kubeadm version):
Environment:
- Kubernetes version (use
kubectl version): 1.11.0 - Cloud provider or hardware configuration: None
- OS (e.g. from /etc/os-release): Ubuntu 16.04
- Kernel (e.g.
uname -a): - Others:
What happened?
I’m trying to set up a kubernetes (v1.11.0) cluster. Here is the setting of the cluster:
- Enable IPVS in kube-proxy
- Use hostport for nginx ingress controller. Deloy nginx ingress controller on the same node as kubenetes core services.
Host port 443 and 80 of nginx ingress controller is conflict with kubernetes (kube-apiserver) service’s port 443 and 80. Nginx ingress controller keeps crashloopback because failed to connect to kube-apiserver. I even cannot run telnet 10.0.0.1 443.
Try to find the root cause. Here is the iptable rules generated
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- anywhere anywhere /* cali:6gwbT8clXdHdC1b1 */
CNI-HOSTPORT-DNAT all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
KUBE-SERVICES all -- anywhere anywhere /* kubernetes service portals */
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
cali-OUTPUT all -- anywhere anywhere /* cali:tVnHkvAo15HuiPy0 */
CNI-HOSTPORT-DNAT all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
KUBE-SERVICES all -- anywhere anywhere /* kubernetes service portals */
DOCKER all -- anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
cali-POSTROUTING all -- anywhere anywhere /* cali:O3lYWMrLQYEMJtB5 */
CNI-HOSTPORT-SNAT all -- localhost !localhost
KUBE-POSTROUTING all -- anywhere anywhere /* kubernetes postrouting rules */
MASQUERADE all -- 172.17.0.0/16 anywhere
The CNI-HOSTPORT related iptable rules are on top of KUBE-SERVICES rule. As you seen the pre-routing rule
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- anywhere anywhere /* cali:6gwbT8clXdHdC1b1 */
CNI-HOSTPORT-DNAT all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
KUBE-SERVICES all -- anywhere anywhere /* kubernetes service portals */
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Every time I call https://10.0.0.1:443 it will match CNI-HOSTPORT-DNAT rule to redirect to nginx ingress service. That’s why I got failure when calling kubernetes api with service ip.
What you expected to happen?
Should always take KUBE-SERVICES rule first rather than CNI-HOSTPORT-DNAT. So the pre-routing rule should be like
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- anywhere anywhere /* cali:6gwbT8clXdHdC1b1 */
KUBE-SERVICES all -- anywhere anywhere /* kubernetes service portals */
CNI-HOSTPORT-DNAT all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
How to reproduce it (as minimally and precisely as possible)?
See above append.
Anything else we need to know?
When I restarted kube-proxy, the iptable rules were generated correctly. Nginx ingress controller now started successfully.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 38 (14 by maintainers)
Commits related to this issue
- Make hostport to cowork with ipvs kube-proxy More details https://github.com/kubernetes/kubernetes/issues/66103 — committed to chenchun/galaxy by chenchun 4 years ago
@Lion-Wei Yes,Some cni plugin may think the service ip or host port should it self to generate a iptables chain and rule to hold this problem. If we just make the proxy’s iptables rule on the top of preroute chain.We may fix this problem but maybe cause other problems. In my opion,i want the @liqlin2015 to give us the ingress config . And would do you like to give us the whole iptables rule to let me know the calico’s rule. And the ipset list, ipvs? Let’s to find out why the calico chain above the KUBE-SERVICES make ur service wrong. In my env, i use contiv and ipvs dont have the problem. Thx.
iptables rule sequencing should be fixed now in all active branches.
Another way to avoid this hop, is to run nginx as
This way it does not conflict with
kubernetes.deafult.svc.cluster.local:443and still listening directly on Node:443.@Lion-Wei I came across a merged PR (https://github.com/kubernetes/kubernetes/pull/62718) that you authored that seem to suggest that the issue of IPVS/hostPort incompatibility was fixed.
However this issue seems to suggest otherwise, I guess this is a different problem? though also related to IPVS/hostPort?
We use the nginx ingress controller on hostPorts 80, 443 + various TCP ports (for services that consume raw tcp) that are also exposed on clusterIP services (with same port numbers).
We’ve hit this issue during testing (K8s 1.13.2, kube-proxy IPVS mode and Calico 3.4.0) and can’t seem to find a solution/workaround.
Given our requirements, we may need to move back to kube-proxy iptables mode.
Would be great if you can share any details you know, or perhaps a workaround? 🙏
+1
ping @thockin 🙏
EDIT: wanted to share the details I got from @thockin in case anyone else wonders:
https://github.com/containernetworking/plugins/pull/269 is the one I think you want, which is released in https://github.com/containernetworking/plugins/releases/tag/v0.7.5 which is integrated in https://github.com/kubernetes/kubernetes/pulls?q=is%3Apr+CNI+0.7.5+is%3Aclosed
basically, ipvs nat mode will not do snat - i know it is confused but that is true.