# Journey into Kubernetes - Ingress

The last step in our cluster creation process -- creating an ingress controller. Let's talk about what that is.

Ingress means "going in". In the K8s scenario, this means traffic going into the cluster. Egress, the anytonym of ingress, means going out. That would be the traffic leaving the cluster such the service sending data out from inside the cluster. An ingress controller (IC) is essentially a gateway into the cluster.

There are many different ICs to choose from, but we're going to focus on the K8s supported `ingress-nginx` project (not to be confused with `nginx-ingress` which is supported by the folks behind nginx). Both nginx ICs are good choices, and the nginx-supported one even has a 'plus' version you must pay for with some extra features. However, for our purposes, and quite honestly purposes of many production-bound projects, we're good with `ingress-nginx`.

You can visit the project website [here](https://kubernetes.github.io/ingress-nginx/).

On the site, you can visit the Deployment section -> Installation guide and click on Azure. You must run one command to install everything... but before you do that, we need to modify the installation file, because it doesn't include our SSL certificate. Go ahead and download the YAML file. You can either grab the linke from the official website, or just right-click [here](https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml) and Save As `deploy.yaml`.

The above YAML file is a master installer which will create a lot of artifacts in your cluster. It creates a namespace (we already did this step in the previous article, so nothing new will happen here), some ConfigMaps, a ServiceAccount, a ClusterRole and ClusterRoleBinding, some Roles and Services and of course a Deployment of a special version of nginx. There's a lot of stuff that's created but worry not! Our focus here is pretty narrow.

We must modify the nginx configuration to read our SSL certificate. The default nginx configuration which we get from the above installation does not include this important flag, so we must do it ourselves. Inside the downloaded YAML file, look for lines:
```yaml
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
```
This is the deployment for the nginx ingress controller. If you scroll down a bit, you'll see where the container spec is defined and these lines:
```yaml
args:
  - /nginx-ingress-controller
  ...
```
Go ahead and add this right after `/nginx-ingress-controller`
```yaml
- --default-ssl-certificate=ingress-nginx/aks-ingress-tls
```
You should have this complete args:
```yaml
args:
  - /nginx-ingress-controller
  - --default-ssl-certificate=ingress-nginx/aks-ingress-tls
  - --publish-service=ingress-nginx/ingress-nginx-controller
  - --election-id=ingress-controller-leader
  - --ingress-class=nginx
  - --configmap=ingress-nginx/ingress-nginx-controller
  - --validating-webhook=:8443
  - --validating-webhook-certificate=/usr/local/certificates/cert
  - --validating-webhook-key=/usr/local/certificates/key
```
Save the modified installation YAML and apply it
```powershell
kubectl apply -f deploy.yaml
```
Halfway there! The ingress controller is created. One last step we need to take is to tell the ingress controller where to route the incoming traffic.

Inside your integration folder, create a new file; `ingress.yml` and put this inside:
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-fancyapi
  namespace: integration
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - yourcooldomain.io
    secretName: aks-ingress-tls
  rules:
  - host: integration.yourcooldomain.io
    http:
      paths:
      - backend:
          serviceName: fancyapi-service
          servicePort: 80
```
There are a few new things here. First, we're adding an annotation. Annotations are metadata. In this case, we're attaching metadata required by the nginx ingress controller.

Next, in the spec map, we have tls and a list of hosts. I defined a made-up host and attached the secret we created in the previous article to it. For this to work however, you'll need to edit the A record of the domain first to point yourcooldomain.io to the IP address of the ingress controller, and second add a wildcard CNAME of *.yourcooldomain.io. (you are likely to need the . at the end there, as it's a standard) as well. Also, it's important that the host `yourcooldomain.io` is the same host you defined when creating your SSL certificate!

Both the A record and the wildcard CNAME need to point to the IP address of the ingress service. You can find this IP address via the following command:
```powershell
kubectl get svc -n=ingress-nginx
```
External IP is what you're looking for. Assuming your IP is 1.2.3.4, here's an example of what your DNS records should look like:

| DNS Type        | Hostname              | IP Address |
| :-------------- | :-------------------- | :--------- |
| A Record        | yourcooldomain.io     | 1.2.3.4    |
| CNAME           | *.yourcooldomain.io.  | 1.2.3.4    |

Your domain address provider is likely to have instructions on how to set this up.

In the rules map, we have a list again, but only one item. Here, we're saying "hey when someone hits `integration.yourcooldomain.io`, I want them to go to the backend service `fancyapi-service` on port `80`". When you create your production ingress file inside the production namespace, you will possible just have `yourcooldomain.io` without a subdomain, or maybe `www.yourcooldomain.io` or something.

Almost there! Go ahead and apply this config to the K8s cluster:
```powershell
kubectl apply -f ingress.yml
```
If your domain provider has updated their DNS entries, you can visit `https://integration.yourcooldomain.io` and you should be warned by your browser that the SSL certificate cannot be trusted. Thankfully, you know you can trust it, because you created it! If you skip the warning in the browser, you should arrive at your service!

Congratulations! You now have a namespaced cluster with a running service, an ingress controller and integrated SSL certificate. This is the end of the series, but there are at least 3 more Kubernetes articles to come. They will build on the knowledge we've gained in this series.

Happy Kubernetesing!

---

Resources
- [Annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
