Rolling Update #
Deployment ke production yang menyebabkan downtime adalah hal yang tidak bisa diterima. Kubernetes menyediakan mekanisme rolling update bawaan — container lama digantikan container baru secara bertahap, memastikan selalu ada instance yang melayani traffic. Tapi rolling update yang benar-benar aman membutuhkan lebih dari sekadar kubectl set image — ia butuh health check yang proper, rollback otomatis saat terjadi masalah, dan orkestrasi yang memastikan semua langkah terjadi dalam urutan yang benar. Ansible memberikan kontrol penuh atas semua ini.
Anatomi Rolling Update yang Aman #
Langkah rolling update yang aman:
1. Backup state saat ini (catat versi yang sedang berjalan)
2. Verifikasi target image tersedia di registry
3. Update Deployment dengan image baru
4. Monitor rollout — tunggu setiap Pod baru siap sebelum lanjut
5. Jalankan smoke test setelah rollout selesai
6. Jika smoke test gagal → rollback otomatis ke versi sebelumnya
7. Notifikasi tim tentang hasil deployment
Implementasi Rolling Update dengan Ansible #
# playbooks/rolling-update.yml
---
- name: Rolling update aplikasi ke versi baru
hosts: localhost
vars:
app_name: myapp
app_namespace: production
new_version: "{{ version | mandatory }}" # -e version=2.2.0
tasks:
- name: Catat versi yang sedang berjalan (untuk rollback)
kubernetes.core.k8s_info:
kubeconfig: "{{ k8s_kubeconfig }}"
kind: Deployment
name: "{{ app_name }}"
namespace: "{{ app_namespace }}"
register: current_deployment
- name: Simpan versi saat ini sebagai fact rollback
set_fact:
rollback_image: >-
{{ current_deployment.resources[0].spec.template.spec.containers[0].image }}
- name: Debug — tampilkan versi saat ini dan target
debug:
msg:
- "Versi saat ini: {{ rollback_image }}"
- "Target versi: {{ app_image }}:{{ new_version }}"
- name: Update image Deployment
kubernetes.core.k8s:
kubeconfig: "{{ k8s_kubeconfig }}"
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ app_name }}"
namespace: "{{ app_namespace }}"
spec:
template:
metadata:
annotations:
# Annotation ini memaksa Pod restart meski image tag sama
deployment-time: "{{ ansible_date_time.iso8601 }}"
spec:
containers:
- name: "{{ app_name }}"
image: "{{ app_image }}:{{ new_version }}"
- name: Monitor rollout hingga selesai
kubernetes.core.k8s_rollout_status:
kubeconfig: "{{ k8s_kubeconfig }}"
name: "{{ app_name }}"
namespace: "{{ app_namespace }}"
kind: Deployment
timeout: 300
register: rollout_status
- name: Jalankan smoke test setelah rollout
uri:
url: "https://{{ app_domain }}/health"
status_code: 200
timeout: 10
register: smoke_test
retries: 5
delay: 10
- name: Rollback jika smoke test gagal
command: >
kubectl rollout undo deployment/{{ app_name }}
-n {{ app_namespace }}
--kubeconfig {{ k8s_kubeconfig }}
when: smoke_test.status != 200
- name: Gagalkan playbook jika rollback dilakukan
fail:
msg: >
Smoke test gagal setelah update ke {{ new_version }}!
Rollback ke {{ rollback_image }} sudah dilakukan.
Periksa log untuk investigasi lebih lanjut.
when: smoke_test.status != 200
Rollback Manual #
- name: Rollback ke versi sebelumnya
hosts: localhost
tasks:
- name: Undo deployment ke revisi sebelumnya
command: >
kubectl rollout undo deployment/{{ app_name }}
-n {{ app_namespace }}
--kubeconfig {{ k8s_kubeconfig }}
register: rollback_result
- name: Tunggu rollback selesai
kubernetes.core.k8s_rollout_status:
kubeconfig: "{{ k8s_kubeconfig }}"
name: "{{ app_name }}"
namespace: "{{ app_namespace }}"
kind: Deployment
timeout: 180
- name: Verifikasi versi setelah rollback
kubernetes.core.k8s_info:
kubeconfig: "{{ k8s_kubeconfig }}"
kind: Pod
namespace: "{{ app_namespace }}"
label_selectors:
- "app={{ app_name }}"
register: pod_info
- name: Tampilkan image yang berjalan setelah rollback
debug:
msg: "Pod {{ item.metadata.name }} berjalan dengan image: {{ item.spec.containers[0].image }}"
loop: "{{ pod_info.resources }}"
loop_control:
label: "{{ item.metadata.name }}"
Deployment Multi-Service yang Berurutan #
Saat aplikasi terdiri dari beberapa service yang saling bergantung, urutan update penting:
# playbooks/full-stack-update.yml
---
- name: Update full stack dengan urutan yang benar
hosts: localhost
vars:
target_version: "{{ version | mandatory }}"
tasks:
# 1. Update database schema terlebih dahulu
- name: Jalankan migrasi database
kubernetes.core.k8s:
kubeconfig: "{{ k8s_kubeconfig }}"
state: present
definition:
apiVersion: batch/v1
kind: Job
metadata:
name: "db-migration-{{ target_version | replace('.', '-') }}"
namespace: production
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migration
image: "{{ app_image }}:{{ target_version }}"
command: ["python", "manage.py", "migrate"]
- name: Tunggu migrasi database selesai
kubernetes.core.k8s_info:
kubeconfig: "{{ k8s_kubeconfig }}"
kind: Job
name: "db-migration-{{ target_version | replace('.', '-') }}"
namespace: production
register: migration_job
until: >
migration_job.resources[0].status.succeeded is defined and
migration_job.resources[0].status.succeeded == 1
retries: 30
delay: 10
# 2. Update backend API
- name: Update backend API
kubernetes.core.k8s:
kubeconfig: "{{ k8s_kubeconfig }}"
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
namespace: production
spec:
template:
spec:
containers:
- name: backend-api
image: "{{ api_image }}:{{ target_version }}"
- name: Tunggu backend API rollout
kubernetes.core.k8s_rollout_status:
kubeconfig: "{{ k8s_kubeconfig }}"
name: backend-api
namespace: production
kind: Deployment
timeout: 300
# 3. Baru update frontend (setelah backend siap)
- name: Update frontend
kubernetes.core.k8s:
kubeconfig: "{{ k8s_kubeconfig }}"
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: production
spec:
template:
spec:
containers:
- name: frontend
image: "{{ frontend_image }}:{{ target_version }}"
Ringkasan #
- Catat versi yang sedang berjalan sebelum update — ini memungkinkan rollback yang tepat jika ada masalah.
- Gunakan
k8s_rollout_statusuntuk menunggu rollout selesai — jangan lanjutkan ke smoke test sebelum semua Pod baru siap.- Implementasikan rollback otomatis jika smoke test gagal — pipeline deployment yang baik tidak butuh intervensi manual untuk kasus ini.
- Untuk multi-service, perhatikan urutan update: migrasi database dulu, baru backend, baru frontend — urutan terbalik bisa menyebabkan error runtime.
maxUnavailable: 0danmaxSurge: 1di Deployment strategy untuk zero-downtime — Kubernetes tidak akan terminate Pod lama sebelum Pod baru siap.- Simpan history rollout dengan
kubectl rollout history— Kubernetes menyimpan beberapa revisi terakhir yang bisa di-rollback kapan saja.
← Sebelumnya: Cluster Maintenance Berikutnya: CI/CD Integration →