Skip to content

Commit

Permalink
hostport: Add an option host-port-only-local
Browse files Browse the repository at this point in the history
Enable option host-port-only-local expects same behavior as kube-proxy, that is
almost same with the iptable rule 'ADDRTYPE match dst-type LOCAL'. And means not
do the destination pod ip translation locally.

Yes, the present implementation has better performance for pod to pod traffics
inside cluster, but in some special cases we still need this option to keep same
behavior with kube-proxy, and if all the traffics come from outside, we do not
need thousands of service mapping entries on each nodes.

Fixes: 7fcf660 ("cilium, bpf: add native HostPort mapping support")

Example:
--host-port-only-local=false (by default, no changes)
8    10.44.76.162:9000    HostPort       1 => 172.30.0.74:8000
9    10.44.75.162:9000    HostPort       1 => 172.30.2.178:8000
10   10.44.74.162:9000    HostPort       1 => 172.30.3.29:8000
11   10.44.76.150:9000    HostPort       1 => 172.30.1.34:8000

--host-port-only-local=true
8    10.44.76.162:9000    HostPort       1 => 172.30.0.74:8000

Signed-off-by: yangxingwu <[email protected]>
Signed-off-by: huangxuesen <[email protected]>
Signed-off-by: Wang Li <[email protected]>
  • Loading branch information
Wang Li committed Apr 22, 2020
1 parent fff6d6c commit 4e632d2
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 5 deletions.
1 change: 1 addition & 0 deletions Documentation/cmdref/cilium-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ cilium-agent [flags]
--flannel-uninstall-on-exit When used along the flannel-master-device flag, it cleans up all BPF programs installed when Cilium agent is terminated.
--force-local-policy-eval-at-source Force policy evaluation of all local communication at the source endpoint (default true)
-h, --help help for cilium-agent
--host-port-only-local Only generate hostPort mapping on local node (requires enabling enable-host-port)
--host-reachable-services-protos strings Only enable reachability of services for host applications for specific protocols (default [tcp,udp])
--http-idle-timeout uint Time after which a non-gRPC HTTP stream is considered failed unless traffic in the stream has been processed (in seconds); defaults to 0 (unlimited)
--http-max-grpc-timeout uint Time after which a forwarded gRPC request is considered failed unless completed (in seconds). A "grpc-timeout" header may override this with a shorter value; defaults to 0 (unlimited)
Expand Down
3 changes: 3 additions & 0 deletions api/v1/models/kube_proxy_replacement.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions api/v1/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,8 @@ definitions:
properties:
enabled:
type: boolean
local:
type: boolean
externalIPs:
type: object
properties:
Expand Down
6 changes: 6 additions & 0 deletions api/v1/server/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions daemon/cmd/daemon_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ func init() {
flags.Bool(option.EnableHostPort, true, fmt.Sprintf("Enable k8s hostPort mapping feature (requires enabling %s)", option.EnableNodePort))
option.BindEnv(option.EnableHostPort)

flags.Bool(option.HostPortOnlyLocal, false, fmt.Sprintf("Only generate hostPort mapping on local node (requires enabling %s)", option.EnableHostPort))
option.BindEnv(option.HostPortOnlyLocal)

flags.Bool(option.EnableNodePort, false, "Enable NodePort type services by Cilium (beta)")
option.BindEnv(option.EnableNodePort)

Expand Down
3 changes: 3 additions & 0 deletions daemon/cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ func (d *Daemon) getKubeProxyReplacementStatus() *models.KubeProxyReplacement {
}
if option.Config.EnableHostPort {
features.HostPort.Enabled = true
if option.Config.HostPortOnlyLocal {
features.HostPort.Local = true
}
}
if option.Config.EnableExternalIPs {
features.ExternalIPs.Enabled = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ data:
{{- end }}
{{- if .Values.global.hostPort }}
enable-host-port: {{ .Values.global.hostPort.enabled | quote }}
host-port-only-local: {{ .Values.global.hostPort.onlyLocal | quote }}
{{- end }}
{{- if .Values.global.externalIPs }}
enable-external-ips: {{ .Values.global.externalIPs.enabled | quote }}
Expand Down
3 changes: 3 additions & 0 deletions install/kubernetes/cilium/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ global:
# enabled enables the hostPort functionality
enabled: false

# onlyLocal indicates to generate service mapping only for local node
onlyLocal: false

# externalIPs is the configuration for ExternalIPs service handling
externalIPs:
# enabled enables ExternalIPs functionality
Expand Down
6 changes: 5 additions & 1 deletion pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,11 @@ func FormatStatusResponse(w io.Writer, sr *models.StatusResponse, allAddresses,
}

if sr.KubeProxyReplacement.Features.HostPort.Enabled {
features = append(features, "HostPort")
if sr.KubeProxyReplacement.Features.HostPort.Local {
features = append(features, "HostPort (only local)")
} else {
features = append(features, "HostPort")
}
}

if sr.KubeProxyReplacement.Features.ExternalIPs.Enabled {
Expand Down
3 changes: 3 additions & 0 deletions pkg/datapath/linux/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ func (h *HeaderfileWriter) WriteNodeConfig(w io.Writer, cfg *datapath.LocalNodeC
}
if option.Config.EnableHostPort {
cDefinesMap["ENABLE_HOSTPORT"] = "1"
if option.Config.HostPortOnlyLocal {
cDefinesMap["HOSTPORT_ONLY_LOCAL"] = "1"
}
}

cDefinesMap["NODEPORT_PORT_MIN"] = fmt.Sprintf("%d", option.Config.NodePortMin)
Expand Down
15 changes: 12 additions & 3 deletions pkg/k8s/watchers/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func (k *K8sWatcher) deleteK8sPodV1(pod *types.Pod) error {
return err
}

func genServiceMappings(pod *types.Pod) []loadbalancer.SVC {
func genHostPortServiceMappings(localIPv4 net.IP, localIPv6 net.IP, onlyLocal bool, pod *types.Pod) []loadbalancer.SVC {
var svcs []loadbalancer.SVC
for _, c := range pod.SpecContainers {
for _, p := range c.HostPorts {
Expand All @@ -289,6 +289,11 @@ func genServiceMappings(pod *types.Pod) []loadbalancer.SVC {
if feIP == nil {
feIP = net.ParseIP(pod.StatusHostIP)
}

if onlyLocal && !feIP.Equal(localIPv4) && !feIP.Equal(localIPv6) {
continue
}

proto, err := loadbalancer.NewL4Type(p.Protocol)
if err != nil {
continue
Expand Down Expand Up @@ -333,7 +338,9 @@ func (k *K8sWatcher) UpsertHostPortMapping(pod *types.Pod) error {
return nil
}

svcs := genServiceMappings(pod)
svcs := genHostPortServiceMappings(k.datapath.LocalNodeAddressing().IPv4().PrimaryExternal(),
k.datapath.LocalNodeAddressing().IPv6().PrimaryExternal(),
option.Config.HostPortOnlyLocal, pod)
if len(svcs) == 0 {
return nil
}
Expand Down Expand Up @@ -368,7 +375,9 @@ func (k *K8sWatcher) DeleteHostPortMapping(pod *types.Pod) error {
return nil
}

svcs := genServiceMappings(pod)
svcs := genHostPortServiceMappings(k.datapath.LocalNodeAddressing().IPv4().PrimaryExternal(),
k.datapath.LocalNodeAddressing().IPv6().PrimaryExternal(),
option.Config.HostPortOnlyLocal, pod)
if len(svcs) == 0 {
return nil
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/option/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ const (
// EnableHostPort enables HostPort forwarding implemented by Cilium in BPF
EnableHostPort = "enable-host-port"

// HostPortOnlyLocal only generates HostPort mapping on local node
HostPortOnlyLocal = "host-port-only-local"

// EnableNodePort enables NodePort services implemented by Cilium in BPF
EnableNodePort = "enable-node-port"

Expand Down Expand Up @@ -1712,6 +1715,9 @@ type DaemonConfig struct {
// EnableHostPort enables k8s Pod's hostPort mapping through BPF
EnableHostPort bool

// HostPortOnlyLocal only generates hostport mapping on local node
HostPortOnlyLocal bool

// NodePortMode indicates in which mode NodePort implementation should run
// ("snat", "dsr" or "hybrid")
NodePortMode string
Expand Down Expand Up @@ -2321,8 +2327,9 @@ func (c *DaemonConfig) Populate() {
c.EnableExternalIPs = viper.GetBool(EnableExternalIPs)
c.EnableL7Proxy = viper.GetBool(EnableL7Proxy)
c.EnableTracing = viper.GetBool(EnableTracing)
c.EnableNodePort = viper.GetBool(EnableNodePort)
c.EnableHostPort = viper.GetBool(EnableHostPort)
c.HostPortOnlyLocal = viper.GetBool(HostPortOnlyLocal)
c.EnableNodePort = viper.GetBool(EnableNodePort)
c.NodePortMode = viper.GetString(NodePortMode)
c.NodePortAcceleration = viper.GetString(NodePortAcceleration)
c.EnableAutoProtectNodePortRange = viper.GetBool(EnableAutoProtectNodePortRange)
Expand Down

0 comments on commit 4e632d2

Please sign in to comment.