diff --git a/cmd/kubeadm/app/cmd/phases/addons.go b/cmd/kubeadm/app/cmd/phases/addons.go index da71b0ac9c1..098df6dfa41 100644 --- a/cmd/kubeadm/app/cmd/phases/addons.go +++ b/cmd/kubeadm/app/cmd/phases/addons.go @@ -116,6 +116,7 @@ func getAddonsSubCommands() []*cobra.Command { if properties.use == "all" || properties.use == "kube-dns" { cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, `Use alternative domain for services, e.g. "myorg.internal.`) + cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, `Use alternative range of IP address for service VIPs`) } subCmds = append(subCmds, cmd) } diff --git a/cmd/kubeadm/app/cmd/phases/addons_test.go b/cmd/kubeadm/app/cmd/phases/addons_test.go index ca2e614d113..424e319081e 100644 --- a/cmd/kubeadm/app/cmd/phases/addons_test.go +++ b/cmd/kubeadm/app/cmd/phases/addons_test.go @@ -47,6 +47,7 @@ func TestAddonsSubCommandsHasFlags(t *testing.T) { "apiserver-bind-port", "pod-network-cidr", "service-dns-domain", + "service-cidr", }, }, { @@ -61,6 +62,7 @@ func TestAddonsSubCommandsHasFlags(t *testing.T) { command: "kube-dns", additionalFlags: []string{ "service-dns-domain", + "service-cidr", }, }, } diff --git a/cmd/kubeadm/app/phases/addons/dns/BUILD b/cmd/kubeadm/app/phases/addons/dns/BUILD index bb0f1d4f5df..ba7086d154f 100644 --- a/cmd/kubeadm/app/phases/addons/dns/BUILD +++ b/cmd/kubeadm/app/phases/addons/dns/BUILD @@ -41,6 +41,7 @@ go_library( "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", "//pkg/api/legacyscheme:go_default_library", + "//pkg/registry/core/service/ipallocator:go_default_library", "//pkg/util/version:go_default_library", "//vendor/k8s.io/api/apps/v1beta2:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", diff --git a/cmd/kubeadm/app/phases/addons/dns/dns.go b/cmd/kubeadm/app/phases/addons/dns/dns.go index 0be3a4ed740..314b7e0da1a 100644 --- a/cmd/kubeadm/app/phases/addons/dns/dns.go +++ b/cmd/kubeadm/app/phases/addons/dns/dns.go @@ -34,6 +34,7 @@ import ( kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" "k8s.io/kubernetes/pkg/util/version" ) @@ -59,7 +60,7 @@ func kubeDNSAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Interfac return err } - dnsip, err := getDNSIP(client) + dnsip, err := GetDNSIP(cfg.Networking.ServiceSubnet) if err != nil { return err } @@ -148,7 +149,7 @@ func coreDNSAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Interfac return fmt.Errorf("error when parsing CoreDNS configMap template: %v", err) } - dnsip, err := getDNSIP(client) + dnsip, err := GetDNSIP(cfg.Networking.ServiceSubnet) if err != nil { return err } @@ -244,21 +245,20 @@ func createDNSService(dnsService *v1.Service, serviceBytes []byte, client client return nil } -// getDNSIP fetches the kubernetes service's ClusterIP and appends a "0" to it in order to get the DNS IP -func getDNSIP(client clientset.Interface) (net.IP, error) { - k8ssvc, err := client.CoreV1().Services(metav1.NamespaceDefault).Get("kubernetes", metav1.GetOptions{}) +// GetDNSIP returns a dnsIP, which is 10th IP in svcSubnet CIDR range +func GetDNSIP(svcSubnet string) (net.IP, error) { + + // Get the service subnet CIDR + _, svcSubnetCIDR, err := net.ParseCIDR(svcSubnet) if err != nil { - return nil, fmt.Errorf("couldn't fetch information about the kubernetes service: %v", err) + return nil, fmt.Errorf("couldn't parse service subnet CIDR %q: %v", svcSubnet, err) } - if len(k8ssvc.Spec.ClusterIP) == 0 { - return nil, fmt.Errorf("couldn't fetch a valid clusterIP from the kubernetes service") + // Selects the 10th IP in service subnet CIDR range as dnsIP + dnsIP, err := ipallocator.GetIndexedIP(svcSubnetCIDR, 10) + if err != nil { + return nil, fmt.Errorf("unable to get tenth IP address from service subnet CIDR %s: %v", svcSubnetCIDR.String(), err) } - // Build an IP by taking the kubernetes service's clusterIP and appending a "0" and checking that it's valid - dnsIP := net.ParseIP(fmt.Sprintf("%s0", k8ssvc.Spec.ClusterIP)) - if dnsIP == nil { - return nil, fmt.Errorf("could not parse dns ip %q: %v", dnsIP, err) - } return dnsIP, nil } diff --git a/cmd/kubeadm/app/phases/addons/dns/dns_test.go b/cmd/kubeadm/app/phases/addons/dns/dns_test.go index 23dde4ec7db..92341e26ef4 100644 --- a/cmd/kubeadm/app/phases/addons/dns/dns_test.go +++ b/cmd/kubeadm/app/phases/addons/dns/dns_test.go @@ -144,3 +144,33 @@ func TestCompileManifests(t *testing.T) { } } } + +func TestGetDNSIP(t *testing.T) { + var tests = []struct { + svcSubnet, expectedDNSIP string + }{ + { + svcSubnet: "10.96.0.0/12", + expectedDNSIP: "10.96.0.10", + }, + { + svcSubnet: "10.87.116.64/26", + expectedDNSIP: "10.87.116.74", + }, + } + for _, rt := range tests { + dnsIP, err := GetDNSIP(rt.svcSubnet) + if err != nil { + t.Fatalf("couldn't get dnsIP : %v", err) + } + + actualDNSIP := dnsIP.String() + if actualDNSIP != rt.expectedDNSIP { + t.Errorf( + "failed GetDNSIP\n\texpected: %s\n\t actual: %s", + rt.expectedDNSIP, + actualDNSIP, + ) + } + } +}