0% found this document useful (0 votes)
5 views15 pages

Installphpngiinxotro

This tutorial guides users on deploying a MySQL-connected NodeJS application with SSL on a Kubernetes cluster. It covers the steps to package the app into a Docker image, set up a persistent MySQL database, and configure SSL certificates using Let's Encrypt. The tutorial emphasizes the ease of managing infrastructure through Kubernetes YAML files, allowing for flexibility across cloud providers.

Uploaded by

carrionjoser
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views15 pages

Installphpngiinxotro

This tutorial guides users on deploying a MySQL-connected NodeJS application with SSL on a Kubernetes cluster. It covers the steps to package the app into a Docker image, set up a persistent MySQL database, and configure SSL certificates using Let's Encrypt. The tutorial emphasizes the ease of managing infrastructure through Kubernetes YAML files, allowing for flexibility across cloud providers.

Uploaded by

carrionjoser
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

medium.com

NodeJS app with database over SSL


on Kubernetes - Łukasz Wolnik -
Medium
Łukasz Wolnik

9-12 minutos

In this tutorial I will show you how to push a MySQL-connected


NodeJS app live on app.your-domain.com with a valid SSL
certificate running on a Kubernetes cluster.

No prior knowledge on Kubernetes is required to follow it.


NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

Fig 1. Your app running on a Kubernetes cluster

My minimal requirements for an app to be ready for production


are:

it’s must be private, i.e. pulled from a private Docker repository

it’s accessible over HTTPS (port 443) with a valid SSL


certificate

it has an access to a persistent database (in this case,


MySQL)

What I won’t cover here is advanced load balancing, CDN,


analytics, monitoring, backups, DDoS mitigation, etc.

In this tutorial you will learn how to:

package your app into a Docker image

push the image to a private Docker repository

setup a database on a persistent volume

run your app on Kubernetes and connect it with a database

Or visually speaking we will transition from a well-known setup


depicted below:
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

Fig 2. Typical VPS installed and configured manually.

to this:
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

Fig 3. Result of automating installation and configuration of a


typical MySQL, NodeJS app in Kubernetes cluster.

Prerequisites

The only requirement for this tutorial is to have a Kubernetes


cluster running, i.e. it must have at least one worker node.

If you haven’t got an access to Kubernetes you can either


create your own cluster or if you don’t want to master the
kubeadm command just yet use a paid provider (Amazon,
Azure, OVH) that will deal with all the setup and maintenance.

Kubernetes cluster

You can easily check if you have an access to a Kubernetes


cluster using kubectl command in your terminal. Make sure
you have kubectl installed on your system first.

$ kubectl cluster-info

You should see an output beginning with:

Kubernetes master is running at


https://k8s.example.com
KubeDNS is running at https://k8s.example.com
/api/v1/namespaces/kube-system/services/kube-
dns:dns/proxy

Dockerize your app


NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

Kubernetes requires an app to be packaged into a container. By


default it’s using Docker containers.

For a NodeJS app start with creating the following two files in
your NodeJS root directory, i.e. where your index.js file is.

First create .dockerignore:

node_modules
npm-debug.log

that will ensure that we won’t be storing the heavy


node_modulesfolder inside a Docker image. Now create a
Dockerfile:

FFROM node:8WORKDIR /usr/src/app


COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000CMD [ "node", "./index.js" ]

It will simply create a container with a NodeJS already installed,


install our app’s dependencies from package.json and lastly
run our app.

Docker private repository

If your project is not an open-source one you may wish to have


your Docker image stored on a private repository. Docker Hub
offers one private Docker repository for free but if you wish to
have more private repos you may want to use a free plan from
canister.io which offers up to 20 private repos.
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

On your local machine sign in to your Docker repository by:

docker login cloud.canister.io:5000

It will save your auth token in your home directory, i.e.


~/.docker/config.json.

Now build your NodeJS app’s Docker image and push it to your
private repository.

Your Kubernetes cluster also needs to be authorised to pull your


NodeJS app’s private Docker image. The way to store sensitive
data on Kubernetes are configuration YAML files named
Secrets. To generate a Secret — named regcred — on our
cluster that contains our Docker private repo’s authentication
token run:

kubectl create secret generic regcred --from-


file=.dockerconfigjson=~/.docker/config.json
--type=kubernetes.io/dockerconfigjson

From now on if your deployment points to a Docker image on a


private repo, your Kubernetes cluster will use the auth token
stored in regcred to obtain access to it.

Deploy your NodeJS app

To deploy your app on your Kubernetes cluster create a


deployment instructions in a node.yml file that reads:

apiVersion: apps/v1
kind: Deployment
metadata:
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

name: node-deployment
spec:
replicas: 2
selector:
matchLabels:
app: node
template:
metadata:
labels:
app: node
spec:
containers:
- name: node
image:
cloud.canister.io:5000/yourname/imagename
ports:
- containerPort: 3000
imagePullSecrets:
- name: regcred # secret that K8s uses
to access image
---
apiVersion: v1
kind: Service
metadata:
name: node
spec:
selector:
app: node
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

ports:
- port: 80 # expose the service on internal
port 80
targetPort: 3000 # our NodeJS app listens
on port 3000

Deploy on your Kubernetes cluster:

kubectl apply -f node.yml

MySQL database

Deploying a database on a cluster doesn’t differ from deploying


your NodeJS app. The only difference is that we want our
database to persist the data whenever the MySQL pod is
destroyed and recreated. And for that we need a persistent
storage where database’s data will be stored on a permanent
physical disk.

Kubernetes uses Persitent Volume (PV) and Persistent Volume


Claim (PVC) to describe a persistent storage. PVC is what
deployments refers to when they need a persistent volume.

Below is an example of 10GB persistent volume (refer to your


Kubernetes provider for a proper storageClassName). For
OVH provider it’s cinder-high-speed , i.e. an SSD. Create a
new file mysql-pv.yml and copy & paste below:

kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv-volume
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

labels:
type: local
spec:
storageClassName: cinder-high-speed # CHANGE
HERE
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: cinder-high-speed # CHANGE
HERE
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

Run on your cluster:

kubectl create -f ./mysql-pv.yml

Having set up a persistent volumes we can finally deploy


NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

MySQL on the cluster by creating mysql.yml file with below


contents:

apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: NodePort
ports:
- port: 3306
targetPort: 3306
nodePort: 31306 # exposed port we can
communicate to
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: yourR4ndomP455w0rd
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim

On the last line we refer to the Persistent Volume Claim


prescribed in the mysql-pv.yml file.

Deploy your MySQL service:

kubectl apply -f ./mysql.yml

Let’s Encrypt SSL certificates

Days of the paid SSL certificates are luckily gone thanks to Let’s
Encrypt which provides free SSL certificates. But that’s not the
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

only benefit of it, it also gives you fully automated processes to


issue certificates for your domains.

Add an issuer to your Kubernetes cluster by creating prod-


issuer.yml file with below content:

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: node-ssl-prod
spec:
acme:
server: https://acme-
v02.api.letsencrypt.org/directory
email: your@email.com # CHANGE TO YOUR
EMAIL HERE
privateKeySecretRef:
name: node-ssl-prod
http01: {}

Run the issuer on your cluster:

kubectl create -f ./prod-issuer.yml

Grande finale

Expose your NodeJS app using Ingress, which is a routing


mechanism for HTTP and HTTPS requests hitting your
Kubernetes cluster.

Install ingress-nginx on your cluster using Helm:

helm install stable/nginx-ingress --namespace


NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

kube-system --name nginx-ingress

Create ingress-node.yml file with below content:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: node-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: node-
ssl-prod
spec:
tls:
- hosts:
- app.yourdomain.com
secretName: node-ssl-prod
rules:
- host: app.yourdomain.com
http:
paths:
- path: /*
backend:
serviceName: lockjs
servicePort: 80 - backend:
serviceName: node
servicePort: 80

Deploy using:

kubectl create -f ./ingress-node.yml


NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

Above ingress-node.yml configuration will automatically ask


our cluster’s issuer — named node-ssl-prod — to get a
certificate for app.yourdomain.com.

You can now securely access your NodeJS app via HTTPS by
typing https://app.yourdomain.com in a browser.

Conclusion

Comparing schematics of the infrastructures in figures 2 and 3


one may wonder if the effort of moving to Kubernetes was worth
it for such a small project.

I believe it was even for a personal project like this. One of the
great consequences of deploying apps on Kubernetes is its
requirement to describe every piece of an infrastructure in a file.
In this tutorial we used the following files: node.yml, mysql-
pv.yml, mysql.yml, prod-issuer.yml and ingress-
node.yml.

Quite a lot for a little NodeJS app but it allowed us to


encapsulate all the infrastructure requirements in a
standardised way using Kubernetes YAML files. Which in turn
liberates us to use any cloud provider (including our very own)
without being forced to be locked-in in AWS, Azure or Google
vendor’s specific solutions. You don’t need to spend any extra
time to learn new cloud provider’s tools of trade. You can simply
feed a new Kubernetes cluster with a handful of files and
Kubernetes will do the rest.
NodeJS app with database over SSL on Kubernetes - Łukasz... about:reader?url=https://medium.com/@lukaszwolnik/nodejs...

You might also like