Are you trying to set up Nginx ingress on DigitalOcean Kubernetes using Helm?
This guide is for you.
Kubernetes Ingresses offer you a flexible way of routing traffic from beyond your cluster to internal Kubernetes Services. Ingress Resources are objects in Kubernetes that define rules for routing HTTP and HTTPS traffic to Services.
Helm is a package manager for managing Kubernetes. Using Helm Charts with your Kubernetes provides configurability and lifecycle management to update, rollback, and delete a Kubernetes application.
Here at Ibmi Media, as part of our Server Management Services, we regularly help our Customers to DigitalOcean related queries.
In this context, we shall look into how to set up Nginx ingress on DigitalOcean.
To set up Nginx ingress, simply follow the steps given below.
i. First, we shall create a Hello World app called hello-kubernetes so that we can have some services which we will route the traffic.
ii. Then to ensure that Nginx works Ingress properly in the next steps, we will deploy it twice.
We shall store the deployment configuration on the local machine. We shall name the first deployment configuration file as hello-kubernetes-first.yaml.
iii. So we create it using a text editor:
$ nano hello-kubernetes-first.yaml
Then we add the below code in it:
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-first
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-first
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-first
template:
metadata:
labels:
app: hello-kubernetes-first
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.7
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the first deployment!
iv. We then save and close the file.
v. Then we will create the first variant of the hello-kubernetes app in Kubernetes by running the below command:
$ kubectl create -f hello-kubernetes-first.yaml
vi. In order to verify the Service's creation, we run the below command:
$ kubectl get service hello-kubernetes-first
As a result, we see that the newly created Service has a ClusterIP assigned. It means that it is working properly.
Then all the traffic sent to it is forwarded to the selected Deployment on port 8080.
vii. Now, we have worked on the first variant of the hello-kubernetes app. So we shall move on to the second one.
For that, we open a file named hello-kubernetes-second.yaml for editing:
$ nano hello-kubernetes-second.yaml
viii. Then we add the below lines:
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-second
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-second
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-second
template:
metadata:
labels:
app: hello-kubernetes-second
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.7
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the second deployment!
ix. Then we save and close the file.
x. Now, we create it in Kubernetes with the below command:
$ kubectl create -f hello-kubernetes-second.yaml
xi. Then to verify whether the second Service is up and running or not we run the below command.
$ kubectl get service
As a result, both the hello-kubernetes-first and hello-kubernetes-second will be listed. This means that Kubernetes has created them successfully.
xii. Finally, now we have created two deployments of the hello-kubernetes app with accompanying Services.
i. Now, we shall install the Kubernetes-maintained Nginx Ingress Controller using Helm via Github:
https://github.com/kubernetes/ingress-nginx
ii. In order to install the Nginx Ingress Controller to the cluster, we run the below command:
$ helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true
The above command will install the Nginx Ingress Controller from the stable charts repository.
Then it names the Helm release nginx-ingress and sets the publishService parameter to true.
iii. Now, Helm has logged what resources in Kubernetes it created as a part of the chart installation.
Here is the command that we run to see if the Load Balancer is available:
$ kubectl get services -o wide -w nginx-ingress-controller
i. Now, we shall create an Ingress Resource to use to expose the hello-kubernetes app deployments.
ii. After that, we can test it by accessing it from the browser.
iii. We shall store the Ingress in a file named hello-kubernetes-ingress.yaml.
We create it using an editor:
$ nano hello-kubernetes-ingress.yaml
iv. Then we add the below lines:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: hw1.your_domain
http:
paths:
- backend:
serviceName: hello-kubernetes-first
servicePort: 80
- host: hw2.your_domain
http:
paths:
- backend:
serviceName: hello-kubernetes-second
servicePort: 80
Here, we define an Ingress Resource with the name hello-kubernetes-ingress.
v. Then we specify two host rules so that hw1.your_domain is routed to the hello-kubernetes-first Service, and hw2.your_domain is routed to the Service from the second deployment (hello-kubernetes-second).
vi. Then we create it in Kubernetes by running the following command:
$ kubectl create -f hello-kubernetes-ingress.yaml
Now, we navigate to hw1.your_domain in the browser, we see the “Hello from the first deployment” message.
The second variant (hw2.your_domain) will show the “Hello from the second deployment” message.
Through this, we have verified that the Ingress Controller correctly routes requests.
In order to secure the Ingress Resources, we will install Cert-Manager, create a ClusterIssuer for production, and modify the configuration of the Ingress to take advantage of the TLS certificates.
i. Before installing Cert-Manager to cluster via Helm, we will manually apply the required CRDs from the jetstack/cert-manager repository by running the following command:
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.14.1/cert-manager.crds.yaml
ii. Then, we create a namespace for cert-manager by running the following command:
$ kubectl create namespace cert-manager
iii. Next, we add the Jetstack Helm repository to Helm, which hosts the Cert-Manager chart. For that, we run the below command:
$ helm repo add jetstack https://charts.jetstack.io
iv. Finally, we install Cert-Manager into the cert-manager namespace:
$ helm install cert-manager --version v0.14.1 --namespace cert-manager jetstack/cert-manager
v. Now, we create the one that issues Let's Encrypt certificates, and we’ll store its configuration in a file named production_issuer.yaml.
We create it and open it for editing:
$ nano production_issuer.yaml
vi. Then we add the below lines:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: your_email_address
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-prod-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
vii. We then save and close the file.
viii. After that, we roll it with with kubectl:
$ kubectl create -f production_issuer.yaml
ix. Now, to introduce the certificates to the Ingress Resource defined in the previous step, we open the hello-kubernetes-ingress.yaml.
$ nano hello-kubernetes-ingress.yaml
x. Then we add the below highlighted lines:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- hw1.your_domain
- hw2.your_domain
secretName: hello-kubernetes-tls
rules:
- host: hw1.your_domain
http:
paths:
- backend:
serviceName: hello-kubernetes-first
servicePort: 80
- host: hw2.your_domain
http:
paths:
- backend:
serviceName: hello-kubernetes-second
servicePort: 80
xi. Then we re-apply this configuration to the cluster by running the following command:
$ kubectl apply -f hello-kubernetes-ingress.yaml
It would take some time for the Let's Encrypt servers to issue a certificate for the domains.
when the last line of output reads Certificate issued successfully, we exit by pressing CTRL + C.
This article covers how to set up Nginx ingress on DigitalOcean Kubernetes using Helm. To implement this successfully, an Ingress Controller must be present; its role is to implement the rules by accepting traffic (most likely via a Load Balancer) and routing it to the appropriate Services.
Most Ingress Controllers use only one global Load Balancer for all Ingresses, which is more efficient than creating a Load Balancer per every Service you wish to expose.
To install the Nginx Ingress Controller to your cluster, run the following command:
$ helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true
This command installs the Nginx Ingress Controller from the stable charts repository, names the Helm release nginx-ingress, and sets the publishService parameter to true.