Exposing your AKS workloads using External DNS and Nginx Ingress Controller

Introduction

Simple Architecture

Azure Infrastructure and Configuration

az role assignment create --role “Contributor” --assignee 9b1cf06b-137f-4ac0–9526-***** --scope /subscriptions/<subscription id>
The VMScaleSet will be located in the Shadow Resource Group AKS Service Creates
az aks show -g adrian-group -n adrian-cluster --query “identity”
{
"principalId": "ABC-123",
"tenantId": "XYZ",
"type": "SystemAssigned",
"userAssignedIdentities": null
}
az role assignment create --role “Contributor” --assignee ABC-123 --scope /subscriptions/<your subscription ID>

Kubernetes Resources

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
#internal-ingress.yaml
controller:
service:
loadBalancerIP: 10.240.0.254
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
helm install nginx-ingress ingress-nginx/ingress-nginx   --namespace default  -f internal-ingress.yaml  --set controller.replicaCount=2 --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux  --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux
kubectl describe svc nginx-ingress-ingress-nginx-controller
kubectl apply -f external-dns.yaml
#external-dns.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
args:
- --source=service
- --source=ingress
- --domain-filter=hynes.pri
- --provider=azure-private-dns
- --azure-resource-group=<Resource Group>
- --azure-subscription-id=<Subscription ID>
env:
- name: AZURE_TENANT_ID
value: <Tenant ID>
- name: AZURE_CLIENT_ID
value: <adrian-identity client id>
- name: AZURE_SUBSCRIPTION_ID
value: <Subscription ID>
image: k8s.gcr.io/external-dns/external-dns:v0.7.0
kubectl apply -f example.yaml#example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-two
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-two
template:
metadata:
labels:
app: aks-helloworld-two
spec:
containers:
- name: aks-helloworld-two
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "AKS Ingress Demo"
---
apiVersion: v1
kind: Service
metadata:
name: aks-helloworld-two
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: aks-helloworld-two
---apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: aido.hynes.pri
http:
paths:
- backend:
serviceName: aks-helloworld-two
servicePort: 80
path: /(.*)
kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
hello-world-ingress aido.hynes.priv 10.240.0.254 80 5h54m

Conclusion

References

--

--

Cloud Platform Architect. Opinions and articles on medium are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adrian Hynes

Cloud Platform Architect. Opinions and articles on medium are my own.