Rollback'i Elle Yapmayı Bırakınca
SSH açıp eski imajı koşturmak kayıt değildir

02:40'ta SSH açtım. docker ps -a listesinde üç imaj, ikisi 'bir önceki' iddiasındaydı. Tag'ler latest ve latest. Digest'leri farklı. Hangisini koşturacağımı Slack'ten sordum. Rollback, tahmin oldu. Tahmin, süre yedi.
Elle geri dönüşün iki kusuru var. Bir: hangi blob'un iyi olduğu yazılı değil. İki: yaptığın şey kümenin veya compose'un istediği durum değil; host'un o anki hali. Bir sonraki otomatik job, elini siler, bozuğu tekrar çeker.
Kayıt ne tutar
Yayın kaydı: git SHA, semver, imaj digest, zaman, iş URL'si. Dördü bir satır. Geri dönüş o satırdaki digest'i tekrar istenilen durum yapmaktır. Tag'i geri çekmek değil. latest'i eskiye basmak değil. İlk yazıdaki ders burada işe yarar: hareket eden isimle geri dönülmez.
# compose host
services:
api:
image: api:1.8.0@sha256:7c2d1b0e4a9f2c8b1d6e0a4f3c9b8e7d6c5b4a3928170654433221100ffeedd
Compose'ta dosyadaki digest'i önceki kayıttaki ile değiştir, docker compose up -d. Image host'ta yoksa pull. docker run ile elle isim uydurmak, dosyayı yalançı bırakır. Bir sonraki kişi dosyaya bakar, eskiyi açar.
kube tarafı
kubectl rollout undo deployment/api bir önceki ReplicaSet'e döner. Önceki ReplicaSet, önceki pod template, önceki digest. undo kaydı Deployment history'sinden okur. History revisionHistoryLimit: 0 ise okuyacak şey yoktur. Limiti 5-10 bırak.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
revisionHistoryLimit: 8
template:
spec:
containers:
- name: api
image: api@sha256:7c2d1b0e4a9f2c8b1d6e0a4f3c9b8e7d6c5b4a3928170654433221100ffeedd
name: rollback
on:
workflow_dispatch:
inputs:
digest:
description: Image digest to restore
required: true
jobs:
restore:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Set image
env:
DIGEST: ${{ inputs.digest }}
run: |
kubectl set image deployment/api api="api@${DIGEST}"
kubectl rollout status deployment/api --timeout=120s
workflow_dispatch ile digest vermek, SSH'tan daha az romantik, daha tekrarlanır. Secret'lı kubeconfig job'da durur; laptop'taki kubeconfig 'ben yaptım' izi bırakmaz. İz, Actions koşusu. 02:40'ta Slack'e sormak yerine kayıttaki satırı yapıştırırım.
Elle kalan tek iş
Veri migrasyonu geri dönmüyorsa imaj geri dönmek yetmez. Bunu runbook yazar: '1.8.0 → 1.7.4 imaj, şema 18'de kaldıysa dur'. Rollback otomasyonu şema bilmez. Bildiği digest. Migrasyonu geri almayan bir yayın, geri dönüşü kapatır. O ayrı bir kapı; imaj kapısını önce kapat.
Digest yoksa geri dönüş yok
Registry GC, tag'siz blob'u siler. 'Bir önceki latest'i çek' o yüzden ölür. Kayıtta digest yoksa, host'taki docker images listesi tek kaynak olur. Liste prune edilmişse kaynak yoktur. Retention: son N semver, son N SHA, ikisi de tag'li. Tag'li blob GC'den geçer.
Migrasyon geri dönmüyorsa imaj geri dönmek yetmez demiştim. Bunu sayıya vurayım: 1.8.0 şema 19 ekler, 1.7.4 şema 18 bekler. undo 1.7.4'ü açar, tablo 19'dadır, sütun fazladır. Uygulama bazen hoşgörür, bazen SELECT patlar. Runbook: 'geri dönüş için şema uyumu'. Uyum yoksa ileri git, hotfix bas. Geri gitme.
# compose: pin the previous known-good line from the deploy log
services:
api:
image: api:1.7.4@sha256:aa01bb02cc03dd04ee05ff06aa07bb08cc09dd10ee11ff12aa13bb14cc15dd16
kubectl rollout history revision listesini basar. undo --to-revision=N belirli bir ReplicaSet'e gider, 'bir önceki'ne değil. Bir öncekini iki kez undo etmek, ileri gitmektir. N'i kayıttan oku. History limit 0 ise N yoktur; o gece SSH açılır. Limiti kapatmayın.
Blue/green ayrı bir hikâye: iki digest birden yaşar, trafik kayar. Rollback orada 'eski rengi işaretle'. Yine digest. Renk bir isim, isim hareket eder. Bu yazının konusu acil geri dönüş. Acil, kahraman değil, kayıtlı bir satır.
Probu geri dönüşte unutmak
Eski imajın /health/ready yolu yoksa, yeni probe eski kutuyu kırmızıya boyar. Rollback, probe ile birlikte düşünülür. 1.7.4 /health taşır, 1.8.0 /health/ready taşır. undo 1.7.4'ü açar, kubelet ready path'i 404 görür, replica hiç hazır olmaz. Trafik kesilir. 'Geri döndük' Slack'i yalan olur.
Bu yüzden path'i bir süre iki yerde tuttum: /health alias, /ready asıl. Alias'ı bir sonraki major'da kestim. Geri dönüş penceresi o major'a kadar. Probe'u kıran yayın, geri dönüşü de kırar. İkisini aynı PR'da yapma.
# keep both paths until the previous release ages out
livenessProbe:
httpGet: { path: /health/live, port: 8080 }
readinessProbe:
httpGet: { path: /health/ready, port: 8080 }
---
# 1.7.4 still answers /health as an alias of /health/live
Compose'ta aynı tuzak: yeni healthcheck komutu eski imajda wget bile olmayabilir. Dosyadaki check, koşan imajla evlenir. Digest'i geri alıp compose health'i yeni bırakmak, kutuyu unhealthy yapar, restart policy yine ölmemiş süreci açmaz. Trafik yine ölür.
name: record-deploy
on:
workflow_dispatch:
inputs:
digest:
required: true
semver:
required: true
jobs:
record:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Append deploy log
run: |
printf '%s %s %s %s %s\n' \
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
"${{ github.sha }}" \
"${{ inputs.semver }}" \
"${{ inputs.digest }}" \
"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
>> deploy.log
- name: Rollout
run: |
kubectl set image deployment/api api="api@${{ inputs.digest }}"
kubectl rollout status deployment/api --timeout=120s
Deploy log'unu bir satırlık bir dosyada tutuyorum: zaman, SHA, semver, digest, iş URL'si. Slack mesajı kayıt değildir. Kanal kayar, arama bozulur. Dosya veya job artifact, bir sonraki 02:40'ta açılır. SSH o dosyadan okunursa hâlâ teşhistir. Dosyasız SSH, tahmin. Tahmin ile geri dönmek, Cuma imajını Pazartesi latest'inden ayıramamaktır.
Elle rollback'i bıraktığım gün, kahramanlık da bitti. Biten şey cesaret değil, kayıtsız host'ta kura çekmekti. Komut duruyor, digest duruyor, history duruyor. 02:40'ta Slack'e sorulan soru artık hangisi önceki değil, kayıttaki satırı yapıştırdın mı. Yapıştırmadıysan SSH yine açılır; bu kez dosyayı okumak için.
SSH'ı yasaklamıyorum. Teşhis için duruyor. Yayın ve geri dönüş için durmuyor. Kahramanlık, kayıtsız host'ta docker run ise, bir sonraki kesinti aynı kahramanı arar. Komut dosyası, kahramanı işten çıkarır.
Yorumlar
Yorumlar (0)
Yorumlar üyelere açık. Üye ol · Giriş yap