- 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
- 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 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
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
- How to make life simple on Kubernetes with