Kubernetes Deployments
- K8s deployment is just another k8s api object, But this object contains replica sets. Replica sets will contain Pods.
- K8s Deployment gives us options to
- Perform Rolling update (Zero-down time deployment)
- Perform Recreation (This will have downtime)
- Deployments with Rolling updates is the default option
- Rolling update deployments help us
- in Rolling out a new deployment
- Undo deployment and go back to previous stable version
- To create this deployment we need to write a spec. As of now i’m using the deployment for k8s 1.16 on AKS Reference and for sample deployment yaml refer microsoft documentationRefer Here
- Lets create a k8s deployment spec for sample app (jenkins:1.642.4)
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-deploy
spec:
replicas: 3
minReadySeconds: 10
selector:
matchLabels:
app: jenkins
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 25%
template:
metadata:
name: jenkins-pod
labels:
app: jenkins
ver: "1.x"
spec:
containers:
- name: jenkins
image: jenkins:1.642.4
- Since we need to access the pods, lets expose the pods using the loadbalancer by matching labels "app: jenkins"
appVersion: v1
kind: Service
metadata:
name: jenkins-svc
spec:
selector:
app: jenkins
ports:
- name: http
port: 80
targetPort: 8080
type: LoadBalancer
- Now lets apply this in k8s cluster
- Refer kubectl rollout examples
- Now a new version of docker image (i.e. your application) is released.
- Now lets look at strategy
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 25%
- Lets look at new deployment spec
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-deploy
spec:
replicas: 3
minReadySeconds: 10
selector:
matchLabels:
app: jenkins
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 25%
template:
metadata:
name: jenkins-pod
labels:
app: jenkins
ver: "2.x"
spec:
containers:
- name: jenkins
image: jenkins:latest
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc
spec:
selector:
app: jenkins
ports:
- name: http
port: 80
targetPort: 8080
type: LoadBalancer
- Now in the below screen shot you can see two revisions
- Now lets assume somethings wrong in the new version, so we have decided to go back to previous version
kubectl rollout undo deployments jenkins-deploy --to-revision=1
- Sample microservice and ingress based deployment in k8s
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-deploy
spec:
minReadySeconds: 10
progressDeadlineSeconds: 60
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1pod
image: shaikkhajaibrahim/dummymicroapp1:v1
---
apiVersion: v1
kind: Service
metadata:
name: app1svc
spec:
type: ClusterIp
ports:
- port: 5000
selector:
app: app1
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
ingressclass.kubernetes.io/is-default-class: true
spec:
rules:
- http:
paths:
- path: /app1(.*)
backend:
serviceName: app1svc
servicePort: 5000
- http:
paths:
- path: /app2(/|$)(.*)
backend:
serviceName: app2svc
servicePort: 5000
- http:
paths:
- path: /app3(/|$)(.*)
backend:
serviceName: app3svc
servicePort: 5000
Stateful Sets
- When we create pods/rs/deployments and if we want to preserve data we go for persistent volumes
- Now lets assume we are creating pods for hadoop/db clusters. Where we will multiple pods but each pod requires state to be of its own
- So stateful set will create a PV for the pod for its usage (private)
ConfigMaps and Secrets
- Generally every application needs some kind of configuration e.g. log-level, database connection string, json
- When we deploy pods for dev,qa,uat etc these configuration might change, so k8s gives easy way to handle configurations.
- You create config map
- Create a config map
---
apiVersion: v1
kind: ConfigMap
metadata:
name: dummy1
namespace: default
data:
log_level: info
app1: qtidentity
- Use them in the Pod spec
---
apiVersion: v1
kind: Pod
metadata:
name: alpine-pod
spec:
containers:
- image: alpine
name: alpine
resources:
requests:
cpu: "500m"
memory: "128Mi"
command: ["sleep", "1d"]
envFrom:
- configMapRef:
name: dummy1
- What will you do if you have sensitive information like passwords etc. Then we can use Secrets Refer Here
- Secrets also will be loaded as environmental variables or files.
- Secrets can be encrypted with Keys and Certificates
k8s namesapces
- K8s is a cluster where we run Pods. All the Pods, Services, Deployments in k8s will be in a logical cluster called namespace. Persistent Volumes & Nodes will not be part of namespaces.
- Kuberenetes will have a default namespace called as default. Till now we have been creating our api objects in k8s default namesapce.
- In the same physical k8s cluster , if you want multiple logical clusters then you can create namespaces. Refer Here for official docs
Labels and annotations
- Labels in k8s are used to match different api objects like Pods, services etc.
- Labels are key value pairs where we represent information
- Annotations provide a place for storing additional metadata for k8s objects with sole purpose of assisting tools and libraries
- Annotations are also key value pairs which can be specified in the metadata section (much like lables)
metadata:
annotations:
learningthoughts.com/icon-url: "https://learningthought.in/icons.png"
Scaling and AutoScaling Kuberenetes Objects
- Kuberenetes support scale and autoscale from kubectl commands
kubectl scale --help
kubectl autoscale --help
- Refer here and also here
EKS CLuster Storage Classes and Persistent Volumes
- Amazon eks gives us the default storage class as gp2 (general purpose volume2). Refer Here
- To write storage class use the following example
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
labels:
app: mysql
spec:
containers:
- name: mysql
image: 798279872530.dkr.ecr.us-west-2.amazonaws.com/mysql:5.7
volumeMounts:
- mountPath: "/var/lib/mysql"
persistentVolumeClaim:
claimName: ebs-gp2
env:
- name: MYSQL_DATABASE
value: 'test'
- name: MYSQL_USER
value: 'directdevops'
- name: MYSQL_PASSWORD
value: 'directdevops'
- name: MYSQL_ROOT_PASSWORD
value: 'password'
ports:
- name: dbport
containerPort: 3306
protocol: TCP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-gp2
labels:
app: mysql
spec:
storageClassName: gp2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Next Steps
- How to make life simple on Kubernetes with
- Helm
- Openshift