My first DevOps job interview Part 2 of 3
4 min read
865 words
This article is part 2 of a 3 part series of my job interview experience as a DevOps Engineer.
In
the last part
I introduced in the exercises and talked about the complications I had with
building a Dockerimage with Chrome inside on an arm64
platform. Also the used
NodeJS app and its’ Dockerfile
was presented. This part
will be more about Kubernetes, setting up the Cluster
and deploying the NodeJS app.
Setting up a Kubernetes Cluster
After creating the Dockerfile
it was about setting up a Kubernetes cluster.
Which program I use for this was up to me. In my
DevOps with Kubernetes course we use
k3d, this implements K3s in Docker. During
the course I had not experienced any problems with this solution, so I was sure
to use k3d to solve the assignments. Installing k3d on macOS is easy via
Homebrew with brew install k3d
. The cluster can then be
created with
k3d cluster create --port '8082:30080@agent[0]' -p 8081:80@loadbalancer --agents 2
.
The 8081:80@loadbalancer
will allow our apps to be accessible to us via
localhost:8081
.
Deploying the app
With a running Kubernetes cluster, deployment was now on the agenda. I decided
from the beginning to logically separate the app from the rest of the cluster
and created a separate namespace. This is possible with
kubectl create namespace exercise-ns
in Kubernetes. The basic structure for
deployment can be found in the Kubernetes documentation
(Deployments | Kubernetes).
So I created a deployment.yaml
in my manifests
folder with the following
content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: exercise-app
namespace: exercise-ns
labels:
app: exercise-app
spec:
replicas: 1
selector:
matchLabels:
app: exercise-app
template:
metadata:
labels:
app: exercise-app
spec:
containers:
- name: exercise-app
image: niklasmtj/exercise-app:v1
To make the deployment discoverable I also created a service. The Kubernetes
documentation for services
(Deployments | Kubernetes)
again provides the basic structure. The service definition can be found under
manifests/service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: exercise-svc
namespace: exercise-ns
spec:
type: ClusterIP
selector:
app: exercise-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
It is important to note here that the targetPort
corresponds to the port
exposed by the Docker container.
Ingress
After preparing the deployment, the task was now to be able to access it. Thus,
the connection via an
Ingress came
into play. By default, K3s uses the Traefik Ingress Controller for Ingress
routing, which I also used. The ingress configuration is quite simple. In an
ingress.yaml
file I used the following configuration:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: exercise-ingress
namespace: exercise-ns
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: exercise-svc
servicePort: 80
This way the /
path is directly forwarded to the exercise
service we defined
in service.yaml
on port 80.
IP-Whitelisting
Another task I had to solve with an Ingress was to limit the IP range that is
accepted at all. Unfortunately, due to my previous knowledge, I did not had the
possibility to implement the whole thing at that time. Nevertheless I read up on
how I would implement it and documented it in my readme. During the task I took
a closer look at the NGINX Ingress Controller, because I found the most results
about it during my research. There it seems to work by a simple annotation in
the ingress.yaml
:
metadata:
annotations:
ingress.kubernetes.io/whitelist-source-range: "192.168.0.0/16"
This will make sure that only IPs from the 192.168.0.0/16
net is able to
connect to the apps. So every IP starting at 192.168.0.1
to 196.168.255.254
are eligible to connect. NGINX will drop every request not coming from this IP
range.
Also, attempts with Traefik as the Ingress controller, which is used by k3s by default, failed. This is an area I need to look at in more detail in the near future to understand exactly how Ingress works and at what level you can block IPs. Additionally, I need to look at whether it makes a difference that my k3s cluster is running inside Docker and how that affects incoming IPs.
Thank you for reading,\Niklas
The code from this post can also be found on GitHub:
niklasmtj/kubernetes-exercise.
Additionally, I created an arm64
as well as an amd64
docker image for
niklasmtj/exercise-app:v1
. So the example app should be usable on other
devices as well.
The series: