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.
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 [email protected]: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 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 188.8.131.52 80:31908/TCP 3d1h
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.localat 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) 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:
Okay, so we've successfully got our cluster up and running, and we've exposed a service to the internet. Next up, head over to Part 3 where 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.