Di episode ini kita akan coba bahas Kubernetes Deployment untuk managing application rollout. Kita akan mempelajari rolling update, rollback, scaling strategy, dan best practice untuk production deployment.

Catatan
Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 25 di bawah ini
Di episode sebelumnya kita sudah belajar tentang managing Kubernetes object menggunakan imperative dan declarative approach. Selanjutnya di episode 26 kali ini, kita akan coba bahas Deployment, salah satu Kubernetes resource paling penting untuk managing application rollout dan update.
Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.
Deployment menyediakan declarative update untuk Pod dan ReplicaSet. Dia manage entire lifecycle application kalian, dari initial deployment ke update dan rollback, ensuring zero-downtime deployment.
Deployment adalah Kubernetes resource yang manage set identical Pod, ensuring desired number Pod running dan handling update gracefully.
Bayangkan Deployment seperti production manager - dia ensure right number worker (Pod) selalu available, replace worker ketika fail, dan coordinate smooth transition ketika kalian need update workforce.
Karakteristik kunci Deployment:
Deployment solve beberapa critical challenge:
Tanpa Deployment, kalian harus manually manage Pod, handle update carefully untuk avoid downtime, dan implement rollback mechanism sendiri.
Mari kita buat basic Deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80Apply Deployment:
sudo kubectl apply -f nginx-deployment.ymlCheck Deployment status:
sudo kubectl get deploymentsOutput:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 30sCheck Pod created oleh Deployment:
sudo kubectl get pods -l app=nginxapiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
labels:
app: myapp
spec:
replicas: 5
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
version: v1.0
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5Adjust number replica.
Menggunakan kubectl scale:
sudo kubectl scale deployment nginx-deployment --replicas=5Menggunakan kubectl apply:
spec:
replicas: 5 # Changed dari 3 ke 5sudo kubectl apply -f nginx-deployment.ymlGunakan HorizontalPodAutoscaler untuk automatic scaling:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70Apply HPA:
sudo kubectl apply -f hpa.ymlCheck HPA status:
sudo kubectl get hpaUpdate Deployment tanpa downtime.
Deployment support dua update strategy:
RollingUpdate (default):
Recreate:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # Max 2 extra Pod during update
maxUnavailable: 1 # Max 1 Pod unavailable during update
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080maxSurge: Maximum number Pod yang bisa created above desired replica maxUnavailable: Maximum number Pod yang bisa unavailable during update
Update image menggunakan kubectl set:
sudo kubectl set image deployment/nginx-deployment nginx=nginx:1.26Update menggunakan kubectl apply:
# Change image version
containers:
- name: nginx
image: nginx:1.26 # Updated dari 1.25sudo kubectl apply -f nginx-deployment.ymlWatch rollout progress:
sudo kubectl rollout status deployment/nginx-deploymentOutput:
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled outRevert ke previous version.
sudo kubectl rollout history deployment/nginx-deploymentOutput:
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.26sudo kubectl rollout history deployment/nginx-deployment --revision=2sudo kubectl rollout undo deployment/nginx-deploymentsudo kubectl rollout undo deployment/nginx-deployment --to-revision=2Pause rollout:
sudo kubectl rollout pause deployment/nginx-deploymentMake multiple change:
sudo kubectl set image deployment/nginx-deployment nginx=nginx:1.26
sudo kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=500m,memory=512MiResume rollout:
sudo kubectl rollout resume deployment/nginx-deploymentDifferent approach untuk updating application.
Gradually replace old Pod dengan new one:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%Keuntungan:
Kekurangan:
Terminate semua Pod sebelum create new one:
spec:
strategy:
type: RecreateKeuntungan:
Kekurangan:
Run dua identical environment, switch traffic:
# Blue deployment (current)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: myapp:1.0
---
# Green deployment (new)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: myapp:2.0
---
# Service (switch antara blue dan green)
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
version: blue # Change ke 'green' untuk switch
ports:
- port: 80
targetPort: 8080Gradually shift traffic ke new version:
# Stable deployment (90% traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-stable
spec:
replicas: 9
selector:
matchLabels:
app: myapp
track: stable
template:
metadata:
labels:
app: myapp
track: stable
spec:
containers:
- name: app
image: myapp:1.0
---
# Canary deployment (10% traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
app: myapp
track: canary
template:
metadata:
labels:
app: myapp
track: canary
spec:
containers:
- name: app
image: myapp:2.0
---
# Service (route ke both)
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp # Match both stable dan canary
ports:
- port: 80
targetPort: 8080apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
tier: frontend
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
version: v1.0
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
name: http
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostnameapiVersion: v1
kind: ConfigMap
metadata:
name: api-config
data:
LOG_LEVEL: "info"
API_TIMEOUT: "30"
---
apiVersion: v1
kind: Secret
metadata:
name: api-secrets
type: Opaque
stringData:
DATABASE_PASSWORD: "secretpassword"
API_KEY: "abc123xyz789"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapi:latest
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-secrets
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-sidecar
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
# Main application
- name: app
image: myapp:latest
ports:
- containerPort: 8080
volumeMounts:
- name: logs
mountPath: /var/log/app
# Log shipper sidecar
- name: log-shipper
image: fluent/fluentd:v1.16
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true
volumes:
- name: logs
emptyDir: {}sudo kubectl get deployments
sudo kubectl get deployments -o widesudo kubectl describe deployment nginx-deploymentsudo kubectl get deployment nginx-deployment -o yamlsudo kubectl get deployments --watchsudo kubectl get replicasetssudo kubectl get pods -l app=nginxProblem: Pod bisa consume unlimited resource.
Solusi: Selalu set resource limit:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"Problem: Kubernetes route traffic ke unhealthy Pod.
Solusi: Add liveness dan readiness probe:
livenessProbe:
httpGet:
path: /health
port: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080Problem: Update happen terlalu fast, causing issue.
Solusi: Configure appropriate maxSurge dan maxUnavailable:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # Ensure no downtimeProblem: Deploy untested change ke production.
Solusi: Test di staging dulu:
# Test di staging
sudo kubectl apply -f deployment.yml --namespace=staging
# Setelah validation, deploy ke production
sudo kubectl apply -f deployment.yml --namespace=productionProblem: Tidak monitor deployment progress.
Solusi: Selalu check rollout status:
sudo kubectl rollout status deployment/nginx-deploymentSelalu gunakan YAML file:
# Bagus: Declarative
sudo kubectl apply -f deployment.yml
# Hindari: Imperative
sudo kubectl create deployment nginx --image=nginx:1.25Pilih based on load dan availability requirement:
# Development: 1-2 replica
replicas: 1
# Production: 3+ replica untuk high availability
replicas: 5Organize dan select resource:
metadata:
labels:
app: myapp
version: v1.0
environment: production
tier: backendControl rollout behavior:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%Document deployment detail:
metadata:
annotations:
kubernetes.io/change-cause: "Update to version 1.26"
description: "Production web server"
owner: "platform-team"Isolate environment:
metadata:
name: app-deployment
namespace: productionSet up monitoring dan alert:
sudo kubectl get deployments --watch
sudo kubectl rollout status deployment/appsudo kubectl get deployment nginx-deployment
sudo kubectl describe deployment nginx-deploymentsudo kubectl get replicasets
sudo kubectl describe replicaset <replicaset-name>sudo kubectl get pods -l app=nginx
sudo kubectl describe pod <pod-name>
sudo kubectl logs <pod-name>sudo kubectl get events --sort-by='.lastTimestamp'sudo kubectl rollout undo deployment/nginx-deploymentPada episode 26 ini, kita telah membahas Deployment di Kubernetes secara mendalam. Kita sudah belajar cara create Deployment, perform rolling update, rollback change, dan implement different deployment strategy.
Key takeaway:
Deployment adalah cornerstone application management di Kubernetes. Dengan memahami Deployment, kalian bisa confidently deploy, update, dan manage application di production dengan zero downtime dan easy rollback capability.
Bagaimana, makin jelas kan tentang Deployment di Kubernetes? Jadi, pastikan tetap semangat belajar dan nantikan episode selanjutnya!
Catatan
Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 27 di bawah ini