aws-sd.md 5.66 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Setting up ExternalDNS using AWS Service Discovery API

This tutorial describes how to set up ExternalDNS for usage within a Kubernetes cluster on AWS with [Service Discovery API](https://docs.aws.amazon.com/Route53/latest/APIReference/overview-service-discovery.html).

The **Service Discovery API** is an alternative approach to managing DNS records directly using the Route53 API. It is more suitable for a dynamic environment where service endpoints change frequently. It abstracts away technical details of the DNS protocol and offers a simplified model. Service discovery consists of three main API calls:

* CreatePublicDnsNamespace – automatically creates a DNS hosted zone
* CreateService – creates a new named service inside the specified namespace
* RegisterInstance/DeregisterInstance – can be called multiple times to create a DNS record for the specified *Service*

Learn more about the API in the [Amazon Route 53 API Reference](https://docs.aws.amazon.com/Route53/latest/APIReference/API_Operations_Amazon_Route_53_Auto_Naming.html).


## IAM Permissions

To use the service discovery API, a user executing the ExternalDNS must have the permissions in the `AmazonRoute53AutoNamingFullAccess` managed policy.

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:GetHostedZone",
                "route53:ListHostedZonesByName",
                "route53:CreateHostedZone",
                "route53:DeleteHostedZone",
                "route53:ChangeResourceRecordSets",
                "route53:CreateHealthCheck",
                "route53:GetHealthCheck",
                "route53:DeleteHealthCheck",
                "route53:UpdateHealthCheck",
                "ec2:DescribeVpcs",
                "ec2:DescribeRegions",
                "servicediscovery:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

## Set up a namespace

Create a DNS namespace using the service discovery API

```console
$ aws servicediscovery create-public-dns-namespace --name "external-dns-test.my-org.com"
```

Verify that the namespace was truly created

```console
$ aws servicediscovery list-namespaces
```

## Deploy ExternalDNS

Connect your `kubectl` client to the cluster that you want to test ExternalDNS with.
Then apply the following manifest file to deploy ExternalDNS.

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      containers:
      - name: external-dns
80
        image: registry.opensource.zalan.do/teapot/external-dns:latest
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=external-dns-test.my-org.com # Makes ExternalDNS see only the namespaces that match the specified domain. Omit the filter if you want to process all available namespaces.
        - --provider=aws-sd
        - --aws-zone-type=public # Only look at public namespaces. Valid values are public, private, or no value for both)
        - --txt-owner-id=my-identifier
```


## Verify that ExternalDNS works (Service example)

Create the following sample application to test that ExternalDNS works.

> For services ExternalDNS will look for the annotation `external-dns.alpha.kubernetes.io/hostname` on the service and use the corresponding value.

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: http
    targetPort: 80
  selector:
    app: nginx

---

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
          name: http
```

After one minute check that a corresponding DNS record for your service was created in your hosted zone. We recommended that you use the [Amazon Route53 console](https://console.aws.amazon.com/route53) for that purpose.


## Custom TTL

The default DNS record TTL (time to live) is 300 seconds. You can customize this value by setting the annotation `external-dns.alpha.kubernetes.io/ttl`.
For example, modify the service manifest YAML file above:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com
    external-dns.alpha.kubernetes.io/ttl: 60
spec:
    ...
```

This will set the TTL for the DNS record to 60 seconds.


## Clean up

Delete all service objects before terminating the cluster so all load balancers get cleaned up correctly.

```console
$ kubectl delete service nginx
```

Give ExternalDNS some time to clean up the DNS records for you. Then delete the remaining service and namespace.

```console
$ aws servicediscovery list-services

{
    "Services": [
        {
            "Id": "srv-6dygt5ywvyzvi3an",
            "Arn": "arn:aws:servicediscovery:us-west-2:861574988794:service/srv-6dygt5ywvyzvi3an",
            "Name": "nginx"
        }
    ]
}
```

```console
$ aws servicediscovery delete-service --id srv-6dygt5ywvyzvi3an
```

```console
$ aws servicediscovery list-namespaces
{
    "Namespaces": [
        {
            "Type": "DNS_PUBLIC",
            "Id": "ns-durf2oxu4gxcgo6z",
            "Arn": "arn:aws:servicediscovery:us-west-2:861574988794:namespace/ns-durf2oxu4gxcgo6z",
            "Name": "external-dns-test.my-org.com"
        }
    ]
}
```

```console
$ aws servicediscovery delete-namespace --id ns-durf2oxu4gxcgo6z
Nick Jüttner's avatar
Nick Jüttner committed
200
```