-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multi-cluster tproxy with consul-dataplane's DNS proxy
- Loading branch information
Showing
18 changed files
with
220 additions
and
224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package connectinject | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/miekg/dns" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/utils/pointer" | ||
) | ||
|
||
func (w *MeshWebhook) configureDNS(pod *corev1.Pod) error { | ||
// First, we need to determine the nameservers configured in this cluster from /etc/resolv.conf. | ||
etcResolvConf := "/etc/resolv.conf" | ||
if w.etcResolvFile != "" { | ||
etcResolvConf = w.etcResolvFile | ||
} | ||
cfg, err := dns.ClientConfigFromFile(etcResolvConf) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Set DNS policy on the pod to None because we want DNS to work according to the config we will provide. | ||
pod.Spec.DNSPolicy = corev1.DNSNone | ||
|
||
// Set the consul-dataplane's DNS server as the first server in the list (i.e. localhost). | ||
// We want to do that so that when consul cannot resolve the record, we will fall back to the nameservers | ||
// configured in our /etc/resolv.conf. It's important to add Consul DNS as the first nameserver because | ||
// if we put kube DNS first, it will return NXDOMAIN response and a DNS client will not fall back to other nameservers. | ||
if pod.Spec.DNSConfig == nil { | ||
consulDPAddress := "127.0.0.1" | ||
nameservers := []string{consulDPAddress} | ||
nameservers = append(nameservers, cfg.Servers...) | ||
var options []corev1.PodDNSConfigOption | ||
if cfg.Ndots != 0 { | ||
ndots := strconv.Itoa(cfg.Ndots) | ||
options = append(options, corev1.PodDNSConfigOption{ | ||
Name: "ndots", | ||
Value: &ndots, | ||
}) | ||
} | ||
if cfg.Timeout != 0 { | ||
options = append(options, corev1.PodDNSConfigOption{ | ||
Name: "timeout", | ||
Value: pointer.String(strconv.Itoa(cfg.Timeout)), | ||
}) | ||
} | ||
if cfg.Attempts != 0 { | ||
options = append(options, corev1.PodDNSConfigOption{ | ||
Name: "attempts", | ||
Value: pointer.String(strconv.Itoa(cfg.Attempts)), | ||
}) | ||
} | ||
|
||
pod.Spec.DNSConfig = &corev1.PodDNSConfig{ | ||
Nameservers: nameservers, | ||
Searches: cfg.Search, | ||
Options: options, | ||
} | ||
} else { | ||
return fmt.Errorf("DNS redirection to Consul is not supported with an already defined DNSConfig on the pod") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package connectinject | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/utils/pointer" | ||
) | ||
|
||
func TestMeshWebhook_configureDNS(t *testing.T) { | ||
cases := map[string]struct { | ||
etcResolv string | ||
expDNSConfig *corev1.PodDNSConfig | ||
}{ | ||
"empty /etc/resolv.conf file": { | ||
expDNSConfig: &corev1.PodDNSConfig{ | ||
Nameservers: []string{"127.0.0.1"}, | ||
Searches: []string{}, | ||
Options: []corev1.PodDNSConfigOption{ | ||
{ | ||
Name: "ndots", | ||
Value: pointer.String("1"), | ||
}, | ||
}, | ||
}, | ||
}, | ||
"one nameserver": { | ||
etcResolv: `nameserver 1.1.1.1`, | ||
expDNSConfig: &corev1.PodDNSConfig{ | ||
Nameservers: []string{"127.0.0.1", "1.1.1.1"}, | ||
Searches: []string{}, | ||
Options: []corev1.PodDNSConfigOption{ | ||
{ | ||
Name: "ndots", | ||
Value: pointer.String("1"), | ||
}, | ||
}, | ||
}, | ||
}, | ||
"mutiple nameservers, searches, and options": { | ||
etcResolv: ` | ||
nameserver 1.1.1.1 | ||
nameserver 2.2.2.2 | ||
search foo.bar bar.baz | ||
options ndots:5 timeout:6 attempts:3`, | ||
expDNSConfig: &corev1.PodDNSConfig{ | ||
Nameservers: []string{"127.0.0.1", "1.1.1.1", "2.2.2.2"}, | ||
Searches: []string{"foo.bar", "bar.baz"}, | ||
Options: []corev1.PodDNSConfigOption{ | ||
{ | ||
Name: "ndots", | ||
Value: pointer.String("5"), | ||
}, | ||
{ | ||
Name: "timeout", | ||
Value: pointer.String("6"), | ||
}, | ||
{ | ||
Name: "attempts", | ||
Value: pointer.String("3"), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for name, c := range cases { | ||
t.Run(name, func(t *testing.T) { | ||
etcResolvFile, err := os.CreateTemp("", "") | ||
require.NoError(t, err) | ||
t.Cleanup(func() { | ||
_ = os.Remove(etcResolvFile.Name()) | ||
}) | ||
_, err = etcResolvFile.WriteString(c.etcResolv) | ||
require.NoError(t, err) | ||
w := MeshWebhook{ | ||
etcResolvFile: etcResolvFile.Name(), | ||
} | ||
|
||
pod := minimal() | ||
err = w.configureDNS(pod) | ||
require.NoError(t, err) | ||
require.Equal(t, corev1.DNSNone, pod.Spec.DNSPolicy) | ||
require.Equal(t, c.expDNSConfig, pod.Spec.DNSConfig) | ||
}) | ||
} | ||
} | ||
|
||
func TestMeshWebhook_configureDNS_error(t *testing.T) { | ||
w := MeshWebhook{} | ||
|
||
pod := minimal() | ||
pod.Spec.DNSConfig = &corev1.PodDNSConfig{Nameservers: []string{"1.1.1.1"}} | ||
err := w.configureDNS(pod) | ||
require.EqualError(t, err, "DNS redirection to Consul is not supported with an already defined DNSConfig on the pod") | ||
} |
Oops, something went wrong.