Let's Embark! Setting up Ingress (Part 2)
Tags: devops, kubernetes, beginners, tutorial
Published: 2020-01-22 14:16:52

*In this article of the "Let's Embark!" series, we cover how to setup nginx-ingress using the offical nginxinc/nginx-ingress images and getting your cluster connected to the internet. To find out how to setup a Cluster on Digital Ocean, see [Part 1](https://engi.fyi/lets-embark-setting-up-kubernetes-part-1/) and use my [Referral Code](https://m.do.co/c/f250f695871e) for $100 credit to get you up and running.*

Well, we have a cluster. What now? We need to get our Cluster connected to the internet so that it can receive connections to our services. By the end of this article, you will have `nginx-ingress` setup and configured, and a demo app reachable from the internet.

##Installing nginx-ingress

I prefer to use the offical `nginx-ingress` images from Nginx, Inc. We will be setting up our Ingress controllers as a DaemonSet, so each pod will run on a node within our Cluster. Let's clone the source repository for our configuration and get our basic configuration items setup on our Cluster.

```
git clone git@github.com:nginxinc/kubernetes-ingress.git
cd deployments/
kubectl apply -f common/ns-and-sa.yaml
kubectl apply -f rbac/rbac.yaml
kubectl apply -f common/custom_resource_definitions.yaml
kubectl apply -f common/nginx-config.yaml
kubectl apply -f daemon-set/nginx-ingress.yaml
```

Within about five minutes, you should see a DaemonSet on each node you have active. For the final part of our installation, we need to configure our domain name to point to our IP address, so run the following command and the value available under `EXTERNAL-IP` should be created as an A record in your DNS settings. I would recommend using [Digital Ocean's DNS Service](https://www.digitalocean.com/docs/networking/dns/quickstart/) for this.

```
$ kubectl get service nginx-ingress -n nginx-ingress
NAME           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)        AGE
nginx-ingress  LoadBalancer  10.245.114.32  1.1.1.1      80:31908/TCP   3d1h
```

## Exposing Services

On Kubernetes, when we talk about "Services" we are talking about the endpoint that gets exposed via a Cluster's external IP Address. There are three things that go into creating and running a service on Kubernetes:

- Deployment: this creates the template for the pods, including container and replica configuration which includes image, network, and metadata information.
- Service: this defines the port that the item created by the Deployment (ReplicaSet, DaemonSet, etc) wil be exposed on in the cluster. Once you've created a Service, you can access it within the cluster at `<deployment_name>.<namespace>.svc.cluster.local` at the port you have exposed in the Service configuration.
- Ingress: This defines the domain name that we expose the service as on the external IP. Ingress within Kubernetes generally uses [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) which means without a domain name, it will be impossible to get to your Service.

For us to get our service up and running, we need to run five scripts which will setup everything we need and expose our service on our `nginx-ingress`. Prior to continuing, you will have needed to setup your domain name, as we will use it in the configuration below.

```
$ kubectl apply -f echo_namespace.yaml

# echo_namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
  name: echo
  labels:
    name: echo
```

```

$ kubectl apply -f echo_deployment.yaml

# echo_deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
  namespace: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 2
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Default HTTP Service"
        ports:
        - containerPort: 5678
```

```
$ kubectl apply -f echo_service.yaml

# echo_service.yaml
apiVersion: v1
kind: Service
metadata:
  name: echo
  namespace: echo
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
```

```
kubectl apply -f echo_ingress.yaml

# echo_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  namespace: echo
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: <YOUR_DOMAIN_NAME>
    http:
      paths:
      - backend:
          serviceName: echo
          servicePort: 80
```

Once all of these templates have been applied to your cluster, your new service will be available at the domain name you specified. The way that `nginx-ingress` knows to expose your service is through the annotation on the Ingress template: `kubernetes.io/ingress.class: nginx`.

## What's Next?

Okay, so we've successfully got our cluster up and running, and we've exposed a service to the internet. Next up, we have details on how to secure our service using TLS via Jetstack's `cert-manager` and Let's Encrypt. For more information on the series, please visit the [series page](https://engi.fyi/lets-embark-setting-up-kubernetes/).