Deploy a NodeJS App on Kubernetes and Rancher | SUSE Communities

Deploy a NodeJS App on Kubernetes and Rancher

Share

Kubernetes
ghostRancher recently
shipped 1.0 which added support for the Kubernetes
orchestration

framework. Now, you can leverage the capabilities of Kubernetes with
your Rancher environments. Kubernetes is an open-source cluster
management framework for application containers started by Google; it’s
designed to provide a simple way to deploy, schedule, scale, and roll
out new features of applications by providing a container-centric
environment without depending on the underlying infrastructure. The
native support for Kubernetesin
Rancher gives you the ability to launch multiple Kubernetes clusters and
Rancher will take care of deploying these clusters into your
environment, also, it adds several features including:

  • Node provisioning through Docker Machine.
  • UI to manage Kubernetes cluster from Rancher.
  • Leveraging Rancher Load balancers to route traffic to Kubernetes
    services and pods.
  • One-click deployments for applications and microservices using
    Rancher catalog templates for Kubernetes.

Today I will provide an overview of using Kubernetes in Rancher by
deploying a NodeJS application on the Kubernetes environment.

Starting Kubernetes Cluster within Rancher

After Installing Rancher platform
and adding a few hosts, you should be able to access the Rancher
environments by navigating to Manage Environments by clicking on the
environment name: HG
1
Click on “Add new environment,” or simply edit the current environment.
Now, you will have the option to choose between different cluster
management platforms for your hosts. The default is the Rancher native
Cattle clustering. Also, you will have two more options: Kubernetes and
Docker Swarm. After choosing Kubernetes and clicking on save, you will
notice new menu items including Kubernetes, which will provide a UI to
manage the kubernetes cluster. HG
2
Rancher will start to deploy containers to get the Kubernetes cluster
running. These containers include core functions such as etcd and the
kubernetes API server, as well as kubelets and proxys on each computing
host.: HG
3

KubeCTL in Rancher

Rancher includes full access to Kubectl, which is a command line
interface to manage the Kubernetes cluster. Also, Rancher adds the
ability to generate and copy the configuration file for kubectl to add
to your own local machine: HG
4
Kubectl is installed using
gcloud.
You can copy the configuration for kubectl and add it to
~/.kube/config, and start using kubectl from your local computer:

$ kubectl get nodes
NAME      LABELS    STATUS    AGE

node-1    beta.kubernetes.io/instance-type=rancher,failure-domain.alpha.kubernetes.io/region=Region1,failure-domain.alpha.kubernetes.io/zone=FailureDomain1,kubernetes.io/hostname=node-1   Ready     1h

Getting the NodeJS Application Ready

Now that I have Kubernetes in place, I will start building my app by
creating the Docker image for the NodeJS application. I am going to use
the blogging application Ghost, which already has an official Docker
image. But, we will do minor tweaks to this image to add support for a
MySQL database. The Docker image is based on the official ghost
image
; in addition, it
adds a custom entry point, and configuration file:

FROM ghost: latest

COPY docker-entrypoint.sh /entrypoint.sh

RUN chmod u+x /entrypoint.sh

COPY config-example.js /config-example.js

ENTRYPOINT ["/entrypoint.sh"]

CMD ["npm", "start", "--production"]

The custom configuration file for ghost will add placeholders to be
replaced with values of Ghost database and username/password:

database: {

client: 'mysql',

connection: {

host     : 'mysql',

user     : 'GHOST_USER',

password : 'GHOST_PASSWORD',

database : 'GHOST_DB',

charset  : 'utf8'

}

}

Then the entry point will be responsible to replace these placeholders
with the actual values parsed from the environment variables passed to
the image. Here is a snippet from the entry point:

if [ ! -e "$GHOST_CONTENT/config.js" ]; then

sed -r "

s/GHOST_DB/$GHOST_DB/g;

s/GHOST_USER/$GHOST_USER/g;

s/GHOST_PASSWORD/$GHOST_PASSWORD/g;

s!path.join(__dirname, (.)/content!path.join(process.env.GHOST_CONTENT, 1!g;

" "/config-example.js" > "$GHOST_CONTENT/config.js"

fi

You can build and push the image to an accessible registry, which will
be available to your kubernetes cluster:

$ docker build -t husseingalal/ghost ghost/

$ docker push husseingalal/ghost

Creating Pods and Services for Ghost

I will create simple pods to serve the ghost application and mysql. Pods
are the smallest deployable units of computing that can be set up and
managed in Kubernetes, which represents a group of containers that are
related to each other. In our example, I will create a pod for MySQL and
another one for the nodejs application, the pod configuration MySQL will
look like this:

apiVersion: v1

kind: Pod

metadata:

name: mysql

labels:

name: mysql

spec:

containers:

- image: mysql

name: mysql

env:

- name: MYSQL_ROOT_PASSWORD

value: mysqlrootpassword

- name: MYSQL_DATABASE

value: ghost

- name: MYSQL_USER

value: ghost_user

- name: MYSQL_PASSWORD

value: ghost_pass

ports:

- containerPort: 3306

name: mysql

volumeMounts:

- name: mysql-vol

mountPath: /var/lib/mysql

livenessProbe:

tcpSocket:

port: "mysql"

initialDelaySeconds: 5

timeoutSeconds: 1

readinessProbe:

exec:

command: ["mysqladmin", "status", "-pmysqlrootpassword"]

volumes:

- name: mysql-vol

hostPath:

path: /var/lib/mysql

The services in Kubernetes are an abstraction that defines a logical
set of Pods. We will create a service for each set of pods in
Kubernetes. The MySQL service will look like this:

apiVersion: v1

kind: Service

metadata:

labels:

name: mysql

name: mysql

spec:

ports:

- port: 3306

selector:

name: mysql

The ghost pod and service will look similar to both the pod and the
service for MySQL:

apiVersion: v1

kind: Pod

metadata:

name: ghost

labels:

name: ghost

spec:

restartPolicy: Always

containers:

- image: "husseingalal/ghost"

imagePullPolicy: Always

name: "ghost"

ports:

- containerPort: 2368

env:

- name: GHOST_USER

value: ghost_user

- name: GHOST_PASSWORD

value: ghost_pass

- name: GHOST_DB

value: ghost

volumeMounts:

- name: ghost-vol

mountPath: /var/lib/ghost

volumes:

- name: ghost-vol

hostPath:

path: /var/lib/ghost



ghost-service.yaml
apiVersion: v1

kind: Service

metadata:

labels:

name: ghost-lb

name: ghost-lb

spec:

ports:

- port: 2368

selector:

name: ghost

type: LoadBalancer

You may notice the type in the ghost-service.yaml file to be
LoadBalancer, Rancher will provide a load balancer to distribute the
requests to defined pods. You can create the pods and services using
kubectl:

$ for i in *.yaml; do kubectl create -f $i; done

service "ghost-lb" created

pod "ghost" created

service "mysql" created

pod "mysql" created

You can see in Rancher UI for kubernetes the new services and pods are
being created: HG
5
In addition, you can check for the pods and services using the command
line:

$ kubectl get pods

NAME      READY     STATUS    RESTARTS   AGE

ghost       1/1             Running     0                   15m

mysql      1/1              Running     0                   20m
kubectl get services

NAME         CLUSTER_IP     EXTERNAL_IP   PORT(S)    SELECTOR     AGE

ghost-lb     10.43.27.14                  2368/TCP   name=ghost   22m

kubernetes   10.43.0.1      <none>        443/TCP    <none>       2h

mysql        10.43.51.244   <none>        3306/TCP   name=mysql   22m

You can test the previous setup by accessing the ghost application
directly: HG
6

Conclusion

Kubernetes is a great addition to the Rancher management platform. It
leverages a lot of features and services for your own customized
environment. You can learn more about using Kubernetes by visiting the
official documentation. You
can now start creating your own Kubernetes
cluster within your Rancher
environment. To learn more about running containers with Kubernetes,
view a recording of our recent meetup on deploying Kubernetes environments,
or download a copy of our eBook on modernizing CI/CD with Docker and
Rancher.