Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bind Envoy NLLB to all localhost loopback IPs #4529

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions pkg/component/worker/nllb/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ type envoyParams struct {
// Directory in which the envoy config files are stored.
configDir string

// IP to which Envoy will bind.
bindIP net.IP
// IPs to which Envoy will bind.
bindIPs []net.IP

// Port to which Envoy will bind the API server load balancer.
apiServerBindPort uint16
Expand Down Expand Up @@ -131,12 +131,12 @@ func (e *envoyProxy) start(ctx context.Context, profile workerconfig.Profile, ap
}
}()

loopbackIP, err := getLoopbackIP(ctx)
loopbackIPs, err := getLoopbackIPs(ctx)
if err != nil {
if errors.Is(err, ctx.Err()) {
return err
}
e.log.WithError(err).Infof("Falling back to %s as bind address", loopbackIP)
e.log.WithError(err).Infof("Falling back to %v as bind addresses", loopbackIPs)
}

nllb := profile.NodeLocalLoadBalancing
Expand All @@ -148,7 +148,7 @@ func (e *envoyProxy) start(ctx context.Context, profile workerconfig.Profile, ap
e.config = &envoyConfig{
envoyParams{
e.dir,
loopbackIP,
loopbackIPs,
uint16(profile.NodeLocalLoadBalancing.EnvoyProxy.APIServerBindPort),
konnectivityBindPort,
},
Expand Down Expand Up @@ -179,7 +179,7 @@ func (e *envoyProxy) getAPIServerAddress() (*k0snet.HostPort, error) {
if e.config == nil {
return nil, errors.New("not yet started")
}
return k0snet.NewHostPort(e.config.bindIP.String(), e.config.apiServerBindPort)
return k0snet.NewHostPort(e.config.getBindHost(), e.config.apiServerBindPort)
}

func (e *envoyProxy) updateAPIServers(apiServers []k0snet.HostPort) error {
Expand Down Expand Up @@ -213,15 +213,23 @@ func (e *envoyProxy) stop() {
e.config = nil
}

func (p *envoyParams) getBindHost() string {
if len(p.bindIPs) == 1 {
return p.bindIPs[0].String()
}

return "localhost"
}

func writeEnvoyConfigFiles(params *envoyParams, filesParams *envoyFilesParams) error {
data := struct {
BindIP net.IP
BindIPs []net.IP
APIServerBindPort uint16
KonnectivityServerBindPort uint16
KonnectivityServerPort uint16
UpstreamServers []k0snet.HostPort
}{
BindIP: params.bindIP,
BindIPs: params.bindIPs,
APIServerBindPort: params.apiServerBindPort,
KonnectivityServerBindPort: params.konnectivityServerBindPort,
KonnectivityServerPort: filesParams.konnectivityServerPort,
Expand Down Expand Up @@ -301,7 +309,7 @@ func makePodManifest(params *envoyParams, podParams *envoyPodParams) corev1.Pod
TimeoutSeconds: 3,
ProbeHandler: corev1.ProbeHandler{
TCPSocket: &corev1.TCPSocketAction{
Host: params.bindIP.String(), Port: intstr.FromInt(int(params.apiServerBindPort)),
Host: params.getBindHost(), Port: intstr.FromInt(int(params.apiServerBindPort)),
},
},
},
Expand All @@ -328,24 +336,28 @@ dynamic_resources:
cds_config:
path: /etc/envoy/cds.yaml

{{ $localKonnectivityPort := .KonnectivityServerBindPort -}}
{{ $apiServerPort := .APIServerBindPort -}}
{{- $localKonnectivityPort := .KonnectivityServerBindPort -}}
{{- $remoteKonnectivityPort := .KonnectivityServerPort -}}
static_resources:
listeners:
- name: apiserver
{{- range $idx, $bindIP := .BindIPs }}
- name: apiserver-ip-{{ $idx }}
address:
socket_address: { address: {{ printf "%q" .BindIP }}, port_value: {{ .APIServerBindPort }} }
socket_address: { address: {{ printf "%q" $bindIP }}, port_value: {{ $apiServerPort }} }
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: apiserver
cluster: apiserver
{{- end }}
{{- if ne $localKonnectivityPort 0 }}
- name: konnectivity
{{- range $idx, $bindIP := .BindIPs }}
- name: konnectivity-ip-{{ $idx }}
address:
socket_address: { address: {{ printf "%q" .BindIP }}, port_value: {{ $localKonnectivityPort }} }
socket_address: { address: {{ printf "%q" $bindIP }}, port_value: {{ $localKonnectivityPort }} }
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
Expand All @@ -354,6 +366,7 @@ static_resources:
stat_prefix: konnectivity
cluster: konnectivity
{{- end }}
{{- end }}
`))

var envoyClustersConfig = template.Must(template.New("Clusters").Parse(`
Expand Down
2 changes: 1 addition & 1 deletion pkg/component/worker/nllb/envoy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestWriteEnvoyConfigFiles(t *testing.T) {
dir := t.TempDir()
params := envoyParams{
configDir: dir,
bindIP: net.IPv6loopback,
bindIPs: []net.IP{net.IPv6loopback},
}
filesParams := envoyFilesParams{}
for _, server := range test.servers {
Expand Down
10 changes: 7 additions & 3 deletions pkg/component/worker/nllb/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,19 +418,23 @@ func writePatchedKubeconfig(path string, kubeconfig *clientcmdapi.Config, server
return file.WriteContentAtomically(path, bytes, constant.CertSecureMode)
}

func getLoopbackIP(ctx context.Context) (net.IP, error) {
func getLoopbackIPs(ctx context.Context) (ips []net.IP, _ error) {
localIPs, err := net.DefaultResolver.LookupIPAddr(ctx, "localhost")
if err != nil {
err = fmt.Errorf("failed to resolve localhost: %w", err)
} else {
for _, addr := range localIPs {
if addr.IP.IsLoopback() {
return addr.IP, nil
ips = append(ips, addr.IP)
}
}

if len(ips) != 0 {
return ips, nil
}

err = fmt.Errorf("no loopback IPs found for localhost: %v", localIPs)
}

return net.IP{127, 0, 0, 1}, err
return []net.IP{{127, 0, 0, 1}}, err
}
Loading