Skip to content

Commit 7c2f664

Browse files
[release-v1.38] Auto pick #3866: Set explicit DNS nameservers for calico/node when needed (#3868)
* Set explicit DNS nameservers for calico/node when needed * Make gen-versions * Update copyright * Fix typo * Fix log * gosimple * fix * gen-versions
1 parent 8c848f2 commit 7c2f664

File tree

5 files changed

+60
-1
lines changed

5 files changed

+60
-1
lines changed

cmd/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,12 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe
389389
log.Error(err, fmt.Sprintf("Couldn't find the cluster domain from the resolv.conf, defaulting to %s", clusterDomain))
390390
}
391391

392+
nameservers, err := dns.Nameservers(dns.DefaultResolveConfPath)
393+
if err != nil {
394+
log.Error(err, "Couldn't find the nameservers from the resolv.conf")
395+
}
396+
log.Infof("Found nameservers: %v", nameservers)
397+
392398
kubernetesVersion, err := common.GetKubernetesVersion(clientset)
393399
if err != nil {
394400
log.Error(err, "Unable to resolve Kubernetes version, defaulting to v1.18")
@@ -436,6 +442,7 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe
436442
DetectedProvider: provider,
437443
EnterpriseCRDExists: enterpriseCRDExists,
438444
ClusterDomain: clusterDomain,
445+
Nameservers: nameservers,
439446
KubernetesVersion: kubernetesVersion,
440447
ManageCRDs: manageCRDs,
441448
ShutdownContext: ctx,

pkg/controller/installation/core_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ func newReconciler(mgr manager.Manager, opts options.AddOptions) (*ReconcileInst
185185
namespaceMigration: nm,
186186
enterpriseCRDsExist: opts.EnterpriseCRDExists,
187187
clusterDomain: opts.ClusterDomain,
188+
nameservers: opts.Nameservers,
188189
manageCRDs: opts.ManageCRDs,
189190
tierWatchReady: &utils.ReadyFlag{},
190191
newComponentHandler: utils.NewComponentHandler,
@@ -368,6 +369,7 @@ type ReconcileInstallation struct {
368369
enterpriseCRDsExist bool
369370
migrationChecked bool
370371
clusterDomain string
372+
nameservers []string
371373
manageCRDs bool
372374
tierWatchReady *utils.ReadyFlag
373375
// newComponentHandler returns a new component handler. Useful stub for unit testing.
@@ -1410,6 +1412,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile
14101412
BirdTemplates: birdTemplates,
14111413
TLS: typhaNodeTLS,
14121414
ClusterDomain: r.clusterDomain,
1415+
Nameservers: r.nameservers,
14131416
NodeReporterMetricsPort: nodeReporterMetricsPort,
14141417
BGPLayouts: bgpLayout,
14151418
NodeAppArmorProfile: nodeAppArmorProfile,

pkg/controller/options/options.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ type AddOptions struct {
3434
ManageCRDs bool
3535
ShutdownContext context.Context
3636

37+
// Nameservers contains the nameservers configured for the operator. Most pods do not need explicit
38+
// nameservers specified, as they will use the default nameservers configured in the cluster. However, any pods
39+
// that must function prior to cluster DNS being available (e.g., the operator itself and calico/node)
40+
// may need to have the nameservers explicitly set if configured to access the Kubernetes API via a domain name.
41+
Nameservers []string
42+
3743
// Kubernetes clientset used by controllers to create watchers and informers.
3844
K8sClientset *kubernetes.Clientset
3945

pkg/dns/dns.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved.
1+
// Copyright (c) 2020-2025 Tigera, Inc. All rights reserved.
22

33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package dns
1717
import (
1818
"bufio"
1919
"fmt"
20+
"net"
2021
"os"
2122
"regexp"
2223
)
@@ -59,6 +60,38 @@ func GetClusterDomain(resolvConfPath string) (string, error) {
5960
return clusterDomain, nil
6061
}
6162

63+
// IsDomainName checks if the given name is a domain name and returns true if it is.
64+
func IsDomainName(name string) bool {
65+
// Attempt to parse it as an IP.
66+
return net.ParseIP(name) == nil
67+
}
68+
69+
// Nameservers returns the list of nameservers from the resolv.conf file.
70+
func Nameservers(resolvConfPath string) ([]string, error) {
71+
var nameservers []string
72+
file, err := os.Open(resolvConfPath)
73+
if err != nil {
74+
return nil, err
75+
}
76+
defer file.Close()
77+
78+
reg := regexp.MustCompile(`^nameserver\s+([^\s]+)`)
79+
80+
scanner := bufio.NewScanner(file)
81+
for scanner.Scan() {
82+
match := reg.FindStringSubmatch(scanner.Text())
83+
if len(match) > 0 {
84+
nameservers = append(nameservers, match[1])
85+
}
86+
}
87+
88+
if err := scanner.Err(); err != nil {
89+
return nil, err
90+
}
91+
92+
return nameservers, nil
93+
}
94+
6295
// GetServiceDNSNames returns a list of a service's DNS names.
6396
// We return:
6497
// - <svc_name>

pkg/render/node.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/tigera/operator/pkg/components"
3636
"github.com/tigera/operator/pkg/controller/k8sapi"
3737
"github.com/tigera/operator/pkg/controller/migration"
38+
"github.com/tigera/operator/pkg/dns"
3839
"github.com/tigera/operator/pkg/ptr"
3940
rcomp "github.com/tigera/operator/pkg/render/common/components"
4041
"github.com/tigera/operator/pkg/render/common/configmap"
@@ -98,6 +99,7 @@ type NodeConfiguration struct {
9899
IPPools []operatorv1.IPPool
99100
TLS *TyphaNodeTLS
100101
ClusterDomain string
102+
Nameservers []string
101103

102104
// Optional fields.
103105
LogCollector *operatorv1.LogCollector
@@ -987,6 +989,14 @@ func (c *nodeComponent) nodeDaemonset(cniCfgMap *corev1.ConfigMap) *appsv1.Daemo
987989
},
988990
}
989991

992+
if len(c.cfg.Nameservers) > 0 && dns.IsDomainName(c.cfg.K8sServiceEp.Host) {
993+
// If the configured k8s service endpoint is a domain name rather than an IP address, calico/node
994+
// will need explicit nameservers to resolve it.
995+
ds.Spec.Template.Spec.DNSConfig = &corev1.PodDNSConfig{
996+
Nameservers: c.cfg.Nameservers,
997+
}
998+
}
999+
9901000
if c.cfg.Installation.CNI.Type == operatorv1.PluginCalico {
9911001
ds.Spec.Template.Spec.InitContainers = append(ds.Spec.Template.Spec.InitContainers, c.cniContainer())
9921002
}

0 commit comments

Comments
 (0)