From c57f20b712919e86637170a6f3ab44d2e5cc75a1 Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Mon, 13 May 2019 21:04:14 -0700 Subject: [PATCH] tests: Replaces dnsutils image used with agnhost (part 4) Quite a few images are only used a few times in a few tests. Thus, the images are being centralized into the agnhost image, reducing the number of images that have to be pulled and used. This PR replaces the usage of the following images with agnhost: - dnsutils dnsmasq is a Linux specific binary. In order for the tests to also pass on Windows, CoreDNS should be used instead. --- test/e2e/network/dns.go | 16 +++- test/e2e/network/dns_common.go | 121 +++++++++++++++++------------- test/e2e/network/dns_configmap.go | 10 +-- test/e2e/windows/dns.go | 2 +- test/utils/image/manifest.go | 4 +- 5 files changed, 88 insertions(+), 65 deletions(-) diff --git a/test/e2e/network/dns.go b/test/e2e/network/dns.go index 664e8c2c860..81df6aed721 100644 --- a/test/e2e/network/dns.go +++ b/test/e2e/network/dns.go @@ -460,10 +460,20 @@ var _ = SIGDescribe("DNS", func() { testSearchPath := "resolv.conf.local" testDNSNameFull := fmt.Sprintf("%s.%s", testDNSNameShort, testSearchPath) - testServerPod := generateDNSServerPod(map[string]string{ + corednsConfig := generateCoreDNSConfigmap(f.Namespace.Name, map[string]string{ testDNSNameFull: testInjectedIP, }) - testServerPod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), testServerPod, metav1.CreateOptions{}) + corednsConfig, err := f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(context.TODO(), corednsConfig, metav1.CreateOptions{}) + framework.ExpectNoError(err, "unable to create test configMap %s", corednsConfig.Name) + + defer func() { + framework.Logf("Deleting configmap %s...", corednsConfig.Name) + err := f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Delete(context.TODO(), corednsConfig.Name, nil) + framework.ExpectNoError(err, "Failed to delete configmap %s: %v", corednsConfig.Name) + }() + + testServerPod := generateCoreDNSServerPod(corednsConfig) + testServerPod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), testServerPod, metav1.CreateOptions{}) framework.ExpectNoError(err, "failed to create pod: %s", testServerPod.Name) framework.Logf("Created pod %v", testServerPod) defer func() { @@ -528,7 +538,7 @@ var _ = SIGDescribe("DNS", func() { // This verifies both: // - Custom search path is appended. // - DNS query is sent to the specified server. - cmd = []string{"/usr/bin/dig", "+short", "+search", testDNSNameShort} + cmd = []string{"dig", "+short", "+search", testDNSNameShort} digFunc := func() (bool, error) { stdout, stderr, err := f.ExecWithOptions(framework.ExecOptions{ Command: cmd, diff --git a/test/e2e/network/dns_common.go b/test/e2e/network/dns_common.go index f5052d8ec37..82204067bb8 100644 --- a/test/e2e/network/dns_common.go +++ b/test/e2e/network/dns_common.go @@ -19,6 +19,7 @@ package network import ( "context" "fmt" + "regexp" "strings" "time" @@ -40,6 +41,9 @@ import ( "github.com/onsi/gomega" ) +// Windows output can contain additional \r +var newLineRegexp = regexp.MustCompile("\r?\n") + type dnsTestCommon struct { f *framework.Framework c clientset.Interface @@ -104,7 +108,7 @@ func (t *dnsTestCommon) checkDNSRecordFrom(name string, predicate func([]string) // runDig queries for `dnsName`. Returns a list of responses. func (t *dnsTestCommon) runDig(dnsName, target string) []string { - cmd := []string{"/usr/bin/dig", "+short"} + cmd := []string{"dig", "+short"} switch target { case "coredns": cmd = append(cmd, "@"+t.dnsPod.Status.PodIP) @@ -135,7 +139,7 @@ func (t *dnsTestCommon) runDig(dnsName, target string) []string { if stdout == "" { return []string{} } - return strings.Split(stdout, "\n") + return newLineRegexp.Split(stdout, -1) } func (t *dnsTestCommon) setConfigMap(cm *v1.ConfigMap) { @@ -208,7 +212,7 @@ func (t *dnsTestCommon) createUtilPodLabel(baseName string) { Containers: []v1.Container{ { Name: "util", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), + Image: imageutils.GetE2EImage(imageutils.Agnhost), Command: []string{"sleep", "10000"}, Ports: []v1.ContainerPort{ {ContainerPort: servicePort, Protocol: v1.ProtocolTCP}, @@ -274,8 +278,8 @@ func (t *dnsTestCommon) deleteCoreDNSPods() { } } -func generateDNSServerPod(aRecords map[string]string) *v1.Pod { - pod := &v1.Pod{ +func generateCoreDNSServerPod(corednsConfig *v1.ConfigMap) *v1.Pod { + return &v1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", }, @@ -283,29 +287,61 @@ func generateDNSServerPod(aRecords map[string]string) *v1.Pod { GenerateName: "e2e-dns-configmap-dns-server-", }, Spec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: "coredns-config", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: corednsConfig.Name, + }, + }, + }, + }, + }, Containers: []v1.Container{ { Name: "dns", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), + Image: imageutils.GetE2EImage(imageutils.Agnhost), Command: []string{ - "/usr/sbin/dnsmasq", - "-u", "root", - "-k", - "--log-facility", "-", - "-q", + "/coredns", + "-conf", "/etc/coredns/Corefile", + }, + VolumeMounts: []v1.VolumeMount{ + { + Name: "coredns-config", + MountPath: "/etc/coredns", + ReadOnly: true, + }, }, }, }, DNSPolicy: "Default", }, } +} +func generateCoreDNSConfigmap(namespaceName string, aRecords map[string]string) *v1.ConfigMap { + entries := "" for name, ip := range aRecords { - pod.Spec.Containers[0].Command = append( - pod.Spec.Containers[0].Command, - fmt.Sprintf("-A/%v/%v", name, ip)) + entries += fmt.Sprintf("\n\t\t%v %v", ip, name) + } + + corefileData := fmt.Sprintf(`. { + hosts {%s + } + log +}`, entries) + + return &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespaceName, + GenerateName: "e2e-coredns-configmap-", + }, + Data: map[string]string{ + "Corefile": corefileData, + }, } - return pod } func (t *dnsTestCommon) createDNSPodFromObj(pod *v1.Pod) { @@ -322,47 +358,26 @@ func (t *dnsTestCommon) createDNSPodFromObj(pod *v1.Pod) { framework.ExpectNoError(err, "failed to get pod: %s", t.dnsServerPod.Name) } -func (t *dnsTestCommon) createDNSServer(aRecords map[string]string) { - t.createDNSPodFromObj(generateDNSServerPod(aRecords)) +func (t *dnsTestCommon) createDNSServer(namespace string, aRecords map[string]string) { + corednsConfig := generateCoreDNSConfigmap(namespace, aRecords) + corednsConfig, err := t.c.CoreV1().ConfigMaps(namespace).Create(context.TODO(), corednsConfig, metav1.CreateOptions{}) + if err != nil { + framework.Failf("unable to create test configMap %s: %v", corednsConfig.Name, err) + } + + t.createDNSPodFromObj(generateCoreDNSServerPod(corednsConfig)) } -func (t *dnsTestCommon) createDNSServerWithPtrRecord(isIPv6 bool) { - pod := &v1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - }, - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "e2e-dns-configmap-dns-server-", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "dns", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), - Command: []string{ - "/usr/sbin/dnsmasq", - "-u", "root", - "-k", - "--log-facility", "-", - "-q", - }, - }, - }, - DNSPolicy: "Default", - }, - } - +func (t *dnsTestCommon) createDNSServerWithPtrRecord(namespace string, isIPv6 bool) { + // NOTE: PTR records are generated automatically by CoreDNS. So, if we're creating A records, we're + // going to also have PTR records. See: https://coredns.io/plugins/hosts/ + var aRecords map[string]string if isIPv6 { - pod.Spec.Containers[0].Command = append( - pod.Spec.Containers[0].Command, - fmt.Sprintf("--host-record=my.test,2001:db8::29")) + aRecords = map[string]string{"my.test": "2001:db8::29"} } else { - pod.Spec.Containers[0].Command = append( - pod.Spec.Containers[0].Command, - fmt.Sprintf("--host-record=my.test,192.0.2.123")) + aRecords = map[string]string{"my.test": "192.0.2.123"} } - - t.createDNSPodFromObj(pod) + t.createDNSServer(namespace, aRecords) } func (t *dnsTestCommon) deleteDNSServerPod() { @@ -413,7 +428,7 @@ func createDNSPod(namespace, wheezyProbeCmd, jessieProbeCmd, podHostName, servic }, { Name: "querier", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), + Image: imageutils.GetE2EImage(imageutils.Agnhost), Command: []string{"sh", "-c", wheezyProbeCmd}, VolumeMounts: []v1.VolumeMount{ { @@ -622,7 +637,7 @@ func generateDNSUtilsPod() *v1.Pod { Containers: []v1.Container{ { Name: "util", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), + Image: imageutils.GetE2EImage(imageutils.Agnhost), Command: []string{"sleep", "10000"}, }, }, diff --git a/test/e2e/network/dns_configmap.go b/test/e2e/network/dns_configmap.go index 7f49bf69edc..ed8593a5026 100644 --- a/test/e2e/network/dns_configmap.go +++ b/test/e2e/network/dns_configmap.go @@ -221,13 +221,13 @@ func (t *dnsNameserverTest) run(isIPv6 bool) { defer t.restoreDNSConfigMap(originalConfigMapData) if isIPv6 { - t.createDNSServer(map[string]string{ + t.createDNSServer(t.f.Namespace.Name, map[string]string{ "abc.acme.local": "2606:4700:4700::1111", "def.acme.local": "2606:4700:4700::2222", "widget.local": "2606:4700:4700::3333", }) } else { - t.createDNSServer(map[string]string{ + t.createDNSServer(t.f.Namespace.Name, map[string]string{ "abc.acme.local": "1.1.1.1", "def.acme.local": "2.2.2.2", "widget.local": "3.3.3.3", @@ -317,7 +317,7 @@ func (t *dnsPtrFwdTest) run(isIPv6 bool) { originalConfigMapData := t.fetchDNSConfigMapData() defer t.restoreDNSConfigMap(originalConfigMapData) - t.createDNSServerWithPtrRecord(isIPv6) + t.createDNSServerWithPtrRecord(t.f.Namespace.Name, isIPv6) defer t.deleteDNSServerPod() // Should still be able to lookup public nameserver without explicit upstream nameserver set. @@ -401,11 +401,11 @@ func (t *dnsExternalNameTest) run(isIPv6 bool) { fooHostname := "foo.example.com" if isIPv6 { - t.createDNSServer(map[string]string{ + t.createDNSServer(t.f.Namespace.Name, map[string]string{ fooHostname: "2001:db8::29", }) } else { - t.createDNSServer(map[string]string{ + t.createDNSServer(t.f.Namespace.Name, map[string]string{ fooHostname: "192.0.2.123", }) } diff --git a/test/e2e/windows/dns.go b/test/e2e/windows/dns.go index 1594122d65b..a05309e32d6 100644 --- a/test/e2e/windows/dns.go +++ b/test/e2e/windows/dns.go @@ -102,7 +102,7 @@ func generateDNSUtilsPod() *v1.Pod { Containers: []v1.Container{ { Name: "util", - Image: imageutils.GetE2EImage(imageutils.Dnsutils), + Image: imageutils.GetE2EImage(imageutils.Agnhost), Command: []string{"sleep", "10000"}, }, }, diff --git a/test/utils/image/manifest.go b/test/utils/image/manifest.go index 9021cbe5f6d..bc780e6f1ae 100644 --- a/test/utils/image/manifest.go +++ b/test/utils/image/manifest.go @@ -70,6 +70,7 @@ func initReg() RegistryList { DockerLibraryRegistry: "docker.io/library", DockerGluster: "docker.io/gluster", E2eRegistry: "gcr.io/kubernetes-e2e-test-images", + // TODO: After the domain flip, this should instead be k8s.gcr.io/k8s-artifacts-prod/e2e-test-images PromoterE2eRegistry: "us.gcr.io/k8s-artifacts-prod/e2e-test-images", InvalidRegistry: "invalid.com/invalid", GcRegistry: "k8s.gcr.io", @@ -139,8 +140,6 @@ const ( CudaVectorAdd // CudaVectorAdd2 image CudaVectorAdd2 - // Dnsutils image - Dnsutils // EchoServer image EchoServer // Etcd image @@ -216,7 +215,6 @@ func initImageConfigs() map[int]Config { configs[CheckMetadataConcealment] = Config{e2eRegistry, "metadata-concealment", "1.2"} configs[CudaVectorAdd] = Config{e2eRegistry, "cuda-vector-add", "1.0"} configs[CudaVectorAdd2] = Config{e2eRegistry, "cuda-vector-add", "2.0"} - configs[Dnsutils] = Config{e2eRegistry, "dnsutils", "1.1"} configs[EchoServer] = Config{e2eRegistry, "echoserver", "2.2"} configs[Etcd] = Config{gcRegistry, "etcd", "3.4.3"} configs[GlusterDynamicProvisioner] = Config{dockerGluster, "glusterdynamic-provisioner", "v1.0"}