Kubernetes Fundamental – Part 4

In Part 1, We have gone through what is Kubernetes and its architecture.

In Part 2, We have gone through the key components such as NodesNamespaces and Pods.

In Part 3, we have gone through the components such as  Service, Job and Ingress.

In this part, Lets talk through the components such ConfigMap , Secret and Volume which are used to store configurational data and sensitive information in an organised, secure and persistent way.

We will see each components with the examples that we used on the previous parts.

ConfigMAP

The ConfigMap is used to store configuration data (key-value pair) which can be accessed by the pods in the cluster. It provides separation of concern, as the configuration data will be stored in separation to pods. So, we could make changes to the configuration data without restarting the pods.

Example
# webapp-with-db-pod-service-ingress-configmap.yaml

apiVersion: v1
kind: Pod
metadata:
name: webapp-with-db
labels:
app: my-webapp
spec:
containers:
- name: webapp
image: nginx:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: webapp-config
- name: database
image: mongo:latest
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
WEBAPP_ENV: "production"
DATABASE_URL: "mongodb://database-service:27017/mydb"
  • On top of the example that we used while going through the Pod and Service components, we have created ConfigMap: webapp-config component at the end.
  • In the data section of configMap : webapp-config, it contains two key-value pair for web application.
  • In the pod : webapp-with-db, we have defined the envFrom field and it contains reference to the configMap: webapp-config that we have mentioned before.
  • Now the pod can access the configuration : WEBAPP_ENV and DATABASE_URL to be used by the application.

Secret

The Secret is used to store sensitive information such as username, password, API Key or certificates which we can’t store it in the configMap. It is also store data in key-value pair. It will encode data in base64 format and mounted as files or environment variables in a pod.

Example
# webapp-with-db-pod-service-ingress-configmap-secret.yaml

apiVersion: v1
kind: Pod
metadata:
name: webapp-with-db
labels:
app: my-webapp
spec:
containers:
- name: webapp
image: nginx:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: webapp-config
- name: database
image: mongo:latest
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
WEBAPP_ENV: "production"
DATABASE_URL: "mongodb://database-service:27017/mydb"
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: <base64-encoded-username>
password: <base64-encoded-password>
  • We have added a new block for Secret: db-credentials .
  • In the block, we defined the data section that contain two sensitive data: username and password .
  • In the pod definition, we have added the environment variables and it referenced the secrets using secretKeyRef field.
  • In the secretKeyRef field, we specify the name : db-credentials of the secret and key is name of key specified in the data section of the Secret : db-credentials block.

VOLUME

The Volume is a directory used to store the data that can be accessible to all the containers. As it stores the data persistently in the separate storage from the pods, it will retain the data even though the pod/container is restarted or rescheduled.

Example

In this example, we will use the PersistentVolumeClaim (PVC) to dynamically provision a PersistentVolume (PV) and attach it to the database container.

# webapp-with-db-pod-service-ingress-configmap-secret-volume.yaml

apiVersion: v1
kind: Pod
metadata:
name: webapp-with-db
labels:
app: my-webapp
spec:
containers:
- name: webapp
image: nginx:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: webapp-config
- name: database
image: mongo:latest
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: db-data
mountPath: /data/db
volumes:
- name: db-data
persistentVolumeClaim:
claimName: database-pvc
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
WEBAPP_ENV: "production"
DATABASE_URL: "mongodb://database-service:27017/mydb"
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: <base64-encoded-username>
password: <base64-encoded-password>
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

  • Here we have created a block for a volume, PersistentVolumeClaim : database-pvc .
  • In the PersistentVolumeClaim , we specify the storage requirement with IGi storage volume.
  • In the pod definition, we created a volume : db-data and it should dynamically provisioned using the database-pvc PVC.
  • The database container is configured to mount this volume at /data/db. It ensures the data written inside the container will be saved in to the specified volume path (db-data).
  • With this setup, MongoDB data will stored in to db-data volume and backed up by dynamically provisioned PersistentVolume. So, the MongoDB data will be retained there even though the container will restarted or rescheduled on a different node.

Below, let us discuss about Deployment and StatefulSet as it ensures high availability, scalability and persistent storage. Both will be responsible for running the stateless and stateful applications.

Deployment

The deployment is a high level of abstraction in the Kubernetes and it manages the group of identical pods. It works well for stateless application when individual pods are interchangeable. It provides feature such as rolling updates, rollback, and scaling make fit well for Web Server, API and Mircoservices.

Example
# webapp-with-db-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-webapp
template:
metadata:
labels:
app: my-webapp
spec:
containers:
- name: webapp
image: nginx:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: webapp-config
- name: database
image: mongo:latest
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: db-data
mountPath: /data/db
volumes:
- name: db-data
persistentVolumeClaim:
claimName: database-pvc
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
WEBAPP_ENV: "production"
DATABASE_URL: "mongodb://database-service:27017/mydb"
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: <base64-encoded-username>
password: <base64-encoded-password>
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
  • We have replaced Pod resource with Deployment type : webapp-deployment.
  • The replicas is set to 3, when the deployment is executed, it will create 3 instances of web application and database running inside the cluster.
  • The Deployment will ensure the availability of pods based on specified replicas by automatically creates a pod when the pod is failed or crashed. So, it facilitates high availability.

Statefulset

StatefulSet provides statefulness to the applications by providing each pod an unique identity, persistent storage and stable network identity. It works well for databases and key-value pair storage which requires persistent storage and ordered scaling.

Example
# webapp-with-db-deployment-and-statefulset.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-webapp
template:
metadata:
labels:
app: my-webapp
spec:
# ... (same as the previous Deployment config)
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
WEBAPP_ENV: "production"
DATABASE_URL: "mongodb://database-service:27017/mydb"
---
apiVersion: v1
kind: StatefulSet
metadata:
name: database-statefulset
spec:
serviceName: database
replicas: 1
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
containers:
- name: database
image: mongo:latest
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeClaimTemplates:
- metadata:
name: database-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
  • We have created a block StatefulSet resource: database-statefulset.
  • The replicas is set to 1, if it requires any scaling, it needs manual intervention.
  • The StatefulSet ensures unique identity and stable host for each pod. It makes ideal for database or any persistent storage.

Hope it make sense about storage component and running a stateful/stateless applications.

I believe that I have covered most of key components of Kubernetes. In the next part, we will go through Kubernetes Configuration.

Happy Container’ising 🙂

One thought on “Kubernetes Fundamental – Part 4”

Leave a comment