Skip to content

Commit

Permalink
Allow kube-dns to load its configuration from a config map
Browse files Browse the repository at this point in the history
- Adds command line flags --config-map, --config-map-ns.
- Fixes 36194 (#36194)
- Update kube-dns yamls
- Update bazel (hack/update-bazel.sh)
- Update known command line flags
- Temporarily reference new kube-dns image (this will be fixed with
  a separate commit when the DNS image is created)
  • Loading branch information
bowei committed Nov 18, 2016
1 parent 8b13068 commit d94b2b7
Show file tree
Hide file tree
Showing 23 changed files with 1,205 additions and 134 deletions.
3 changes: 2 additions & 1 deletion cluster/addons/dns/skydns-rc.yaml.base
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ spec:
spec:
containers:
- name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.8
image: gcr.io/bowei-gke-dev/kubedns-amd64:testing
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
Expand Down Expand Up @@ -76,6 +76,7 @@ spec:
args:
- --domain=__PILLAR__DNS__DOMAIN__.
- --dns-port=10053
- --config-map=kube-dns
# This should be set to v=2 only after the new image (cut from 1.5) has
# been released, otherwise we will flood the logs.
- --v=0
Expand Down
3 changes: 2 additions & 1 deletion cluster/addons/dns/skydns-rc.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ spec:
spec:
containers:
- name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.8
image: gcr.io/bowei-gke-dev/kubedns-amd64:testing
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
Expand Down Expand Up @@ -76,6 +76,7 @@ spec:
args:
- --domain={{ pillar['dns_domain'] }}.
- --dns-port=10053
- --config-map=kube-dns
# This should be set to v=2 only after the new image (cut from 1.5) has
# been released, otherwise we will flood the logs.
- --v=0
Expand Down
3 changes: 2 additions & 1 deletion cluster/addons/dns/skydns-rc.yaml.sed
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ spec:
spec:
containers:
- name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.8
image: gcr.io/bowei-gke-dev/kubedns-amd64:testing
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
Expand Down Expand Up @@ -76,6 +76,7 @@ spec:
args:
- --domain=$DNS_DOMAIN.
- --dns-port=10053
- --config-map=kube-dns
# This should be set to v=2 only after the new image (cut from 1.5) has
# been released, otherwise we will flood the logs.
- --v=0
Expand Down
1 change: 1 addition & 0 deletions cmd/kube-dns/app/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ go_library(
"//pkg/client/restclient:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/dns:go_default_library",
"//pkg/dns/config:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/skynetservices/skydns/metrics",
"//vendor:github.com/skynetservices/skydns/server",
Expand Down
2 changes: 2 additions & 0 deletions cmd/kube-dns/app/options/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ go_library(
srcs = ["options.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/dns/federation:go_default_library",
"//pkg/util/validation:go_default_library",
"//vendor:github.com/spf13/pflag",
],
Expand Down
74 changes: 43 additions & 31 deletions cmd/kube-dns/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,44 @@ limitations under the License.
package options

import (
"net/url"
"os"

"fmt"
_ "net/http/pprof"
"net/url"
"os"
"strings"

"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api"
fed "k8s.io/kubernetes/pkg/dns/federation"
"k8s.io/kubernetes/pkg/util/validation"
)

type KubeDNSConfig struct {
ClusterDomain string
KubeConfigFile string
KubeMasterURL string

HealthzPort int
DNSBindAddress string
DNSPort int
// Federations maps federation names to their registered domain names.

Federations map[string]string

ConfigMapNs string
ConfigMap string
}

func NewKubeDNSConfig() *KubeDNSConfig {
return &KubeDNSConfig{
ClusterDomain: "cluster.local.",
KubeConfigFile: "",
KubeMasterURL: "",
HealthzPort: 8081,
DNSBindAddress: "0.0.0.0",
DNSPort: 53,
Federations: make(map[string]string),

Federations: make(map[string]string),

ConfigMapNs: api.NamespaceSystem,
ConfigMap: "", // default to using command line flags
}
}

Expand Down Expand Up @@ -107,25 +114,8 @@ type federationsVar struct {
nameDomainMap map[string]string
}

// Set deserializes the input string in the format
// "myfederation1=example.com,myfederation2=second.example.com,myfederation3=example.com"
// into a map of key-value pairs of federation names to domain names.
func (fv federationsVar) Set(keyVal string) error {
for _, val := range strings.Split(keyVal, ",") {
splits := strings.SplitN(strings.TrimSpace(val), "=", 2)
name := strings.TrimSpace(splits[0])
domain := strings.TrimSpace(splits[1])
if errs := validation.IsDNS1123Label(name); len(errs) != 0 {
return fmt.Errorf("%q not a valid federation name: %q", name, errs)
}
// The federation domain name need not strictly be domain names, we
// accept valid dns names with subdomain components.
if errs := validation.IsDNS1123Subdomain(domain); len(errs) != 0 {
return fmt.Errorf("%q not a valid domain name: %q", domain, errs)
}
fv.nameDomainMap[name] = domain
}
return nil
return fed.ParseFederationsFlag(keyVal, fv.nameDomainMap)
}

func (fv federationsVar) String() string {
Expand All @@ -141,11 +131,33 @@ func (fv federationsVar) Type() string {
}

func (s *KubeDNSConfig) AddFlags(fs *pflag.FlagSet) {
fs.Var(clusterDomainVar{&s.ClusterDomain}, "domain", "domain under which to create names")
fs.StringVar(&s.KubeConfigFile, "kubecfg-file", s.KubeConfigFile, "Location of kubecfg file for access to kubernetes master service; --kube-master-url overrides the URL part of this; if neither this nor --kube-master-url are provided, defaults to service account tokens")
fs.Var(kubeMasterURLVar{&s.KubeMasterURL}, "kube-master-url", "URL to reach kubernetes master. Env variables in this flag will be expanded.")
fs.IntVar(&s.HealthzPort, "healthz-port", s.HealthzPort, "port on which to serve a kube-dns HTTP readiness probe.")
fs.StringVar(&s.DNSBindAddress, "dns-bind-address", s.DNSBindAddress, "address on which to serve DNS requests.")
fs.Var(clusterDomainVar{&s.ClusterDomain}, "domain",
"domain under which to create names")

fs.StringVar(&s.KubeConfigFile, "kubecfg-file", s.KubeConfigFile,
"Location of kubecfg file for access to kubernetes master service;"+
" --kube-master-url overrides the URL part of this; if neither this nor"+
" --kube-master-url are provided, defaults to service account tokens")
fs.Var(kubeMasterURLVar{&s.KubeMasterURL}, "kube-master-url",
"URL to reach kubernetes master. Env variables in this flag will be expanded.")

fs.IntVar(&s.HealthzPort, "healthz-port", s.HealthzPort,
"port on which to serve a kube-dns HTTP readiness probe.")
fs.StringVar(&s.DNSBindAddress, "dns-bind-address", s.DNSBindAddress,
"address on which to serve DNS requests.")
fs.IntVar(&s.DNSPort, "dns-port", s.DNSPort, "port on which to serve DNS requests.")
fs.Var(federationsVar{s.Federations}, "federations", "a comma separated list of the federation names and their corresponding domain names to which this cluster belongs. Example: \"myfederation1=example.com,myfederation2=example2.com,myfederation3=example.com\"")

fs.Var(federationsVar{s.Federations}, "federations",
"a comma separated list of the federation names and their corresponding"+
" domain names to which this cluster belongs. Example:"+
" \"myfederation1=example.com,myfederation2=example2.com,myfederation3=example.com\"."+
" It is an error to set both the federations and config-map flags.")
fs.MarkDeprecated("federations", "use config-map instead. Will be removed in future version")

fs.StringVar(&s.ConfigMapNs, "config-map-namespace", s.ConfigMapNs,
"namespace for the config-map")
fs.StringVar(&s.ConfigMap, "config-map", s.ConfigMap,
"config-map name. If empty, then the config-map will not used. Cannot be "+
" used in conjunction with federations flag. config-map contains "+
"dynamically adjustable configuration.")
}
19 changes: 16 additions & 3 deletions cmd/kube-dns/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/client/restclient"
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
kdns "k8s.io/kubernetes/pkg/dns"
dnsConfig "k8s.io/kubernetes/pkg/dns/config"
)

type KubeDNSServer struct {
Expand All @@ -52,13 +53,25 @@ func NewKubeDNSServerDefault(config *options.KubeDNSConfig) *KubeDNSServer {
if err != nil {
glog.Fatalf("Failed to create a kubernetes client: %v", err)
}

ks.healthzPort = config.HealthzPort
ks.dnsBindAddress = config.DNSBindAddress
ks.dnsPort = config.DNSPort
ks.kd, err = kdns.NewKubeDNS(kubeClient, config.ClusterDomain, config.Federations)
if err != nil {
glog.Fatalf("Failed to start kubeDNS: %v", err)

var configSync dnsConfig.Sync
if config.ConfigMap == "" {
glog.V(0).Infof("ConfigMap not configured, using values from command line flags")
configSync = dnsConfig.NewNopSync(
&dnsConfig.Config{Federations: config.Federations})
} else {
glog.V(0).Infof("Using configuration read from ConfigMap: %v:%v",
config.ConfigMapNs, config.ConfigMap)
configSync = dnsConfig.NewSync(
kubeClient, config.ConfigMapNs, config.ConfigMap)
}

ks.kd = kdns.NewKubeDNS(kubeClient, config.ClusterDomain, configSync)

return &ks
}

Expand Down
2 changes: 2 additions & 0 deletions hack/verify-flags/known-flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ concurrent-replicaset-syncs
concurrent-resource-quota-syncs
concurrent-serviceaccount-token-syncs
concurrent-service-syncs
config-map
config-map-namespace
config-sync-period
configure-cloud-routes
conntrack-max
Expand Down
2 changes: 2 additions & 0 deletions pkg/dns/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ go_library(
"//pkg/api/unversioned:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/dns/config:go_default_library",
"//pkg/dns/treecache:go_default_library",
"//pkg/dns/util:go_default_library",
"//pkg/runtime:go_default_library",
Expand All @@ -47,6 +48,7 @@ go_test(
"//pkg/api/unversioned:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/dns/config:go_default_library",
"//pkg/dns/treecache:go_default_library",
"//pkg/dns/util:go_default_library",
"//pkg/util/sets:go_default_library",
Expand Down
42 changes: 42 additions & 0 deletions pkg/dns/config/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])

licenses(["notice"])

load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)

go_library(
name = "go_default_library",
srcs = [
"config.go",
"mocksync.go",
"nopsync.go",
"sync.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/dns/federation:go_default_library",
"//pkg/fields:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/watch:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/client-go/pkg/util/wait",
],
)

go_test(
name = "go_default_test",
srcs = ["config_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = ["//vendor:github.com/stretchr/testify/assert"],
)
65 changes: 65 additions & 0 deletions pkg/dns/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
types "k8s.io/kubernetes/pkg/api/unversioned"
fed "k8s.io/kubernetes/pkg/dns/federation"
)

// Config populated either from the configuration source (command
// line flags or via the config map mechanism).
type Config struct {
// The inclusion of TypeMeta is to ensure future compatibility if the
// Config object was populated directly via a Kubernetes API mechanism.
//
// For example, instead of the custom implementation here, the
// configuration could be obtained from an API that unifies
// command-line flags, config-map, etc mechanisms.
types.TypeMeta

// Map of federation names that the cluster in which this kube-dns
// is running belongs to, to the corresponding domain names.
Federations map[string]string `json:"federations"`
}

func NewDefaultConfig() *Config {
return &Config{
Federations: make(map[string]string),
}
}

// IsValid returns whether or not the configuration is valid.
func (config *Config) Validate() error {
if err := config.validateFederations(); err != nil {
return err
}

return nil
}

func (config *Config) validateFederations() error {
for name, domain := range config.Federations {
if err := fed.ValidateName(name); err != nil {
return err
}
if err := fed.ValidateDomain(domain); err != nil {
return err
}
}
return nil
}
Loading

0 comments on commit d94b2b7

Please sign in to comment.