kubernetes: DualStack: NodePort failed when opening dual-stack with ipvs
What happened: when i created nodeport service by opening dual-stack ,it’s faild. i check the kube-proxy by
netsat -anp|grep kube-proxy
and got nothing What you expected to happen: nodeport works well when dual-stack How to reproduce it (as minimally and precisely as possible): open dual-stack and create a nodeport service Anything else we need to know?:
Environment:
- Kubernetes version (use
kubectl version
):1.17.5 - Cloud provider or hardware configuration:
- OS (e.g:
cat /etc/os-release
):
NAME="Ubuntu"
VERSION="16.04 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
UBUNTU_CODENAME=xenial
- Kernel (e.g.
uname -a
):
uname -a
Linux k8s 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
- Install tools:
- Network plugin and version (if this is a network-related bug):knitter
- Others: see the pr:
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 31 (22 by maintainers)
@andrewsykim @Lion-Wei just now, i found this 😃
for completeness and to have more context, I’m copying the original description from #93631
it seems that IPVS use the netlink library to dump the route table to get the local addresses https://github.com/kubernetes/kubernetes/blob/04362870ad9f9812f487ab8f89a40f6bf2daa588/pkg/proxy/ipvs/netlink_linux.go#L148
that, causes that if the filter protocol does not match and it can not find the corresponding IPv6 addresses.
That method is only referenced in 2 places, and it’s only used to return IP addresses per interface https://github.com/kubernetes/kubernetes/blob/04362870ad9f9812f487ab8f89a40f6bf2daa588/pkg/proxy/ipvs/proxier.go#L293 https://github.com/kubernetes/kubernetes/blob/04362870ad9f9812f487ab8f89a40f6bf2daa588/pkg/proxy/ipvs/proxier.go#L306
My suggestion for fixing this (I vaguely remember that we discussed this in another PR and someone already submitted something along this lines), is to replace that method for a function that use the go net library. It simplifies a lot the code (looking the routing table for getting the local addresses is more complex than iterating over the current interfaces ip address ), it’s a very simple fix and removes external dependencies, that seems a win-win 😄
An example that can be adapted is:
I defer to IPVS maintainers the last decision /assign @andrewsykim
/remove-lifecycle stale
I will fix this by using the go net library as @aojea suggested above.
@andrewsykim @Lion-Wei i think maybe it’s a bug of linux. in linux kernel 4.4 there is a function ‘addrconf_dst_alloc’ which has been repaced by ‘addrconf_f6i_alloc’(https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/net/ipv6/route.c#L4438)now. below shows difference: 4.4:
master:
and the function ‘rt6_fill_node’ 4.4:
master:
https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/net/ipv6/route.c#L5494

the thing is more simple for ipv4: https://github.com/torvalds/linux/blob/9bf9511e3d9f328c03f6f79bfb741c3d18f2f2c0/net/ipv4/fib_frontend.c#L1049
the code has never been changed
i install a high version linux:
and try again:
the proto type is correct now.