This practical work will consist of creating Kubernetes objects to deploy an example stack: monster_stack. It is composed of:
You can use either your Cloud environment or Minikube.
Reminder: Install Lens
Lens is a nice graphical interface for Kubernetes.
It connects using the default ~/.kube/config configuration and allows us to access a much more pleasant dashboard.
You can install it by running these commands:
sudo apt-get update; sudo apt-get install -y libxss-dev curl -fSL https://github.com/lensapp/lens/releases/download/v4.0.6/Lens-4.0.6.AppImage -o ~/Lens.AppImage chmod +x ~/Lens.AppImage ~/Lens.AppImage &
Deploying the monsterstack stack
Pods are sets of containers always kept together.
We would like to deploy our monster_app stack. We will start by creating a pod with only our monstericon container.
apiVersion: apps/v1 kind: Deployment metadata: name: monstericon labels: <labels>
This file expresses an empty deployment object.
Add the label app: monsterstack to this Deployment object.
For now, our deployment is not defined because it does not have a spec: section.
The first step is to propose a ReplicaSet template for our deployment. Add the following (spec: should be at the same level as kind: and metadata:)
spec: template: spec:
Fill in the spec section of our monstericon pod from a pod template launching an Nginx container:
containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
metadata: labels: app: monsterstack partie: monstericon
At this stage, we have described the pods of our deployment with their labels (a common label to all objects of the app, a more specific label to the sub-part of the app).
Now it is a matter of adding some options to configure our deployment (at the level of template:):
selector: matchLabels: app: monsterstack partie: monstericon strategy: type: Recreate
This section indicates the labels to use to identify the pods of this deployment among others.
Then the update strategy (rollout) of the pods for the deployment is specified: Recreate designates the most brutal strategy of complete pod deletion and redeployment.
Finally, just before the line selector: and at the level of the strategy: keyword, add replicas: 3. Kubernetes will create 3 identical pods during the monstericon deployment.
The monstericon.yaml file so far:
apiVersion: apps/v1 kind: Deployment metadata: name: monstericon labels: app: monsterstack spec: template: spec: containers: - name: monstericon image: tecpi/monster_icon:0.1 ports: - containerPort: 9090 metadata: labels: app: monsterstack partie: monstericon selector: matchLabels: app: monsterstack partie: monstericon strategy: type: Recreate replicas: 3
readinessProbe: failureThreshold: 5 # Retry 5 times httpGet: path: / port: 9090 scheme: HTTP initialDelaySeconds: 30 # Wait 30s before testing periodSeconds: 10 # Wait 10s between each try timeoutSeconds: 5 # Wait 5s for response
This way, k8s will be able to know if the container is working well by calling the /. route. This is a good practice for Kubernetes to know when to restart a pod.
resources: requests: cpu: "100m" memory: "50Mi"
Our pods will then be guaranteed to have one-tenth of a CPU and 50 megabytes of RAM.
Final monstericon.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: monstericon labels: app: monsterstack spec: template: spec: containers: - name: monstericon image: tecpi/monster_icon:0.1 ports: - containerPort: 9090 readinessProbe: failureThreshold: 5 # Retry 5 times httpGet: path: / port: 9090 scheme: HTTP initialDelaySeconds: 30 # Wait 30s before testing periodSeconds: 10 # Wait 10s between each try timeoutSeconds: 5 # Wait 5s for response resources: requests: cpu: "100m" memory: "50Mi" metadata: labels: app: monsterstack partie: monstericon selector: matchLabels: app: monsterstack partie: monstericon strategy: type: Recreate replicas: 5
Similar deployment for dnmonster. Now we will also create a deployment for dnmonster:
apiVersion: apps/v1 kind: Deployment metadata: name: dnmonster labels: app: monsterstack spec: selector: matchLabels: app: monsterstack partie: dnmonster strategy: type: Recreate replicas: 5 template: metadata: labels: app: monsterstack partie: dnmonster spec: containers: - image: amouat/dnmonster:1.0 name: dnmonster ports: - containerPort: 8080
Finally, configure a third deployment redis:
apiVersion: apps/v1 kind: Deployment metadata: name: redis labels: app: monsterstack spec: selector: matchLabels: app: monsterstack partie: redis strategy: type: Recreate replicas: 1 template: metadata: labels: app: monsterstack partie: redis spec: containers: - image: redis:latest name: redis ports: - containerPort: 6379
Expose our stack with services
K8s services are network endpoints that automatically balance traffic to a set of pods designated by certain labels.
To create a Service object, use the following code, to be completed:
apiVersion: v1 kind: Service metadata: name: <service_name> labels: app: monsterstack spec: ports: - port: <port> selector: app: <app_selector> partie: <tier_selector> type: <type>
Add the following code at the beginning of each deployment file. Complete for each part of our application:
The type will be: ClusterIP for dnmonster and redis because these are services that only need to be accessed internally, and LoadBalancer for monstericon.
Apply your three files.
Let's gather the three objects with a kustomization.
A kustomization allows summarizing an object contained in multiple files in one place to be able to launch it easily:
Also create a kustomization.yaml file inside with:
resources: - monstericon.yaml - dnmonster.yaml - redis.yaml
Add an Ingress load balancer to expose our application on the standard port
Let's install the Nginx Ingress controller with minikube addons enable ingress.
This is an implementation of a dynamic load balancer based on nginx configured to interface with a k8s cluster.
Also, add the following load balancer configuration object in the monster-ingress.yaml file:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: monster-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /monstericon backend: serviceName: monstericon servicePort: 9090
You should be able to access the application by running minikube service monstericon –url and adding /monstericon to access it.