sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/kube-ingress-aws.md (about) 1 # Using ExternalDNS with kube-ingress-aws-controller 2 3 This tutorial describes how to use ExternalDNS with the [kube-ingress-aws-controller][1]. 4 5 [1]: https://github.com/zalando-incubator/kube-ingress-aws-controller 6 7 ## Setting up ExternalDNS and kube-ingress-aws-controller 8 9 Follow the [AWS tutorial](aws.md) to setup ExternalDNS for use in Kubernetes clusters 10 running in AWS. Specify the `source=ingress` argument so that ExternalDNS will look 11 for hostnames in Ingress objects. In addition, you may wish to limit which Ingress 12 objects are used as an ExternalDNS source via the `ingress-class` argument, but 13 this is not required. 14 15 For help setting up the Kubernetes Ingress AWS Controller, that can 16 create ALBs and NLBs, follow the [Setup Guide][2]. 17 18 [2]: https://github.com/zalando-incubator/kube-ingress-aws-controller/tree/HEAD/deploy 19 20 21 ### Optional RouteGroup 22 23 [RouteGroup][3] is a CRD, that enables you to do complex routing with 24 [Skipper][4]. 25 26 First, you have to apply the RouteGroup CRD to your cluster: 27 28 ``` 29 kubectl apply -f https://github.com/zalando/skipper/blob/HEAD/dataclients/kubernetes/deploy/apply/routegroups_crd.yaml 30 ``` 31 32 You have to grant all controllers: [Skipper][4], 33 [kube-ingress-aws-controller][1] and external-dns to read the routegroup resource and 34 kube-ingress-aws-controller to update the status field of a routegroup. 35 This depends on your RBAC policies, in case you use RBAC, you can use 36 this for all 3 controllers: 37 38 ```yaml 39 apiVersion: rbac.authorization.k8s.io/v1 40 kind: ClusterRole 41 metadata: 42 name: kube-ingress-aws-controller 43 rules: 44 - apiGroups: 45 - extensions 46 - networking.k8s.io 47 resources: 48 - ingresses 49 verbs: 50 - get 51 - list 52 - watch 53 - apiGroups: 54 - extensions 55 - networking.k8s.io 56 resources: 57 - ingresses/status 58 verbs: 59 - patch 60 - update 61 - apiGroups: 62 - zalando.org 63 resources: 64 - routegroups 65 verbs: 66 - get 67 - list 68 - watch 69 - apiGroups: 70 - zalando.org 71 resources: 72 - routegroups/status 73 verbs: 74 - patch 75 - update 76 ``` 77 78 See also current RBAC yaml files: 79 - [kube-ingress-aws-controller](https://github.com/zalando-incubator/kubernetes-on-aws/blob/dev/cluster/manifests/ingress-controller/01-rbac.yaml) 80 - [skipper](https://github.com/zalando-incubator/kubernetes-on-aws/blob/dev/cluster/manifests/skipper/rbac.yaml) 81 - [external-dns](https://github.com/zalando-incubator/kubernetes-on-aws/blob/dev/cluster/manifests/external-dns/01-rbac.yaml) 82 83 [3]: https://opensource.zalando.com/skipper/kubernetes/routegroups/#routegroups 84 [4]: https://opensource.zalando.com/skipper 85 86 87 ## Deploy an example application 88 89 Create the following sample "echoserver" application to demonstrate how 90 ExternalDNS works with ingress objects, that were created by [kube-ingress-aws-controller][1]. 91 92 ```yaml 93 apiVersion: apps/v1 94 kind: Deployment 95 metadata: 96 name: echoserver 97 spec: 98 replicas: 1 99 selector: 100 matchLabels: 101 app: echoserver 102 template: 103 metadata: 104 labels: 105 app: echoserver 106 spec: 107 containers: 108 - image: gcr.io/google_containers/echoserver:1.4 109 imagePullPolicy: Always 110 name: echoserver 111 ports: 112 - containerPort: 8080 113 --- 114 apiVersion: v1 115 kind: Service 116 metadata: 117 name: echoserver 118 spec: 119 ports: 120 - port: 80 121 targetPort: 8080 122 protocol: TCP 123 type: ClusterIP 124 selector: 125 app: echoserver 126 ``` 127 128 Note that the Service object is of type `ClusterIP`, because we will 129 target [Skipper][4] and do the HTTP routing in Skipper. We don't need 130 a Service of type `LoadBalancer` here, since we will be using a shared 131 skipper-ingress for all Ingress. Skipper use `hostNetwork` to be able 132 to get traffic from AWS LoadBalancers EC2 network. ALBs or NLBs, will 133 be created based on need and will be shared across all ingress as 134 default. 135 136 ## Ingress examples 137 138 Create the following Ingress to expose the echoserver application to the Internet. 139 140 ```yaml 141 apiVersion: networking.k8s.io/v1 142 kind: Ingress 143 metadata: 144 name: echoserver 145 spec: 146 ingressClassName: skipper 147 rules: 148 - host: echoserver.mycluster.example.org 149 http: &echoserver_root 150 paths: 151 - path: / 152 backend: 153 service: 154 name: echoserver 155 port: 156 number: 80 157 pathType: Prefix 158 - host: echoserver.example.org 159 http: *echoserver_root 160 ``` 161 162 The above should result in the creation of an (ipv4) ALB in AWS which will forward 163 traffic to skipper which will forward to the echoserver application. 164 165 If the `--source=ingress` argument is specified, then ExternalDNS will create DNS 166 records based on the hosts specified in ingress objects. The above example would 167 result in two alias records being created, `echoserver.mycluster.example.org` and 168 `echoserver.example.org`, which both alias the ALB that is associated with the 169 Ingress object. 170 171 Note that the above example makes use of the YAML anchor feature to avoid having 172 to repeat the http section for multiple hosts that use the exact same paths. If 173 this Ingress object will only be fronting one backend Service, we might instead 174 create the following: 175 176 ```yaml 177 apiVersion: networking.k8s.io/v1 178 kind: Ingress 179 metadata: 180 annotations: 181 external-dns.alpha.kubernetes.io/hostname: echoserver.mycluster.example.org, echoserver.example.org 182 name: echoserver 183 spec: 184 ingressClassName: skipper 185 rules: 186 - http: 187 paths: 188 - path: / 189 backend: 190 service: 191 name: echoserver 192 port: 193 number: 80 194 pathType: Prefix 195 ``` 196 197 In the above example we create a default path that works for any hostname, and 198 make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create 199 multiple aliases for the resulting ALB. 200 201 ## Dualstack ALBs 202 203 AWS [supports](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type) both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs. 204 The Kubernetes Ingress AWS controller supports the `alb.ingress.kubernetes.io/ip-address-type` 205 annotation (which defaults to `ipv4`) to determine this. If this annotation is 206 set to `dualstack` then ExternalDNS will create two alias records (one A record 207 and one AAAA record) for each hostname associated with the Ingress object. 208 209 210 Example: 211 212 ```yaml 213 apiVersion: networking.k8s.io/v1 214 kind: Ingress 215 metadata: 216 annotations: 217 alb.ingress.kubernetes.io/ip-address-type: dualstack 218 name: echoserver 219 spec: 220 ingressClassName: skipper 221 rules: 222 - host: echoserver.example.org 223 http: 224 paths: 225 - path: / 226 backend: 227 service: 228 name: echoserver 229 port: 230 number: 80 231 pathType: Prefix 232 ``` 233 234 The above Ingress object will result in the creation of an ALB with a dualstack 235 interface. ExternalDNS will create both an A `echoserver.example.org` record and 236 an AAAA record of the same name, that each are aliases for the same ALB. 237 238 ## NLBs 239 240 AWS has 241 [NLBs](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html) 242 and [kube-ingress-aws-controller][1] is able to create NLBs instead of ALBs. 243 The Kubernetes Ingress AWS controller supports the `zalando.org/aws-load-balancer-type` 244 annotation (which defaults to `alb`) to determine this. If this annotation is 245 set to `nlb` then ExternalDNS will create an NLB instead of an ALB. 246 247 Example: 248 249 ```yaml 250 apiVersion: networking.k8s.io/v1 251 kind: Ingress 252 metadata: 253 annotations: 254 zalando.org/aws-load-balancer-type: nlb 255 name: echoserver 256 spec: 257 ingressClassName: skipper 258 rules: 259 - host: echoserver.example.org 260 http: 261 paths: 262 - path: / 263 backend: 264 service: 265 name: echoserver 266 port: 267 number: 80 268 pathType: Prefix 269 ``` 270 271 The above Ingress object will result in the creation of an NLB. A 272 successful create, you can observe in the ingress `status` field, that is 273 written by [kube-ingress-aws-controller][1]: 274 275 ```yaml 276 status: 277 loadBalancer: 278 ingress: 279 - hostname: kube-ing-lb-atedkrlml7iu-1681027139.$region.elb.amazonaws.com 280 ``` 281 282 ExternalDNS will create a A-records `echoserver.example.org`, that 283 use AWS ALIAS record to automatically maintain IP addresses of the NLB. 284 285 ## RouteGroup (optional) 286 287 [Kube-ingress-aws-controller][1], [Skipper][4] and external-dns 288 support [RouteGroups][3]. External-dns needs to be started with 289 `--source=skipper-routegroup` parameter in order to work on RouteGroup objects. 290 291 Here we can not show [all RouteGroup 292 capabilities](https://opensource.zalando.com/skipper/kubernetes/routegroups/), 293 but we show one simple example with an application and a custom https 294 redirect. 295 296 ```yaml 297 apiVersion: zalando.org/v1 298 kind: RouteGroup 299 metadata: 300 name: my-route-group 301 spec: 302 backends: 303 - name: my-backend 304 type: service 305 serviceName: my-service 306 servicePort: 80 307 - name: redirectShunt 308 type: shunt 309 defaultBackends: 310 - backendName: my-service 311 routes: 312 - pathSubtree: / 313 - pathSubtree: / 314 predicates: 315 - Header("X-Forwarded-Proto", "http") 316 filters: 317 - redirectTo(302, "https:") 318 backends: 319 - redirectShunt 320 ```