alb-ingress.md 5.22 KB
Newer Older
1
2
3
4
# Using ExternalDNS with alb-ingress-controller

This tutorial describes how to use ExternalDNS with the [aws-alb-ingress-controller][1].

5
[1]: https://kubernetes-sigs.github.io/aws-load-balancer-controller
6
7
8
9
10
11
12
13
14
15
16

## Setting up ExternalDNS and aws-alb-ingress-controller

Follow the [AWS tutorial](aws.md) to setup ExternalDNS for use in Kubernetes clusters
running in AWS. Specify the `source=ingress` argument so that ExternalDNS will look
for hostnames in Ingress objects. In addition, you may wish to limit which Ingress
objects are used as an ExternalDNS source via the `ingress-class` argument, but
this is not required.

For help setting up the ALB Ingress Controller, follow the [Setup Guide][2].

17
[2]: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/installation/
18
19
20
21

Note that the ALB ingress controller uses the same tags for [subnet auto-discovery][3]
as Kubernetes does with the AWS cloud provider.

22
[3]: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/subnet_discovery/
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

In the examples that follow, it is assumed that you configured the ALB Ingress
Controller with the `ingress-class=alb` argument (not to be confused with the
same argument to ExternalDNS) so that the controller will only respect Ingress
objects with the `kubernetes.io/ingress.class` annotation set to "alb".

## Deploy an example application

Create the following sample "echoserver" application to demonstrate how
ExternalDNS works with ALB ingress objects.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echoserver
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      containers:
      - image: gcr.io/google_containers/echoserver:1.4
        imagePullPolicy: Always
        name: echoserver
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: NodePort
  selector:
    app: echoserver
```

Note that the Service object is of type `NodePort`. We don't need a Service of
type `LoadBalancer` here, since we will be using an Ingress to create an ALB.

## Ingress examples

Create the following Ingress to expose the echoserver application to the Internet.

```yaml
78
apiVersion: networking.k8s.io/v1
79
80
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
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    kubernetes.io/ingress.class: alb
  name: echoserver
spec:
  rules:
  - host: echoserver.mycluster.example.org
    http: &echoserver_root
      paths:
      - backend:
          serviceName: echoserver
          servicePort: 80
        path: /
  - host: echoserver.example.org
    http: *echoserver_root
```

The above should result in the creation of an (ipv4) ALB in AWS which will forward
traffic to the echoserver application.

If the `source=ingress` argument is specified, then ExternalDNS will create DNS
records based on the hosts specified in ingress objects. The above example would
result in two alias records being created, `echoserver.mycluster.example.org` and
`echoserver.example.org`, which both alias the ALB that is associated with the
Ingress object.

Note that the above example makes use of the YAML anchor feature to avoid having
to repeat the http section for multiple hosts that use the exact same paths. If
this Ingress object will only be fronting one backend Service, we might instead
create the following:

```yaml
113
apiVersion: networking.k8s.io/v1
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
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    external-dns.alpha.kubernetes.io/hostname: echoserver.mycluster.example.org, echoserver.example.org
    kubernetes.io/ingress.class: alb
  name: echoserver
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: echoserver
          servicePort: 80
        path: /
```

In the above example we create a default path that works for any hostname, and
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
multiple aliases for the resulting ALB.

## Dualstack ALBs

AWS [supports][4] both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
The ALB ingress controller uses the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. If this annotation is
set to `dualstack` then ExternalDNS will create two alias records (one A record
and one AAAA record) for each hostname associated with the Ingress object.

[4]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type

Example:

```yaml
148
apiVersion: networking.k8s.io/v1
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/ip-address-type: dualstack
    kubernetes.io/ingress.class: alb
  name: echoserver
spec:
  rules:
  - host: echoserver.example.org
    http:
      paths:
      - backend:
          serviceName: echoserver
          servicePort: 80
        path: /
```

The above Ingress object will result in the creation of an ALB with a dualstack
interface. ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same ALB.