From 3ddb4e30b3b7eba181b5c2081ef1cccec050722a Mon Sep 17 00:00:00 2001 From: Predrag Rogic Date: Thu, 13 May 2021 18:28:16 +0100 Subject: [PATCH] add host.minikube.internal to coredns --- pkg/minikube/node/start.go | 21 +++++++++++++++++++++ test/integration/multinode_test.go | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index e5ae1f56ff..0480725d16 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -21,6 +21,7 @@ import ( "net" "os" "os/exec" + "path" "strconv" "strings" "sync" @@ -60,6 +61,7 @@ import ( "k8s.io/minikube/pkg/minikube/proxy" "k8s.io/minikube/pkg/minikube/reason" "k8s.io/minikube/pkg/minikube/style" + "k8s.io/minikube/pkg/minikube/vmpath" "k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util/retry" ) @@ -131,6 +133,10 @@ func Start(starter Starter, apiServer bool) (*kubeconfig.Settings, error) { if err := kapi.ScaleDeployment(starter.Cfg.Name, meta.NamespaceSystem, kconst.CoreDNSDeploymentName, 1); err != nil { klog.Errorf("Unable to scale down deployment %q in namespace %q to 1 replica: %v", kconst.CoreDNSDeploymentName, meta.NamespaceSystem, err) } + // inject {"host.minikube.internal": hostIP} record into CoreDNS + if err := updateCoreDNS(starter.Runner, "host.minikube.internal", hostIP.String(), *starter.Cfg); err != nil { + klog.Errorf("Unable to inject {%q: %s} record into CoreDNS: %v", "host.minikube.internal", hostIP.String(), err) + } } else { bs, err = cluster.Bootstrapper(starter.MachineAPI, viper.GetString(cmdcfg.Bootstrapper), *starter.Cfg, starter.Runner) if err != nil { @@ -669,3 +675,18 @@ func prepareNone() { exit.Message(reason.HostHomeChown, "Failed to change permissions for {{.minikube_dir_path}}: {{.error}}", out.V{"minikube_dir_path": localpath.MiniPath(), "error": err}) } } + +// updateCoreDNS adds host name and IP record to the DNS by updating CoreDNS's ConfigMap. +// ref: https://coredns.io/plugins/hosts/ +func updateCoreDNS(runner command.Runner, name, ip string, cc config.ClusterConfig) error { + kubectl := kapi.KubectlBinaryPath(cc.KubernetesConfig.KubernetesVersion) + kubecfg := path.Join(vmpath.GuestPersistentDir, "kubeconfig") + cur := fmt.Sprintf("sudo %s --kubeconfig=%s -n kube-system get configmap coredns -o yaml", kubectl, kubecfg) + sed := fmt.Sprintf("sed '/^ forward . \\/etc\\/resolv.conf.*/i \\ hosts {\\n %s %s\\n fallthrough\\n }'", ip, name) + new := fmt.Sprintf("sudo %s --kubeconfig=%s replace -f -", kubectl, kubecfg) + _, err := runner.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s | %s | %s", cur, sed, new))) + if err == nil { + klog.Infof("{%q: %s} record injected into CoreDNS", name, ip) + } + return err +} diff --git a/test/integration/multinode_test.go b/test/integration/multinode_test.go index 897b432e6d..1de08025e7 100644 --- a/test/integration/multinode_test.go +++ b/test/integration/multinode_test.go @@ -464,6 +464,7 @@ func validateDeployAppToMultiNode(ctx context.Context, t *testing.T, profile str t.Errorf("Pod %s could not resolve 'kubernetes.io': %v", name, err) } } + // verify both Pods could resolve "kubernetes.default" // this one is also checked by k8s e2e node conformance tests: // https://github.com/kubernetes/kubernetes/blob/f137c4777095b3972e2dd71a01365d47be459389/test/e2e_node/environment/conformance.go#L125-L179 @@ -473,6 +474,7 @@ func validateDeployAppToMultiNode(ctx context.Context, t *testing.T, profile str t.Errorf("Pod %s could not resolve 'kubernetes.default': %v", name, err) } } + // verify both pods could resolve to a local service. for _, name := range podNames { _, err = Run(t, exec.CommandContext(ctx, Target(), "kubectl", "-p", profile, "--", "exec", name, "--", "nslookup", "kubernetes.default.svc.cluster.local")) @@ -480,4 +482,24 @@ func validateDeployAppToMultiNode(ctx context.Context, t *testing.T, profile str t.Errorf("Pod %s could not resolve local service (kubernetes.default.svc.cluster.local): %v", name, err) } } + + // verify both pods could resolve "host.minikube.internal" + for _, name := range podNames { + // get node's default gateway via 'ip' - eg: "default via 192.168.49.1 dev eth0" => "192.168.49.1" + out, err := Run(t, exec.CommandContext(ctx, Target(), "ssh", "-p", profile, "ip -4 route show default | cut -d' ' -f3")) + if err != nil { + t.Errorf("Error getting default gateway for pod %s: %v", name, err) + } else { + dgw := strings.TrimSpace(out.Stdout.String()) + out, err = Run(t, exec.CommandContext(ctx, Target(), "kubectl", "-p", profile, "--", "exec", name, "--", "sh", "-c", "nslookup host.minikube.internal | awk 'NR==5' | cut -d' ' -f3")) + if err != nil { + t.Errorf("Pod %s could not resolve 'host.minikube.internal': %v", name, err) + } else { + hip := strings.TrimSpace(out.Stdout.String()) + if hip != dgw { + t.Errorf("Pod %s resolved 'host.minikube.internal' to %q different from host's IP (%s)", name, hip, dgw) + } + } + } + } }