CCP2 CNA Kubernets LAB
Page content
12 factor Applications LAB
Overview
- Cloud-Native application is an application optimized for running in the cloud (IaaS or PaaS)
- Each phase in the application life-cycle has to be adopted and optimized to run in the cloud
- typically desigened as a distributed application
LAB
Used Applications
- K3S: a lightweigt Kubernetes designed to run on low-ressource systems
fully CNCF-certified - K3D: a wrapper to run K3s in Docker
makes it easy to run single- and multi-node k3s clusters i.e. for local development of kubernetes
Commands
| Command | Description |
|---|---|
| k3d cluster delete --all | delete all running clusters |
| k3d cluster create --config ./lab-setup/k3d-ccp2-config.yaml | create new cluster with config file |
| kubectl cluster-info | check status of cluster |
| kubect create namespace ccp2-lab | using a non default namespace to deploy the application |
| kubectl -n ccp2-lab get all | -n tell kubectl which namespace to use |
| ./gradlew assemble | compile and package the spring boot application |
| docker-build.sh | script to create docker images (see scripts section |
| docker push registry.localhost:5000/ccp2-postgres:latest | push image to local registry |
| docker push registry.localhost:5000/ccp2-order:1 | same |
| kubectl apply -f postgres.yaml | apply deployment |
| kubectl create secret generic postgres-secret --from-literal=postgres-user=ccp2DbUser --from-literal=postgres-password=newFancyPassword |
create secret with db credentials |
| kubectl get secret postgres-secret -o yaml | show created secret |
| kubectl describe pod/postgres-7bfd5c7d7b-8f5wn | get debug info on a pod |
Task3 externalizing config
using secrets
kubectl create secret generic postgres-secret
--from-literal=postgres-user=ccp2DbUser
--from-literal=postgres-password=newFancyPassword
Modifications to postgres.yaml
…
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
key: postgres-user
name: postgres-secret
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: postgres-password
name: postgres-secret
Modifications to microservices.yaml
spec:
containers:
- name: order
image: registry.localhost:5000/ccp2-order:1
imagePullPolicy: Always
ports:
- containerPort: 8080
resources: {}
env:
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
key: postgres-user
name: postgres-secret
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
key: postgres-password
name: postgres-secret
using config maps
used when config contains no critical info like passwords and doesn’t need to be obfuscated
create config map
kubectl create configmap pg-init-user-db
--from-file=postgres/init-user-db.sh
changes to deployment manifest
spec:
containers:
- name: postgres
image: postgres:14.0
imagePullPolicy: IfNotPresent
And add the following volumeMounts and volumes to the container section:
volumeMounts:
- name: postgres
mountPath: /var/lib/postgresql/data
- name: init-user-db
mountPath: /docker-entrypoint-initdb.d
volumes:
- name: postgres
emptyDir: {}
- name: init-user-db
configMap:
name: pg-init-user-db
once config map and secrets are created and yaml files update restart the postgres pod by chaning replicas to 0 and back to 1
kubectl scale --replicas=0 deployment.apps/postgres deploy/order
kubectl scale --replicas=1 deployment.apps/postgres deploy/order
Files
microservices.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: order
version: "1.0"
name: order
spec:
replicas: 1
selector:
matchLabels:
app: order
strategy: {}
template:
metadata:
labels:
app: order
spec:
containers:
- name: order
image: registry.localhost:5000/ccp2-order:1
imagePullPolicy: Always
ports:
- containerPort: 8080
resources: {}
env:
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
key: postgres-user
name: postgres-secret
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
key: postgres-password
name: postgres-secret
---
apiVersion: v1
kind: Service
metadata:
labels:
app: order
name: order
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
name: http
selector:
app: order
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: order
labels:
name: order
spec:
rules:
- host: order.160.85.253.63.nip.io
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: order
port:
number: 80
postgres.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: postgres
version: "1.0"
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
strategy: {}
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
key: postgres-user
name: postgres-secret
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: postgres-password
name: postgres-secret
resources: {}
volumeMounts:
- name: postgres
mountPath: /var/lib/postgresql/data
- name: init-user-db
mountPath: /docker-entrypoint-initdb.d
volumes:
- name: postgres
emptyDir: {}
- name: init-user-db
configMap:
name: pg-init-user-db
status: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
app: postgres
name: postgres
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
app: postgres
type: NodePort
status:
loadBalancer: {}
k3d config
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: ccp2
servers: 1
agents: 2
image: docker.io/rancher/k3s:v1.22.6-k3s1
kubeAPI:
host: api.160.85.253.63.nip.io
hostIP: "0.0.0.0"
hostPort: "6443"
ports:
- port: 0.0.0.0:80:80 # same as `--port '8080:80@loadbalancer'`
nodeFilters:
- loadbalancer
- port: 0.0.0.0:443:443 # same as `--port '8443:443@loadbalancer'`
nodeFilters:
- loadbalancer
- port: 127.0.0.1:9000:9000 # traefik dashboard only local
nodeFilters:
- loadbalancer
volumes: # map directory for local-path-provisioner
- volume: $HOME/storage:/var/lib/rancher/k3s/storage
nodeFilters:
- all
registries:
create: # creates a default registry to be used with the cluster; same as `--r
egistry-create registry.localhost`
name: registry.localhost
host: "0.0.0.0"
hostPort: "5000"
options:
k3d:
wait: true # wait for cluster to be usable before returini
ng; same as `--wait` (default: true)
timeout: "60s" # wait timeout before aborting; same as `--time out 60s`
disableLoadbalancer: false # same as `--no-lb`
disableImageVolume: false # same as `--no-image-volume`
disableRollback: false # same as `--no-Rollback`
k3s:
extraArgs:
- arg: --tls-san=api.160.85.253.63.nip.io
nodeFilters:
- server:*
- arg: --node-taint=CriticalAddonsOnly=true:NoExecute # set server nodes t o not run pods
nodeFilters:
- server:*
docker-build.sh
#!/bin/sh
docker build --tag=ccp2-postgres postgres
docker tag ccp2-postgres registry.localhost:5000/ccp2-postgres
docker build --tag=ccp2-order:1 microservice-order
docker tag ccp2-order:1 registry.localhost:5000/ccp2-order:1