Skip to content

Commit b65d602

Browse files
authored
Merge pull request #3464 from ceason/tunnel-dns
WIP: Resolve service FQDNs from host during 'minikube tunnel' (macOS)
2 parents 45439bb + 082fe50 commit b65d602

6 files changed

+88
-16
lines changed

pkg/minikube/tunnel/cluster_inspector.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/pkg/errors"
2727
"k8s.io/minikube/pkg/minikube/cluster"
2828
"k8s.io/minikube/pkg/minikube/config"
29+
"k8s.io/minikube/pkg/util"
2930
)
3031

3132
type clusterInspector struct {
@@ -93,9 +94,14 @@ func getRoute(host *host.Host, clusterConfig config.Config) (*Route, error) {
9394
if ip == nil {
9495
return nil, fmt.Errorf("invalid IP for host %s", hostDriverIP)
9596
}
96-
97+
dnsIp, err := util.GetDNSIP(ipNet.String())
98+
if err != nil {
99+
return nil, err
100+
}
97101
return &Route{
98-
Gateway: ip,
99-
DestCIDR: ipNet,
102+
Gateway: ip,
103+
DestCIDR: ipNet,
104+
ClusterDomain: clusterConfig.KubernetesConfig.DNSDomain,
105+
ClusterDNSIP: dnsIp,
100106
}, nil
101107
}

pkg/minikube/tunnel/cluster_inspector_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package tunnel
1818

1919
import (
20+
"k8s.io/minikube/pkg/util"
2021
"testing"
2122

2223
"net"
@@ -78,10 +79,12 @@ func TestMinikubeCheckReturnsHostInformation(t *testing.T) {
7879

7980
ip := net.ParseIP("1.2.3.4")
8081
_, ipNet, _ := net.ParseCIDR("96.0.0.0/12")
82+
dnsIp, _ := util.GetDNSIP(ipNet.String())
8183

8284
expectedRoute := &Route{
83-
Gateway: ip,
84-
DestCIDR: ipNet,
85+
Gateway: ip,
86+
DestCIDR: ipNet,
87+
ClusterDNSIP: dnsIp,
8588
}
8689

8790
if s != Running {

pkg/minikube/tunnel/route_darwin.go

+37
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ package tunnel
1818

1919
import (
2020
"fmt"
21+
"io/ioutil"
2122
"net"
23+
"os"
2224
"os/exec"
2325
"regexp"
2426
"strings"
@@ -34,6 +36,9 @@ func (router *osRouter) EnsureRouteIsAdded(route *Route) error {
3436
if exists {
3537
return nil
3638
}
39+
if err := writeResolverFile(route); err != nil {
40+
return fmt.Errorf("could not write /etc/resolver/{cluster_domain} file: %s", err)
41+
}
3742

3843
serviceCIDR := route.DestCIDR.String()
3944
gatewayIP := route.Gateway.String()
@@ -162,5 +167,37 @@ func (router *osRouter) Cleanup(route *Route) error {
162167
if !re.MatchString(message) {
163168
return fmt.Errorf("error deleting route: %s, %d", message, len(strings.Split(message, "\n")))
164169
}
170+
// idempotent removal of cluster domain dns
171+
resolverFile := fmt.Sprintf("/etc/resolver/%s", route.ClusterDomain)
172+
command = exec.Command("sudo", "rm", "-f", resolverFile)
173+
if err := command.Run(); err != nil {
174+
return fmt.Errorf("could not remove %s: %s", resolverFile, err)
175+
}
176+
return nil
177+
}
178+
179+
func writeResolverFile(route *Route) error {
180+
resolverFile := "/etc/resolver/" + route.ClusterDomain
181+
content := fmt.Sprintf("nameserver %s\nsearch_order 1\n", route.ClusterDNSIP)
182+
// write resolver content into tmpFile, then copy it to /etc/resolver/clusterDomain
183+
tmpFile, err := ioutil.TempFile("", "minikube-tunnel-resolver-")
184+
if err != nil {
185+
return err
186+
}
187+
defer os.Remove(tmpFile.Name())
188+
if _, err = tmpFile.WriteString(content); err != nil {
189+
return err
190+
}
191+
if err = tmpFile.Close(); err != nil {
192+
return err
193+
}
194+
command := exec.Command("sudo", "mkdir", "-p", "/etc/resolver")
195+
if err := command.Run(); err != nil {
196+
return err
197+
}
198+
command = exec.Command("sudo", "cp", "-f", tmpFile.Name(), resolverFile)
199+
if err := command.Run(); err != nil {
200+
return err
201+
}
165202
return nil
166203
}

pkg/minikube/tunnel/route_darwin_test.go

+28-7
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ func TestDarwinRouteFailsOnConflictIntegrationTest(t *testing.T) {
3535
IP: net.IPv4(10, 96, 0, 0),
3636
Mask: net.IPv4Mask(255, 240, 0, 0),
3737
},
38+
ClusterDomain: "cluster.local",
39+
ClusterDNSIP: net.IPv4(10, 96, 0, 10),
3840
}
41+
conflictingCfg := *cfg
42+
conflictingCfg.Gateway = net.IPv4(127, 0, 0, 2)
3943

40-
addRoute(t, "10.96.0.0/12", "127.0.0.2")
44+
addRoute(t, &conflictingCfg)
45+
defer cleanRoute(t, &conflictingCfg)
4146
err := (&osRouter{}).EnsureRouteIsAdded(cfg)
4247
if err == nil {
4348
t.Errorf("add should have error, but it is nil")
@@ -51,9 +56,11 @@ func TestDarwinRouteIdempotentIntegrationTest(t *testing.T) {
5156
IP: net.IPv4(10, 96, 0, 0),
5257
Mask: net.IPv4Mask(255, 240, 0, 0),
5358
},
59+
ClusterDomain: "cluster.local",
60+
ClusterDNSIP: net.IPv4(10, 96, 0, 10),
5461
}
5562

56-
cleanRoute(t, "10.96.0.0/12")
63+
cleanRoute(t, cfg)
5764
err := (&osRouter{}).EnsureRouteIsAdded(cfg)
5865
if err != nil {
5966
t.Errorf("add error: %s", err)
@@ -64,7 +71,7 @@ func TestDarwinRouteIdempotentIntegrationTest(t *testing.T) {
6471
t.Errorf("add error: %s", err)
6572
}
6673

67-
cleanRoute(t, "10.96.0.0/12")
74+
cleanRoute(t, cfg)
6875
}
6976

7077
func TestDarwinRouteCleanupIdempontentIntegrationTest(t *testing.T) {
@@ -75,10 +82,12 @@ func TestDarwinRouteCleanupIdempontentIntegrationTest(t *testing.T) {
7582
IP: net.IPv4(10, 96, 0, 0),
7683
Mask: net.IPv4Mask(255, 240, 0, 0),
7784
},
85+
ClusterDomain: "cluster.local",
86+
ClusterDNSIP: net.IPv4(10, 96, 0, 10),
7887
}
7988

80-
cleanRoute(t, "10.96.0.0/12")
81-
addRoute(t, "10.96.0.0/12", "192.168.1.1")
89+
cleanRoute(t, cfg)
90+
addRoute(t, cfg)
8291
err := (&osRouter{}).Cleanup(cfg)
8392
if err != nil {
8493
t.Errorf("cleanup failed with %s", err)
@@ -89,20 +98,32 @@ func TestDarwinRouteCleanupIdempontentIntegrationTest(t *testing.T) {
8998
}
9099
}
91100

92-
func addRoute(t *testing.T, cidr string, gw string) {
101+
func addRoute(t *testing.T, r *Route) {
102+
cidr := r.DestCIDR.String()
103+
gw := r.Gateway.String()
93104
command := exec.Command("sudo", "route", "-n", "add", cidr, gw)
94105
_, err := command.CombinedOutput()
95106
if err != nil {
96107
t.Logf("add route error (should be ok): %s", err)
97108
}
109+
err = writeResolverFile(r)
110+
if err != nil {
111+
t.Logf("add route DNS resolver error (should be ok): %s", err)
112+
}
98113
}
99114

100-
func cleanRoute(t *testing.T, cidr string) {
115+
func cleanRoute(t *testing.T, r *Route) {
116+
cidr := r.DestCIDR.String()
101117
command := exec.Command("sudo", "route", "-n", "delete", cidr)
102118
_, err := command.CombinedOutput()
103119
if err != nil {
104120
t.Logf("cleanup error (should be ok): %s", err)
105121
}
122+
command = exec.Command("sudo", "rm", "-f", fmt.Sprintf("/etc/resolver/%s", r.ClusterDomain))
123+
_, err = command.CombinedOutput()
124+
if err != nil {
125+
t.Logf("cleanup DNS resolver error (should be ok): %s", err)
126+
}
106127
}
107128

108129
func TestCIDRPadding(t *testing.T) {

pkg/minikube/tunnel/route_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package tunnel
1818

1919
import (
20+
"k8s.io/minikube/pkg/util"
2021
"net"
2122
"reflect"
2223
"testing"
@@ -130,10 +131,12 @@ got
130131
func unsafeParseRoute(gatewayIP string, destCIDR string) *Route {
131132
ip := net.ParseIP(gatewayIP)
132133
_, ipNet, _ := net.ParseCIDR(destCIDR)
134+
dnsIp, _ := util.GetDNSIP(ipNet.String())
133135

134136
expectedRoute := &Route{
135-
Gateway: ip,
136-
DestCIDR: ipNet,
137+
Gateway: ip,
138+
DestCIDR: ipNet,
139+
ClusterDNSIP: dnsIp,
137140
}
138141
return expectedRoute
139142
}

pkg/minikube/tunnel/types.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ func (t *Status) String() string {
6161

6262
// Route represents a route
6363
type Route struct {
64-
Gateway net.IP
65-
DestCIDR *net.IPNet
64+
Gateway net.IP
65+
DestCIDR *net.IPNet
66+
ClusterDomain string
67+
ClusterDNSIP net.IP
6668
}
6769

6870
func (r *Route) String() string {

0 commit comments

Comments
 (0)