Skip to content

Commit

Permalink
adjust docs before the v0.3.0 release (#184)
Browse files Browse the repository at this point in the history
* adjust docs before the v0.3.0 release

* minor fixes

* docs: add missing dot

* docs: add missing dot

* docs: drop line

* docs: drop another line

* adjust documentation

* update main readme

* checkbox for releases, add --txt-owner-id flag in description

* docs: minor weird character fixes [ci skip]
  • Loading branch information
Yerken authored and linki committed May 8, 2017
1 parent 305f691 commit 55816ae
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 73 deletions.
43 changes: 20 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ The [FAQ](docs/faq.md) contains additional information and addresses several que

## Getting started

ExternalDNS' current release is `v0.2`. This version allows you to keep a managed zone in Google's [CloudDNS](https://cloud.google.com/dns/docs/) or [AWS' Route 53](https://aws.amazon.com/route53/) synchronized with Ingresses and Services of `type=LoadBalancer` in your cluster.
ExternalDNS' current release is `v0.3`. This version allows you to keep selected zones (via `--domain`) in Google's [CloudDNS](https://cloud.google.com/dns/docs/) or [AWS' Route 53](https://aws.amazon.com/route53/) synchronized with Ingresses and Services of `type=LoadBalancer` in your cluster.

In this release, ExternalDNS is limited to—and takes full ownership of—a single managed zone. In other words, if you have any existing records in that zone, they will be removed. We encourage you to try out ExternalDNS in its own zone first to see if that model works for you. However, ExternalDNS runs in dryRun mode by default, and won't make any changes to your infrastructure. So as long as you don't change that flag, you're safe.
From this release, ExternalDNS can become aware of the records it is managing (enabled via `--registry=txt`), therefore ExternalDNS can safely manage non-empty hosted zones. We strongly encourage you to use `v0.3` with `--registry=txt` enabled and `--txt-owner-id` set to a unique value that doesn't change for the lifetime of your cluster. You might also want to run ExternalDNS in a dry run mode (`--dry-run` flag) to see the changes to be submitted to your DNS Provider API.

### Technical Requirements

Make sure you have the following prerequisites:
* A local Go 1.7+ development environment.
* Access to a Google project with the DNS API enabled.
* Access to a Google/AWS account with the DNS API enabled.
* Access to a Kubernetes cluster that supports exposing Services, e.g. GKE.
* A properly set up, **unused**, and **empty** hosted zone in Google CloudDNS.

### Setup Steps

Expand All @@ -48,18 +47,18 @@ Annotate the Service with your desired external DNS name. Make sure to change `e
$ kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.example.org."
```

Locally run a single sync loop of ExternalDNS. Make sure to change the Google project to one you control, and the zone identifier to an **unused** and **empty** hosted zone in that project's Google CloudDNS:
Locally run a single sync loop of ExternalDNS.

```console
$ external-dns --zone example-org --provider google --google-project example-project --source service --once
$ external-dns --registry txt --txt-owner-id my-cluster-id --provider google --google-project example-project --source service --once --dry-run
```

This should output the DNS records it will modify to match the managed zone with the DNS records you desire.
This should output the DNS records it will modify to match the managed zone with the DNS records you desire. Note TXT records having `my-cluster-id` value embedded. Those are used to ensure that ExternalDNS is aware of the records it manages.

Once you're satisfied with the result, you can run ExternalDNS like you would run it in your cluster: as a control loop, and not in dryRun mode:
Once you're satisfied with the result, you can run ExternalDNS like you would run it in your cluster: as a control loop, and **not in dry-run** mode:

```console
$ external-dns --zone example-org --provider google --google-project example-project --source service --dry-run=false
$ external-dns --registry txt --txt-owner-id my-cluster-id --provider google --google-project example-project --source service
```

Check that ExternalDNS has created the desired DNS record for your Service and that it points to its load balancer's IP. Then try to resolve it:
Expand All @@ -81,31 +80,29 @@ The [tutorials](docs/tutorials) section contains examples, including Ingress res

ExternalDNS was built with extensibility in mind. Adding and experimenting with new DNS providers and sources of desired DNS records should be as easy as possible. It should also be possible to modify how ExternalDNS behaves—e.g. whether it should add records but never delete them.

We're working on an ownership system that allows ExternalDNS to never modify records over which it lacks control.

Here's a rough outline on what is to come:
Here's a rough outline on what is to come (subject to change):

### v0.1

* Support for Google CloudDNS
* Support for Kubernetes Services
- [x] Support for Google CloudDNS
- [x] Support for Kubernetes Services

### v0.2

* Support for AWS Route 53
* Support for Kubernetes Ingresses
- [x] Support for AWS Route 53
- [x] Support for Kubernetes Ingresses

### v0.3
### v0.3 - _current version_

* Support for AWS Route 53 via ALIAS
* Support for multiple zones
* Ownership System
- [x] Support for AWS Route 53 via ALIAS
- [x] Support for multiple zones
- [x] Ownership System

### v1.0

* Ability to replace Kops' [DNS Controller](https://github.com/kubernetes/kops/tree/master/dns-controller)
* Ability to replace Zalando's [Mate](https://github.com/zalando-incubator/mate)
* Ability to replace Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes)
- [ ] Ability to replace Kops' [DNS Controller](https://github.com/kubernetes/kops/tree/master/dns-controller)
- [ ] Ability to replace Zalando's [Mate](https://github.com/zalando-incubator/mate)
- [ ] Ability to replace Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes)

### Yet to be defined

Expand Down
4 changes: 3 additions & 1 deletion docs/contributing/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ For example, the `ServiceSource` returns all Services converted to `Endpoints` w

This list of endpoints is passed to the [Plan](../../plan) which determines the difference between the current DNS records and the desired list of `Endpoints`.

Once the difference has been figured out the list of intended changes is passed to a `Provider` which live in the [provider](../../provider) package. The provider is the adapter to the DNS provider, e.g. Google CloudDNS. It implements two methods: `ApplyChanges` to apply a set of changes and `Records` to retrieve the current list of records from the DNS provider.
Once the difference has been figured out the list of intended changes is passed to a `Registry` which live in the [registry](../../registry) package. The registry is a wrapper and access point to DNS provider. Registry implements the ownership concept by marking owned records and filtering out records not owned by ExternalDNS before passing them to DNS provider.

The [provider](../../provider) is the adapter to the DNS provider, e.g. Google CloudDNS. It implements two methods: `ApplyChanges` to apply a set of changes filtered by `Registry` and `Records` to retrieve the current list of records from the DNS provider.

The orchestration between the different components is controlled by the [controller](../../controller).

Expand Down
20 changes: 14 additions & 6 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ There are no plans regarding other providers at the moment.

Services exposed via `type=LoadBalancer` and for the hostnames defined in Ingress objects. It also seems useful to expose Services with `type=NodePort` to point to your cluster's nodes directly, but there's no commitment to doing this yet.

### How do I specify DNS name for my Kubernetes objects?

There are three sources of information for ExternalDNS to decide on DNS name. ExternalDNS will pick one in order as listed below:

1. For ingress objects ExternalDNS will create a DNS record based on the host specified for the ingress object. For services ExternalDNS will look for the annotation `external-dns.alpha.kubernetes.io/hostname` on the service and use the corresponding value.

2. If compatibility mode is enabled (e.g. `--compatibility={mate,molecule}` flag), External DNS will parse annotations used by Zalando/Mate, wearemolecule/route53-kubernetes. Compatibility mode with Kops DNS Controller is planned to be added in the future.

3. If `--fqdn-template` flag is specified, e.g. `--fqdn-template={{.Name}}.my-org.com`, ExternalDNS will use service/ingress specifications for the provided template to generate DNS name.

### Which Service and Ingress controllers are supported?

Regarding Services, we'll support the OSI Layer 4 load balancers that Kubernetes creates on AWS and Google Container Engine, and possibly other clusters running on Google Compute Engine.
Expand All @@ -63,16 +73,14 @@ ExternalDNS will allow you to opt into any Services and Ingresses that you want

### I'm afraid you will mess up my DNS records!

ExternalDNS will implement the concept of owning DNS records. This means that ExternalDNS will keep track of which records it has control over, and will never modify any records over which it doesn't have control. This is a fundamental requirement to operate ExternalDNS safely when there might be other actors creating DNS records in the same target space.
ExternalDNS since v0.3 implements the concept of owning DNS records. This means that ExternalDNS will keep track of which records it has control over, and will never modify any records over which it doesn't have control. This is a fundamental requirement to operate ExternalDNS safely when there might be other actors creating DNS records in the same target space.

However, this is a delicate topic and hasn't yet found its way into ExternalDNS.
For now ExternalDNS uses TXT records to label owned records, and there might be other alternatives coming in the future releases.

### Does anyone use ExternalDNS in production?

Nobut ExternalDNS is heavily influenced by Zalando's [Mate](https://github.com/zalando-incubator/mate), which is used in production on AWS. If you want to adopt this approach and need a solution now, then try Mate. Otherwise, we encourage you to stick with ExternalDNS and help us make it work for you.
Yes — Zalando replaced [Mate](https://github.com/zalando-incubator/mate) with ExternalDNS since its v0.3 release, which now runs in production-level clusters. We are planning to document a step-by-step tutorial on how the switch from Mate to ExternalDNS has occured.

### How can we start using ExternalDNS?

ExternalDNS is in an early state and not yet recommended for production use. However, you can start trying it out on a non-production GKE cluster following [the GKE tutorial](tutorials/gke.md).

Clusters on AWS that want to make use of Route 53 work very similar, but a tutorial is still on our TODO list.
Check out the following decriptive tutorials on how to run ExternalDNS in [GKE](tutorials/gke.md) and [AWS](tutorial/aws.md).
7 changes: 4 additions & 3 deletions docs/initial-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

## Background

**Note: This DOC is WIP**

[Project proposal](https://groups.google.com/forum/#!searchin/kubernetes-dev/external$20dns%7Csort:relevance/kubernetes-dev/2wGQUB0fUuE/9OXz01i2BgAJ)

[Initial discussion](https://docs.google.com/document/d/1ML_q3OppUtQKXan6Q42xIq2jelSoIivuXI8zExbc6ec/edit#heading=h.1pgkuagjhm4p)
Expand Down Expand Up @@ -86,5 +84,8 @@ It should be safe to run both `route53-kubernetes` and `external-dns` simultaneo

### Ownership

External DNS should be *responsible* for the created records. Which means that the records should be tagged (TODO:*describe how this supposed to work?*) and only tagged records are viable for future deletion/update. It should not mess with pre-existing records created via other means
External DNS should be *responsible* for the created records. Which means that the records should be tagged and only tagged records are viable for future deletion/update. It should not mess with pre-existing records created via other means.

#### Ownership via TXT records

Each record managed by External DNS is accompanied with a TXT record with a specific value to indicate that corresponding DNS record is managed by External DNS and it can be updated/deleted respectively. TXT records are limited to lifetimes of service/ingress objects and are created/deleted once k8s resources are created/deleted.
76 changes: 47 additions & 29 deletions docs/tutorials/aws.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
# Setting up ExternalDNS for Services on AWS

This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on AWS.
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on AWS. Make sure to use **>=0.3** version of ExternalDNS for this tutorial

## Set up a hosted zone

*If you prefer to try-out ExternalDNS in one of the existing hosted-zones you can skip this step*

Create a DNS zone which will contain the managed DNS records.

```console
$ aws route53 create-hosted-zone --name "external-dns-test.teapot.zalan.do." --caller-reference "external-dns-test-$(date +%s)"
$ aws route53 create-hosted-zone --name "external-dns-test.my-org.com." --caller-reference "external-dns-test-$(date +%s)"
```


Make a note of the ID of the hosted zone you just created.

```console
$ aws route53 list-hosted-zones-by-name --dns-name "external-dns-test.teapot.zalan.do." | jq -r '.HostedZones[0].Id'
/hostedzone/Z16P7IEWFWZ4RB
$ aws route53 list-hosted-zones-by-name --dns-name "external-dns-test.my-org.com." | jq -r '.HostedZones[0].Id'
/hostedzone/ZEWFWZ4R16P7IB
```

Make a note of the nameservers that were assigned to your new zone.

```console
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/Z16P7IEWFWZ4RB" \
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
--query "ResourceRecordSets[?Type == 'NS']" | jq -r '.[0].ResourceRecords[].Value'
ns-1455.awsdns-53.org.
ns-1694.awsdns-19.co.uk.
ns-764.awsdns-31.net.
ns-62.awsdns-07.com.
ns-5514.awsdns-53.org.
...
```

In this case it's the ones shown above but your's will differ.

If you decide not to create a new zone but reuse an existing one, make sure it's currently **unused** and **empty**. This version of ExternalDNS will remove all records it doesn't recognize from the zone.
## Deploy ExternalDNS

Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
Then apply the following manifest file to deploy ExternalDNS.
Expand All @@ -48,15 +51,19 @@ spec:
spec:
containers:
- name: external-dns
image: registry.opensource.zalan.do/teapot/external-dns:v0.2.1
image: registry.opensource.zalan.do/teapot/external-dns:v0.3.0
args:
- --in-cluster
- --zone=Z16P7IEWFWZ4RB
- --source=service
- --source=ingress
- --provider=aws
- --dry-run=false
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --registry=txt
- --txt-owner-id=my-identifier
- --domain=external-dns-test.my-org.com. # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
```
## Verify ExternalDNS works
Create the following sample application to test that ExternalDNS works.
```yaml
Expand All @@ -65,7 +72,7 @@ kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.teapot.zalan.do.
external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com.
spec:
type: LoadBalancer
ports:
Expand Down Expand Up @@ -96,33 +103,44 @@ spec:
After roughly two minutes check that a corresponding DNS record for your service was created.
```console
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/Z16P7IEWFWZ4RB" \
--query "ResourceRecordSets[?Name == 'nginx.external-dns-test.teapot.zalan.do.']|[?Type == 'CNAME']"
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
--query "ResourceRecordSets[?Name == 'nginx.external-dns-test.my-org.com.']|[?Type == 'A']"
[
{
"ResourceRecords": [
{
"Value": "ae11c2360188411e7951602725593fd1-1224345803.eu-central-1.elb.amazonaws.com"
}
],
"Type": "CNAME",
"Name": "nginx.external-dns-test.teapot.zalan.do.",
"TTL": 300
"AliasTarget": {
"HostedZoneId": "ZEWFWZ4R16P7IB",
"DNSName": "ae11c2360188411e7951602725593fd1-1224345803.eu-central-1.elb.amazonaws.com.",
"EvaluateTargetHealth": true
},
"Name": "external-dns-test.my-org.com.",
"Type": "A"
},
{
"Name": "external-dns-test.my-org.com",
"TTL": 300,
"ResourceRecords": [
{
"Value": "\"heritage=external-dns,external-dns/owner=my-identifier\""
}
],
"Type": "TXT"
}
]
```

Note created TXT record alongside ALIAS record. TXT record signifies that the corresponding ALIAS record is managed by ExternalDNS. This makes ExternalDNS safe for running in environments where there are other records managed via other means.

Let's check that we can resolve this DNS name. We'll ask the nameservers assigned to your zone first.

```console
$ dig +short @ns-1455.awsdns-53.org. nginx.external-dns-test.teapot.zalan.do.
$ dig +short @ns-5514.awsdns-53.org. nginx.external-dns-test.my-org.com.
ae11c2360188411e7951602725593fd1-1224345803.eu-central-1.elb.amazonaws.com.
```

If you hooked up your DNS zone with its parent zone correctly you can use `curl` to access your site.

```console
$ curl nginx.external-dns-test.teapot.zalan.do.
$ curl nginx.external-dns-test.my-org.com.
<!DOCTYPE html>
<html>
<head>
Expand All @@ -145,8 +163,8 @@ Make sure to delete all Service objects before terminating the cluster so all lo
$ kubectl delete service nginx
```

Give ExternalDNS some time to clean up the DNS records for you. Then delete the hosted zone.
Give ExternalDNS some time to clean up the DNS records for you. Then delete the hosted zone if you created one for the testing purpose.

```console
$ aws route53 delete-hosted-zone --id /hostedzone/Z16P7IEWFWZ4RB
$ aws route53 delete-hosted-zone --id /hostedzone/ZEWFWZ4R16P7IB
```
Loading

0 comments on commit 55816ae

Please sign in to comment.