From 5fc39db6a0aef47c3de377414a30aea8897c08e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Dunand?= Date: Tue, 4 Aug 2020 12:15:52 +0200 Subject: [PATCH] Add hairpin support for externalIps Add an extra annotation for service in order to generate haipin related iptables rules for externalsIps of the service. --- docs/user-guide.md | 5 ++++ .../proxy/network_services_controller.go | 23 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/user-guide.md b/docs/user-guide.md index 0ffee5cc..32b7be16 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -216,6 +216,11 @@ To enable hairpin traffic for Service `my-service`: kubectl annotate service my-service "kube-router.io/service.hairpin=" ``` +If you want hairpin also apply on externalIPs declared for Service `my-service`: +``` +kubectl annotate service my-service "kube-router.io/service.hairpin.externalips=" +``` + ## Direct server return Please read below blog on how to user DSR in combination with `--advertise-external-ip` to build highly scalable and available ingress. diff --git a/pkg/controllers/proxy/network_services_controller.go b/pkg/controllers/proxy/network_services_controller.go index b42cf4b4..9573e9e3 100644 --- a/pkg/controllers/proxy/network_services_controller.go +++ b/pkg/controllers/proxy/network_services_controller.go @@ -47,12 +47,13 @@ const ( IpvsSvcFSched2 = "flag-2" IpvsSvcFSched3 = "flag-3" - svcDSRAnnotation = "kube-router.io/service.dsr" - svcSchedulerAnnotation = "kube-router.io/service.scheduler" - svcHairpinAnnotation = "kube-router.io/service.hairpin" - svcLocalAnnotation = "kube-router.io/service.local" - svcSkipLbIpsAnnotation = "kube-router.io/service.skiplbips" - svcSchedFlagsAnnotation = "kube-router.io/service.schedflags" + svcDSRAnnotation = "kube-router.io/service.dsr" + svcSchedulerAnnotation = "kube-router.io/service.scheduler" + svcHairpinAnnotation = "kube-router.io/service.hairpin" + svcHairpinExternalIPsAnnotation = "kube-router.io/service.hairpin.externalips" + svcLocalAnnotation = "kube-router.io/service.local" + svcSkipLbIpsAnnotation = "kube-router.io/service.skiplbips" + svcSchedFlagsAnnotation = "kube-router.io/service.schedflags" LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader" localIPsIPSetName = "kube-router-local-ips" @@ -257,6 +258,7 @@ type serviceInfo struct { scheduler string directServerReturnMethod string hairpin bool + hairpinExternalIPs bool skipLbIps bool externalIPs []string loadBalancerIPs []string @@ -1399,6 +1401,7 @@ func (nsc *NetworkServicesController) buildServicesInfo() serviceInfoMap { svcInfo.sessionAffinityTimeoutSeconds = *svc.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds } _, svcInfo.hairpin = svc.ObjectMeta.Annotations[svcHairpinAnnotation] + _, svcInfo.hairpinExternalIPs = svc.ObjectMeta.Annotations[svcHairpinExternalIPsAnnotation] _, svcInfo.local = svc.ObjectMeta.Annotations[svcLocalAnnotation] _, svcInfo.skipLbIps = svc.ObjectMeta.Annotations[svcSkipLbIpsAnnotation] if svc.Spec.ExternalTrafficPolicy == api.ServiceExternalTrafficPolicyTypeLocal { @@ -1574,6 +1577,14 @@ func (nsc *NetworkServicesController) syncHairpinIptablesRules() error { rule, ruleArgs := hairpinRuleFrom(svcInfo.clusterIP.String(), ep.ip, svcInfo.port) rulesNeeded[rule] = ruleArgs + // Handle ExternalIPs if requested + if svcInfo.hairpinExternalIPs { + for _, extip := range svcInfo.externalIPs { + rule, ruleArgs := hairpinRuleFrom(extip, ep.ip, svcInfo.port) + rulesNeeded[rule] = ruleArgs + } + } + // Handle NodePort Service if svcInfo.nodePort != 0 { rule, ruleArgs := hairpinRuleFrom(nsc.nodeIP.String(), ep.ip, svcInfo.nodePort)