Applications
Web demo app¶
Describe the application¶
We will deploy an nodejs application that return Hello world from...
the hostname hosting the app. Sources available into app/webtest
directory.
The application code :
'use strict';
var os = require('os');
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send("Hello world from " + os.hostname() + " (" + os.release() + ")\n");
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
The Dockerfile
to create the container image :
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
Deployment¶
From the kubernetes master (rake shell
), create a Kubernetes deployment with file apps/webtest/kubefiles/deploy.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webtest
labels:
app: webtest
spec:
replicas: 4
selector:
matchLabels:
app: webtest
template:
metadata:
labels:
app: webtest
spec:
containers:
- name: webtest
image: registry.gitlab.inria.fr/pmorillo/g5k8s/webtest:latest
ports:
- containerPort: 8080
Create a Kubernetes service with file app/webtest/kubefiles/service.yaml
:
kind: Service
apiVersion: v1
metadata:
name: webtest
labels:
app: webtest
spec:
selector:
app: webtest
ports:
- port: 8080
targetPort: 8080
protocol: TCP
Create resources :
kubectl create -f /mnt/home/repos/gitlab/g5k8s/apps/webtest/kubefiles/
Show the deployment :
kubectl get all --selector=app=webtest -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
pod/webtest-5848c4954c-4q4mm 1/1 Running 0 32m 10.244.4.2 kubenode3 <none>
pod/webtest-5848c4954c-gg8rt 1/1 Running 0 32m 10.244.3.2 kubenode2 <none>
pod/webtest-5848c4954c-ncvsl 1/1 Running 0 32m 10.244.1.2 kubenode1 <none>
pod/webtest-5848c4954c-s5f7w 1/1 Running 0 32m 10.244.2.3 kubenode0 <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/webtest ClusterIP 10.110.132.150 <none> 8080/TCP 30m app=webtest
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/webtest 4 4 4 4 32m webtest pmorillon/webtest:latest app=webtest
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/webtest-5848c4954c 4 4 4 32m webtest pmorillon/webtest:latest app=webtest,pod-template-hash=1404705107
We can see 4 replicas deployed on 4 nodes (kubenode0, kubenode1, kubenode2, kubenode3) and a service exposed on 10.110.132.150:8080
.
Show logs from pods :
kubectl logs webtest-5848c4954c-4q4mm
> webtest@1.0.0 start /usr/src/app
> node server.js
Running on http://0.0.0.0:8080
Check the service¶
for i in $(seq 1 10); do curl http://10.110.132.150:8080; done
Hello world from webtest-5848c4954c-s5f7w (4.15.0-20-generic)
Hello world from webtest-5848c4954c-4q4mm (4.15.0-20-generic)
Hello world from webtest-5848c4954c-gg8rt (4.15.0-20-generic)
Hello world from webtest-5848c4954c-4q4mm (4.15.0-20-generic)
Hello world from webtest-5848c4954c-s5f7w (4.15.0-20-generic)
Hello world from webtest-5848c4954c-ncvsl (4.15.0-20-generic)
Hello world from webtest-5848c4954c-ncvsl (4.15.0-20-generic)
Hello world from webtest-5848c4954c-4q4mm (4.15.0-20-generic)
Hello world from webtest-5848c4954c-4q4mm (4.15.0-20-generic)
Hello world from webtest-5848c4954c-s5f7w (4.15.0-20-generic)
Expose service with external IP¶
Edit webtest
service and replace spec.type
ClusterIP
by LoadBalancer
:
kubectl edit svc webtest
kubectl get svc webtest
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# webtest LoadBalancer 10.47.168.86 10.158.1.1 8080:30641/TCP 6m50s
From the frontend :
curl http://10.158.1.1:8080
# Hello world from webtest-77764787cc-qq6cz (4.19.0-8-amd64)