Change:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: In a k8s cluster with IPVS proxy mode, when you create an ingress, the loadbalancer of this ingress can't be createautomatically, which caused the ipvs ci "gci-gce-ipvs" failed, link: http://k8s- The failed case is , with logs: Time out when waiting for for ingress to get an address. I'm not sure why, but I can see the pod keep restarting, And with container logs: AFAIK, ingress IP have nothing to do with kube-proxy, but when I change proxy mode to iptables, then ingress got it's IP in few seconds, though still in status. Is there any conflict between ipvs proxy rules and ingress controller? Maybe have this possibility. What you expected to happen: Ingress can got it's IP in ipvs proxy mode. How to reproduce it (as minimally and precisely as possible): a cluster in gce environment with proxy mode IPVS. . ingress with backends. for the ingress IP. TT Anything else we need to know?: Environment: Kubernetes version (use ): master Cloud provider or hardware configuration: gce OS (e.g. from /etc/os-release): Ubuntu16.04.3 Kernel (e.g. ): 4.13.0-1008-gcp -Ubuntu SMP Thu Jan 25 11:08:44 UTC 2018 x8664 x8664 x8664 GNU/Linux Install tools: cluster/kube-up Others:
/sig network /area ipvs
I found this maybe related with iptables rules , ingress-controller need to validate the default service by access . But the iptables like: That means the access of port will be directly DNAT to nginx-ingress-controller. In iptables proxy mode, DNAT will be done in chain, so the access of still functional. Thoughts?
I think the problem here is that the ingress controller is crash looping. You are correct that kube-proxy has nothing to do with the LB getting an ip address so I think we can rule out iptables / ipvs as the issue. I'm wondering why the nginx ingress controller in the test does not have permission to list objects in kube-system? Let me try reproducing and see what I find.
When you switched back to iptables mode, you say the container was still crashlooping. Was the error the same?
My mistake, actually the error log I pasted before is in iptables proxy mode, ipvs mode ingress-controller log are: I didn't notice the difference before. And now I'm sure the is created by kubenet, in host port map workaround. Problem is the access of is treated as , so match this rule:
So I'm confused. Why don't we see this problem in iptables mode then? What is the fix on the IPVS side?
I think that's because in iptables proxy mode, we don DNAT in , so traffic of service will never come to . Besides, iptables will match all virtual server IP in ipvs rules, make things even worse.
I think they are same issue.
/assign
Still get this issue with kubernetes 1.11.0. See below iptable rules in my host,

Discussion:
writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) } <ins> // Accept all traffic with destination of ipvs virtual service, in case other iptables rules // block the traffic, that may result in ipvs rules invalid. // Those rules must be in the end of KUBE-SERVICE chain proxier.acceptIPVSTraffic() </ins> // If the masqueradeMark has been added then we want to forward that same // traffic, this allows NodePort traffic to be forwarded even if the default // FORWARD policy is not accept.

proxier.deleteEndpointConnections(endpointUpdateResult.StaleEndpoints) } <ins> func (proxier *Proxier) acceptIPVSTraffic() { sets := []*IPSet{proxier.clusterIPSet, proxier.externalIPSet, proxier.lbIngressSet} for _, set := range sets { var matchType string if !set.isEmpty() { switch set.SetType { case utilipset.BitmapPort: matchType = "dst" default: matchType = "dst,dst" } writeLine(proxier.natRules, []string{ "-A", string(kubeServicesChain), "-m", "set", "--match-set", set.Name, matchType, "-j", "ACCEPT", }...) } } } </ins> // After a UDP endpoint has been removed, we must flush any pending conntrack entries to it, or else we // risk sending more traffic to it, all of which will be lost (because UDP). // This assumes the proxier mutex is held

checkIptables(t, ipt, epIpt) } <ins> func TestAcceptIPVSTraffic(t *testing.T) { ipt, fp := buildFakeProxier(nil) ingressIP := "1.2.3.4" externalIP := []string{"5.6.7.8"} svcInfos := []struct { svcType api.ServiceType svcIP   string svcName string epIP    string }{ {api.ServiceTypeClusterIP, "10.20.30.40", "svc1", "10.180.0.1"}, {api.ServiceTypeLoadBalancer, "10.20.30.41", "svc2", "10.180.0.2"}, {api.ServiceTypeNodePort, "10.20.30.42", "svc3", "10.180.0.3"}, } for _, svcInfo := range svcInfos { makeServiceMap(fp, makeTestService("ns1", svcInfo.svcName, func(svc *api.Service) { svc.Spec.Type = svcInfo.svcType svc.Spec.ClusterIP = svcInfo.svcIP svc.Spec.Ports = []api.ServicePort{{ Name:     "p80", Port:     80, Protocol: api.ProtocolTCP, NodePort: 80, }} if svcInfo.svcType == api.ServiceTypeLoadBalancer { svc.Status.LoadBalancer.Ingress = []api.LoadBalancerIngress{{ IP: ingressIP, }} } if svcInfo.svcType == api.ServiceTypeClusterIP { svc.Spec.ExternalIPs = externalIP } }), ) makeEndpointsMap(fp, makeTestEndpoints("ns1", "p80", func(ept *api.Endpoints) { ept.Subsets = []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{ IP: svcInfo.epIP, }}, Ports: []api.EndpointPort{{ Name: "p80", Port: 80, }}, }} }), ) } fp.syncProxyRules() // Check iptables chain and rules epIpt := netlinktest.ExpectedIptablesChain{ string(kubeServicesChain): { {JumpChain: "ACCEPT", MatchSet: KubeClusterIPSet}, {JumpChain: "ACCEPT", MatchSet: KubeLoadBalancerSet}, {JumpChain: "ACCEPT", MatchSet: KubeExternalIPSet}, }, } checkIptables(t, ipt, epIpt) } </ins> func TestOnlyLocalLoadBalancing(t *testing.T) { ipt, fp := buildFakeProxier(nil)