Deployments and replication
Use Cases for Multi-Container Pods
Kubectl explain Deployment
k8sworkshop git:(main) ✗ kubectl explain deployments
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the Deployment.
status <Object>
Most recently observed status of the Deployment.
➜ k8sworkshop git:(main) ✗
Kubectl explain Replicaset
➜ k8sworkshop git:(main) ✗ kubectl explain rs
KIND: ReplicaSet
VERSION: apps/v1
DESCRIPTION:
ReplicaSet ensures that a specified number of pod replicas are running at
any given time.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
If the Labels of a ReplicaSet are empty, they are defaulted to be the same
as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More
info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Spec defines the specification of the desired behavior of the ReplicaSet.
More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Status is the most recently observed status of the ReplicaSet. This data
may be out of date by some window of time. Populated by the system.
Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
➜ k8sworkshop git:(main) ✗
Overview on Kubernetes Deployment
Kubernetes also provides Deployment resource that sits on top of ReplicaSets and enables declarative application updates.
When running Pods in datacenter, additional features may be needed such as scalability, updates and rollback etc which are offered by Deployments
A Deployment is a higher-level resource meant for deploying applications and updating them declaratively, instead of doing it through a ReplicationController or a ReplicaSet, which are both considered lower-level concepts.
When you create a Deployment, a ReplicaSet resource is created underneath. Replica-Sets replicate and manage pods, as well.
When using a Deployment, the actual pods are created and managed by the Deployment’s ReplicaSets, not by the Deployment directly
Create Kubernetes Deployment resource
In the deployment spec, following properties are managed:
replicas
: explains how many copies of each Pod should be runningstrategy
: explains how Pods should be updatedselector
: uses matchLabels to identify how labels are matched against the Podtemplate
: contains the pod specification and is used in a deployment to create Podsscale
deployment:kubectl scale deployment nginx-deployment --replicas 10
set image
:kubectl set image deployment nginx-deployment nginx=nginx:1.91 --record
rollout undo
:kubectl rollout undo deployment nginx-deployment
we will create a new deployment using kubectl using –dry-run so that actually a deployment is not created but just verified
➜ k8sworkshop git:(main) ✗ kubectl create deployment nginx-deploy --image=nginx --dry-run=client -o yaml > nginx-deploy.yml
-- Basic Template to cleanup
[root@controller ~]# cat nginx-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-deploy
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx-deploy
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-deploy
spec:
containers:
- image: nginx
name: nginx
resources: {}
--- #Modify the contents of the deployment template
# cat nginx-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
type: dev
name: nginx-deploy
spec:
replicas: 2
selector:
matchLabels:
type: dev
template:
metadata:
labels:
type: dev
spec:
containers:
- image: nginx
name: nginx
➜ k8sworkshop git:(main) ✗ kubectl create -f nginx-deploy.yml
deployment.apps/nginx-deploy created
➜ k8sworkshop git:(main) ✗ kubectl rollout status deployment nginx-deploy
deployment "nginx-deploy" successfully rolled out
➜ k8sworkshop git:(main) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-66dc98fc6f-6ws8k 1/1 Running 0 37s
nginx-deploy-66dc98fc6f-btk6j 1/1 Running 0 37s
kubectl describe Pod <NAME>
➜ k8sworkshop git:(main) ✗ kubectl describe Pod nginx-deploy-66dc98fc6f-6ws8k
Name: nginx-deploy-66dc98fc6f-6ws8k
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Tue, 07 Mar 2023 02:12:20 +0530
Labels: pod-template-hash=66dc98fc6f
type=dev
Annotations: <none>
Status: Running
IP: 172.17.0.4
IPs:
IP: 172.17.0.4
Controlled By: ReplicaSet/nginx-deploy-66dc98fc6f
Containers:
nginx:
Container ID: docker://79a285bd1e02d96c1880958d20aa4cf64060c630ecb03dac37665994a8b4574a
Image: nginx
Image ID: docker-pullable://nginx@sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce1d4b4f55a5c2ef2
Port: <none>
Host Port: <none>
State: Running
Started: Tue, 07 Mar 2023 02:12:25 +0530
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wpgb (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-7wpgb:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 93s default-scheduler Successfully assigned default/nginx-deploy-66dc98fc6f-6ws8k to minikube
Normal Pulling 92s kubelet Pulling image "nginx"
Normal Pulled 88s kubelet Successfully pulled image "nginx" in 4.282948252s
Normal Created 88s kubelet Created container nginx
Normal Started 88s kubelet Started container nginx
➜ k8sworkshop git:(main) ✗
➜ k8sworkshop git:(main) ✗ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deploy-66dc98fc6f 2 2 2 3m30s
Using Kubernetes RollingUpdate
You have two ways of updating all those pods. You can do one of the following:
- Recreate: Delete all existing pods first and then start the new ones. This will lead to a temporary unavailability.
- RollingUpdate: Updates Pod one at a time to guarantee availability of the application. This is the preferred approach and you can further tune its behaviour.
The RollingUpdate strategy options are used to guarantee a certain minimal and maximal amount of Pods to be always available:
- maxUnavailable: The maximum number of Pods that can be unavailable during updating. The value could be a percentage (the default is 25%).
- maxSurge: The maximum number of Pods that can be created over the desired number of ReplicaSet during updating. the value of maxSurge cannot be 0
vim rolling-nginx.yml
----
# cat rolling-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: rolling-nginx
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: rolling-nginx
template:
metadata:
labels:
app: rolling-nginx
spec:
containers:
- name: nginx
image: nginx:1.9
➜ k8s101 git:(main) ✗ kubectl create -f rolling-nginx.yml
deployment.apps/rolling-nginx created
➜ k8s101 git:(main) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-66dc98fc6f-6ws8k 1/1 Running 0 15m
nginx-deploy-66dc98fc6f-btk6j 1/1 Running 0 15m
rolling-nginx-77f89bcf9c-2cgps 0/1 ContainerCreating 0 13s
rolling-nginx-77f89bcf9c-l7cvh 0/1 ContainerCreating 0 13s
rolling-nginx-77f89bcf9c-nx888 0/1 ContainerCreating 0 13s
rolling-nginx-77f89bcf9c-xn2z5 0/1 ContainerCreating 0 13s
➜ k8s101 git:(main) ✗ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 2/2 2 2 15m
rolling-nginx 1/4 4 1 50s
➜ k8s101 git:(main) ✗ kubectl get event --field-selector involvedObject.name=rolling-nginx-77f89bcf9c-xn2z5
LAST SEEN TYPE REASON OBJECT MESSAGE
99s Normal Scheduled pod/rolling-nginx-77f89bcf9c-xn2z5 Successfully assigned default/rolling-nginx-77f89bcf9c-xn2z5 to minikube
99s Normal Pulling pod/rolling-nginx-77f89bcf9c-xn2z5 Pulling image "nginx:1.9"
43s Normal Pulled pod/rolling-nginx-77f89bcf9c-xn2z5 Successfully pulled image "nginx:1.9" in 56.078369942s
43s Normal Created pod/rolling-nginx-77f89bcf9c-xn2z5 Created container nginx
43s Normal Started pod/rolling-nginx-77f89bcf9c-xn2z5 Started container nginx
Check rollout history
But why CHANGE-CAUSE is showing NONE? It is because we have not used –record while creating our deployment. The –record argument will add the command under CHANGE-CAUSE for each revision history
k8s101 git:(main) ✗ kubectl rollout history deployment rolling-nginx
deployment.apps/rolling-nginx
REVISION CHANGE-CAUSE
1 <none>
➜ k8s101 git:(main) ✗ kubectl delete deployment rolling-nginx
deployment.apps "rolling-nginx" deleted
this time I will use –record along with kubectl create:
k8s101 git:(main) ✗ kubectl create -f rolling-nginx.yml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/rolling-nginx created
➜ k8s101 git:(main) ✗ kubectl rollout history deployment rolling-nginx
deployment.apps/rolling-nginx
REVISION CHANGE-CAUSE
1 kubectl create --filename=rolling-nginx.yml --record=true
➜ k8s101 git:(main) ✗ kubectl set image deployment rolling-nginx nginx=nginx:1.15 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/rolling-nginx image updated
Monitor the rolling update status
To monitor the rollout status you can use:
➜ k8s101 git:(main) ✗ kubectl set image deployment rolling-nginx nginx=nginx:1.16 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/rolling-nginx image updated
➜ k8s101 git:(main) ✗ kubectl rollout pause deployment rolling-nginx
deployment.apps/rolling-nginx paused
➜ k8s101 git:(main) ✗ kubectl rollout status deployment rolling-nginx
deployment "rolling-nginx" successfully rolled out
➜ k8s101 git:(main) ✗ kubectl get pods -l app=rolling-nginx
NAME READY STATUS RESTARTS AGE
rolling-nginx-55fc56899f-8hlm4 1/1 Running 0 2m30s
rolling-nginx-55fc56899f-g4b6p 1/1 Running 0 2m30s
rolling-nginx-55fc56899f-hnbs8 1/1 Running 0 2m22s
rolling-nginx-55fc56899f-jngcd 1/1 Running 0 2m21s
➜ k8s101 git:(main) ✗ kubectl rollout resume deployment rolling-nginx
deployment.apps/rolling-nginx resumed
Rolling back (undo) an update
To monitor the rollout status you can use:
➜ k8s101 git:(main) ✗ kubectl rollout history deployment rolling-nginx
deployment.apps/rolling-nginx
REVISION CHANGE-CAUSE
1 kubectl create --filename=rolling-nginx.yml --record=true
2 kubectl set image deployment rolling-nginx nginx=nginx:1.15 --record=true
3 kubectl set image deployment rolling-nginx nginx=nginx:1.16 --record=true
➜ k8s101 git:(main) ✗ kubectl rollout undo deployment rolling-nginx --to-revision=2
deployment.apps/rolling-nginx rolled back
➜ k8s101 git:(main) ✗ kubectl rollout status deployment rolling-nginx
deployment "rolling-nginx" successfully rolled out
➜ k8s101 git:(main) ✗ kubectl delete pod --all
pod "nginx-deploy-66dc98fc6f-6ws8k" deleted
pod "nginx-deploy-66dc98fc6f-btk6j" deleted
pod "rolling-nginx-b746d459b-874mv" deleted
pod "rolling-nginx-b746d459b-gtgpk" deleted
pod "rolling-nginx-b746d459b-txc5j" deleted
pod "rolling-nginx-b746d459b-vw4rf" deleted
➜ k8s101 git:(main) ✗ kubectl delete deployment --all
deployment.apps "nginx-deploy" deleted
deployment.apps "rolling-nginx" deleted
Last updated 03 Jun 2024, 13:43 +0530 .