mirror of https://github.com/kubernetes/kops.git
Find matching existing DNS hosted zone
We choose the longest matching existing hosted zone as the default, rather than the previous heuristic which was overly simplistic. We also require the hosted zone to exist now; it doesn't seem to really cost us anything given that the user has to set up DNS delegation anyway. Fix #125
This commit is contained in:
parent
b69ee2a0ee
commit
cae256340b
10
README.md
10
README.md
|
@ -29,11 +29,15 @@ you should use Go 1.6 or later)
|
|||
|
||||
## Bringing up a cluster on AWS
|
||||
|
||||
* Ensure you have a DNS hosted zone set up in Route 53, e.g. `mydomain.com`
|
||||
* Set up a DNS hosted zone in Route 53, e.g. `mydomain.com`, and set up the DNS nameservers as normal
|
||||
so that domains will resolve. You can reuse an existing domain name (e.g. `mydomain.com`), or you can create
|
||||
a "child" hosted zone (e.g. `myclusters.mydomain.com`) if you want to isolate them. Note that with AWS Route53,
|
||||
you can have subdomains in a single hosted zone, so you can have `cluster1.testclusters.mydomain.com` under
|
||||
`mydomain.com`.
|
||||
|
||||
* Pick a DNS name under this zone to be the name of your cluster. kops will set up DNS so your cluster
|
||||
can be reached on this name. For example, if your zone was `mydomain.com`, a good name would be
|
||||
`kubernetes.mydomain.com`, or `dev.k8s.mydomain.com`, or even `dev.k8s.myproject.mydomain.com`. We'll call this `NAME`.
|
||||
can be reached on this name. For example, if your zone was `mydomain.com`, a good name would be
|
||||
`kubernetes.mydomain.com`, or `dev.k8s.mydomain.com`, or even `dev.k8s.myproject.mydomain.com`. We'll call this `NAME`.
|
||||
|
||||
* Set `AWS_PROFILE` (if you need to select a profile for the AWS CLI to work)
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ const CloudProviderGCE CloudProviderID = "gce"
|
|||
|
||||
type Cloud interface {
|
||||
ProviderID() CloudProviderID
|
||||
|
||||
FindDNSHostedZone(dnsName string) (string, error)
|
||||
}
|
||||
|
||||
// zonesToCloud allows us to infer from certain well-known zones to a cloud
|
||||
|
|
|
@ -464,3 +464,60 @@ func (c *AWSCloud) ValidateZones(zones []string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AWSCloud) FindDNSHostedZone(clusterDNSName string) (string, error) {
|
||||
glog.V(2).Infof("Querying for all route53 zones to find match for %q", clusterDNSName)
|
||||
|
||||
clusterDNSName = "." + strings.TrimSuffix(clusterDNSName, ".")
|
||||
|
||||
var zones []*route53.HostedZone
|
||||
request := &route53.ListHostedZonesInput{}
|
||||
err := c.Route53.ListHostedZonesPages(request, func(p *route53.ListHostedZonesOutput, lastPage bool) bool {
|
||||
for _, zone := range p.HostedZones {
|
||||
zoneName := aws.StringValue(zone.Name)
|
||||
zoneName = "." + strings.TrimSuffix(zoneName, ".")
|
||||
|
||||
if strings.HasSuffix(clusterDNSName, zoneName) {
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error querying for route53 zones: %v", err)
|
||||
}
|
||||
|
||||
// Find the longest zones
|
||||
maxLength := -1
|
||||
maxLengthZones := []*route53.HostedZone{}
|
||||
for _, z := range zones {
|
||||
n := len(aws.StringValue(z.Name))
|
||||
if n < maxLength {
|
||||
continue
|
||||
}
|
||||
|
||||
if n > maxLength {
|
||||
maxLength = n
|
||||
maxLengthZones = []*route53.HostedZone{}
|
||||
}
|
||||
|
||||
maxLengthZones = append(maxLengthZones, z)
|
||||
}
|
||||
|
||||
if len(maxLengthZones) == 0 {
|
||||
// We make this an error because you have to set up DNS delegation anyway
|
||||
tokens := strings.Split(clusterDNSName, ".")
|
||||
suffix := strings.Join(tokens[len(tokens)-2:], ".")
|
||||
//glog.Warningf("No matching hosted zones found; will created %q", suffix)
|
||||
//return suffix, nil
|
||||
return "", fmt.Errorf("No matching hosted zones found for %q; please create one (e.g. %q) first", clusterDNSName, suffix)
|
||||
}
|
||||
|
||||
if len(maxLengthZones) == 1 {
|
||||
id := aws.StringValue(maxLengthZones[0].Id)
|
||||
id = strings.TrimPrefix(id, "/hostedzone/")
|
||||
return id, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Found multiple hosted zones matching cluster %q; please specify the ID of the zone to use")
|
||||
}
|
||||
|
|
|
@ -93,11 +93,6 @@ func (c *CreateClusterCmd) Run() error {
|
|||
if c.Cluster.Spec.MasterPublicName == "" {
|
||||
c.Cluster.Spec.MasterPublicName = "api." + c.Cluster.Name
|
||||
}
|
||||
if c.Cluster.Spec.DNSZone == "" {
|
||||
tokens := strings.Split(c.Cluster.Spec.MasterPublicName, ".")
|
||||
c.Cluster.Spec.DNSZone = strings.Join(tokens[len(tokens)-2:], ".")
|
||||
glog.Infof("Defaulting DNS zone to: %s", c.Cluster.Spec.DNSZone)
|
||||
}
|
||||
|
||||
if len(c.Cluster.Spec.Zones) == 0 {
|
||||
// TODO: Auto choose zones from region?
|
||||
|
@ -437,6 +432,15 @@ func (c *CreateClusterCmd) Run() error {
|
|||
return fmt.Errorf("unknown CloudProvider %q", c.Cluster.Spec.CloudProvider)
|
||||
}
|
||||
|
||||
if c.Cluster.Spec.DNSZone == "" {
|
||||
dnsZone, err := cloud.FindDNSHostedZone(c.Cluster.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error determining default DNS zone; please specify --zone-name: %v", err)
|
||||
}
|
||||
glog.Infof("Defaulting DNS zone to: %s", dnsZone)
|
||||
c.Cluster.Spec.DNSZone = dnsZone
|
||||
}
|
||||
|
||||
tf := &TemplateFunctions{
|
||||
cluster: c.Cluster,
|
||||
}
|
||||
|
|
|
@ -49,3 +49,7 @@ func NewGCECloud(region string, project string) (*GCECloud, error) {
|
|||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *GCECloud) FindDNSHostedZone(clusterDNSName string) (string, error) {
|
||||
return "", fmt.Errorf("FindDNSHostedZone not yet implemented on GCE")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue