Enable CoreDNS in nodeup/protokube (#6)

* Enable CoreDNS in nodeup/protokube.

* Address comments.
This commit is contained in:
Miao Luo 2017-03-23 11:43:36 -07:00
parent 22e0ce3775
commit 6b010c4c5e
6 changed files with 96 additions and 33 deletions

View File

@ -30,6 +30,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
_ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53"
_ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns"
_ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns"
)
@ -47,7 +48,7 @@ func main() {
glog.Flush()
dnsProviderId := "aws-route53"
flags.StringVar(&dnsProviderId, "dns", dnsProviderId, "DNS provider we should use (aws-route53, google-clouddns)")
flags.StringVar(&dnsProviderId, "dns", dnsProviderId, "DNS provider we should use (aws-route53, google-clouddns, coredns)")
var zones []string
flags.StringSliceVarP(&zones, "zone", "z", []string{}, "Configure permitted zones and their mappings")
@ -96,7 +97,7 @@ func main() {
os.Exit(1)
}
dnsController, err := dns.NewDNSController(dnsProvider, zoneRules)
dnsController, err := dns.NewDNSController(dnsProvider, zoneRules, dnsProviderId)
if err != nil {
glog.Errorf("Error building DNS controller: %v", err)
os.Exit(1)

View File

@ -29,6 +29,7 @@ import (
"k8s.io/kops/dns-controller/pkg/util"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns"
"k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype"
)
@ -54,6 +55,9 @@ type DNSController struct {
// changeCount is a change-counter, which helps us avoid computation when nothing has changed
changeCount uint64
//DNS Provider ID, one of aws-route53, google-clouddns, and coredns
dnsProviderId string
}
// DNSController is a Context
@ -80,16 +84,17 @@ type DNSControllerScope struct {
var _ Scope = &DNSControllerScope{}
// NewDnsController creates a DnsController
func NewDNSController(dnsProvider dnsprovider.Interface, zoneRules *ZoneRules) (*DNSController, error) {
func NewDNSController(dnsProvider dnsprovider.Interface, zoneRules *ZoneRules, dnsProviderId string) (*DNSController, error) {
dnsCache, err := newDNSCache(dnsProvider)
if err != nil {
return nil, fmt.Errorf("error initializing DNS cache: %v", err)
}
c := &DNSController{
scopes: make(map[string]*DNSControllerScope),
zoneRules: zoneRules,
dnsCache: dnsCache,
scopes: make(map[string]*DNSControllerScope),
zoneRules: zoneRules,
dnsCache: dnsCache,
dnsProviderId: dnsProviderId,
}
return c, nil
@ -273,7 +278,7 @@ func (c *DNSController) runOnce() error {
dedup = append(dedup, s)
}
err := op.updateRecords(k, dedup, int64(ttl.Seconds()))
err := op.updateRecords(k, newValues, int64(ttl.Seconds()), c.dnsProviderId)
if err != nil {
glog.Infof("error updating records for %s: %v", k, err)
errors = append(errors, err)
@ -288,7 +293,7 @@ func (c *DNSController) runOnce() error {
newValues := newValueMap[k]
if newValues == nil {
err := op.deleteRecords(k)
err := op.deleteRecords(k, c.dnsProviderId)
if err != nil {
glog.Infof("error deleting records for %s: %v", k, err)
errors = append(errors, err)
@ -430,7 +435,7 @@ func (o *dnsOp) listRecords(zone dnsprovider.Zone) ([]dnsprovider.ResourceRecord
return rrs, nil
}
func (o *dnsOp) deleteRecords(k recordKey) error {
func (o *dnsOp) deleteRecords(k recordKey, dnsProviderId string) error {
glog.V(2).Infof("Deleting all records for %s", k)
fqdn := EnsureDotSuffix(k.FQDN)
@ -441,6 +446,31 @@ func (o *dnsOp) deleteRecords(k recordKey) error {
return fmt.Errorf("no suitable zone found for %q", fqdn)
}
// TODO: work-around before ResourceRecordSets.List() is implemented for CoreDNS
if dnsProviderId == k8scoredns.ProviderName {
rrsProvider, ok := zone.ResourceRecordSets()
if !ok {
return fmt.Errorf("zone does not support resource records %q", zone.Name())
}
dnsRecord, err := rrsProvider.Get(fqdn)
if err != nil {
return fmt.Errorf("Failed to get DNS record %s with error: %v", fqdn, err)
}
if dnsRecord != nil && string(dnsRecord.Type()) == string(k.RecordType) {
glog.V(8).Infof("Found matching record: %s %s", k.RecordType, fqdn)
cs, err := o.getChangeset(zone)
if err != nil {
return err
}
cs.Remove(dnsRecord)
}
return nil
}
// when DNS provider is aws-route53 or google-clouddns
rrs, err := o.listRecords(zone)
if err != nil {
return fmt.Errorf("error querying resource records for zone %q: %v", zone.Name(), err)
@ -469,7 +499,7 @@ func (o *dnsOp) deleteRecords(k recordKey) error {
return nil
}
func (o *dnsOp) updateRecords(k recordKey, newRecords []string, ttl int64) error {
func (o *dnsOp) updateRecords(k recordKey, newRecords []string, ttl int64, dnsProviderId string) error {
fqdn := EnsureDotSuffix(k.FQDN)
zone := o.findZone(fqdn)
@ -483,29 +513,42 @@ func (o *dnsOp) updateRecords(k recordKey, newRecords []string, ttl int64) error
return fmt.Errorf("zone does not support resource records %q", zone.Name())
}
rrs, err := o.listRecords(zone)
if err != nil {
return fmt.Errorf("error querying resource records for zone %q: %v", zone.Name(), err)
}
var existing dnsprovider.ResourceRecordSet
for _, rr := range rrs {
rrName := EnsureDotSuffix(rr.Name())
if rrName != fqdn {
glog.V(8).Infof("Skipping record %q (name != %s)", rrName, fqdn)
continue
// TODO: work-around before ResourceRecordSets.List() is implemented for CoreDNS
if dnsProviderId == k8scoredns.ProviderName {
dnsRecord, err := rrsProvider.Get(fqdn)
if err != nil {
return fmt.Errorf("Failed to get DNS record %s with error: %v", fqdn, err)
}
if string(rr.Type()) != string(k.RecordType) {
glog.V(8).Infof("Skipping record %q (type %s != %s)", rrName, rr.Type(), k.RecordType)
continue
if dnsRecord != nil && string(dnsRecord.Type()) == string(k.RecordType) {
glog.V(8).Infof("Found matching record: %s %s", k.RecordType, fqdn)
existing = dnsRecord
}
} else {
// when DNS provider is aws-route53 or google-clouddns
rrs, err := o.listRecords(zone)
if err != nil {
return fmt.Errorf("error querying resource records for zone %q: %v", zone.Name(), err)
}
if existing != nil {
glog.Warningf("Found multiple matching records: %v and %v", existing, rr)
} else {
glog.V(8).Infof("Found matching record: %s %s", k.RecordType, rrName)
for _, rr := range rrs {
rrName := EnsureDotSuffix(rr.Name())
if rrName != fqdn {
glog.V(8).Infof("Skipping record %q (name != %s)", rrName, fqdn)
continue
}
if string(rr.Type()) != string(k.RecordType) {
glog.V(8).Infof("Skipping record %q (type %s != %s)", rrName, rr.Type(), k.RecordType)
continue
}
if existing != nil {
glog.Warningf("Found multiple matching records: %v and %v", existing, rr)
} else {
glog.V(8).Infof("Found matching record: %s %s", k.RecordType, rrName)
}
existing = rr
}
existing = rr
}
cs, err := o.getChangeset(zone)

View File

@ -166,6 +166,7 @@ type ProtokubeFlags struct {
// ClusterId flag is required only for vSphere cloud type, to pass cluster id information to protokube. AWS and GCE workflows ignore this flag.
ClusterId *string `json:"cluster-id,omitempty" flag:"cluster-id"`
DNSServer *string `json:"dns-server,omitempty" flag:"dns-server"`
}
// ProtokubeFlags returns the flags object for protokube
@ -212,8 +213,9 @@ func (t *ProtokubeBuilder) ProtokubeFlags(k8sVersion semver.Version) *ProtokubeF
case fi.CloudProviderGCE:
f.DNSProvider = fi.String("google-clouddns")
case fi.CloudProviderVSphere:
f.DNSProvider = fi.String("aws-route53")
f.DNSProvider = fi.String("coredns")
f.ClusterId = fi.String(t.Cluster.ObjectMeta.Name)
f.DNSServer = fi.String(*t.Cluster.Spec.CloudConfig.VSphereCoreDNSServer)
default:
glog.Warningf("Unknown cloudprovider %q; won't set DNS provider")
}

View File

@ -17,10 +17,12 @@ limitations under the License.
package main
import (
"bytes"
"flag"
"fmt"
"github.com/golang/glog"
"github.com/spf13/pflag"
"io"
"k8s.io/kops/dns-controller/pkg/dns"
"k8s.io/kops/protokube/pkg/protokube"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
@ -30,6 +32,7 @@ import (
// Load DNS plugins
_ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53"
k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns"
_ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns"
)
@ -53,7 +56,7 @@ func main() {
func run() error {
dnsProviderId := "aws-route53"
flags.StringVar(&dnsProviderId, "dns", dnsProviderId, "DNS provider we should use (aws-route53, google-clouddns)")
flags.StringVar(&dnsProviderId, "dns", dnsProviderId, "DNS provider we should use (aws-route53, google-clouddns, coredns)")
var zones []string
flags.StringSliceVarP(&zones, "zone", "z", []string{}, "Configure permitted zones and their mappings")
@ -79,6 +82,9 @@ func run() error {
clusterID := ""
flag.StringVar(&clusterID, "cluster-id", clusterID, "Cluster ID")
dnsServer := ""
flag.StringVar(&dnsServer, "dns-server", dnsServer, "DNS Server")
flagChannels := ""
flag.StringVar(&flagChannels, "channels", flagChannels, "channels to install")
@ -178,7 +184,16 @@ func run() error {
var dnsScope dns.Scope
var dnsController *dns.DNSController
{
dnsProvider, err := dnsprovider.GetDnsProvider(dnsProviderId, nil)
var file io.Reader
if dnsProviderId == k8scoredns.ProviderName {
var lines []string
lines = append(lines, "etcd-endpoints = "+dnsServer)
lines = append(lines, "zones = "+zones[0])
config := "[global]\n" + strings.Join(lines, "\n") + "\n"
file = bytes.NewReader([]byte(config))
}
dnsProvider, err := dnsprovider.GetDnsProvider(dnsProviderId, file)
if err != nil {
return fmt.Errorf("Error initializing DNS provider %q: %v", dnsProviderId, err)
}
@ -191,7 +206,7 @@ func run() error {
return fmt.Errorf("unexpected zone flags: %q", err)
}
dnsController, err = dns.NewDNSController(dnsProvider, zoneRules)
dnsController, err = dns.NewDNSController(dnsProvider, zoneRules, dnsProviderId)
if err != nil {
return err
}

View File

@ -456,6 +456,8 @@ func (c *ApplyClusterCmd) Run() error {
//&model.SSHKeyModelBuilder{KopsModelContext: modelContext},
)
case fi.CloudProviderVSphere:
l.Builders = append(l.Builders,
&model.PKIModelBuilder{KopsModelContext: modelContext})
default:
return fmt.Errorf("unknown cloudprovider %q", cluster.Spec.CloudProvider)

View File

@ -136,7 +136,7 @@ func (tf *TemplateFunctions) DnsControllerArgv() ([]string, error) {
case fi.CloudProviderGCE:
argv = append(argv, "--dns=google-clouddns")
case fi.CloudProviderVSphere:
argv = append(argv, "--dns=aws-route53")
argv = append(argv, "--dns=coredns")
default:
return nil, fmt.Errorf("unhandled cloudprovider %q", tf.cluster.Spec.CloudProvider)