ЁЯФБ рдзрдбрд╛ 09 тАФ Deploy strategies & rollback: рдПрдХреЗрдХ рдХрд░реВрди pins рдмрджрд▓рд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 09 ┬╖ рдорд╛рдЧреАрд▓: lesson-08-environments-gates ┬╖ рдкреБрдвреАрд▓: lesson-10-deploy-to-kubernetes
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ08, рдЖрдгрд┐ рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп рд╡реНрд╣реЕрди рдкреЛрд╣реЛрдЪрд▓реНрдпрд╛рд╡рд░ рдлрд▓рдХрд╛рд╡рд░ рдХрд╛рдп рдШрдбрддреЗ: рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛рд▓рд╛ рдХрдзреАрд╣реА рд░рд┐рдХрд╛рдореА рднрд┐рдВрдд рди рджрд┐рд╕рддрд╛ рдирд╡реА рд╕реВрдЪрдирд╛ рдЬреБрдиреА рдХрд╢реА рдмрджрд▓рддреЗ, рдЖрдгрд┐ рдХрд╛рд▓рдЪреА рд╕реВрдЪрдирд╛ рдкрд░рдд рдХрд╢реА рд▓рд╛рд╡рд╛рдпрдЪреА. рдЦрд▒реНрдпрд╛ files:
- k8s/deployment.yaml тАФ рд╕реВрдЪрдирд╛ рдлрд▓рдХ:
strategy: RollingUpdate,maxSurge: 1,maxUnavailable: 0, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рдпрд░реАрд▓рд╛ gate рдХрд░рдгрд╛рд░рд╛/healthzрд╡рд░рдЪрд╛ readiness probe - k8s/service.yaml тАФ "рдЗрдереЗ рд╡рд╛рдЪрд╛ тЖТ" рдкрд╛рдЯреА; blue/green flip рдордзреНрдпреЗ рддреНрдпрд╛рдЪрд╛
selectorрдмрджрд▓рддреЛ - .github/workflows/deploy.yml тАФ рд╡реНрд╣реЕрди; рддреНрдпрд╛рдЪреНрдпрд╛ рд╢реЗрд╡рдЯрдЪреНрдпрд╛ рджреЛрди рдУрд│реА рдореНрд╣рдгрдЬреЗ rollback рдЪреА рдХреГрддреА
- app/Dockerfile тАФ
ARG APP_VERSIONрдореБрд│реЗ lab рдордзреНрдпреЗ v1 рдЖрдгрд┐ v2 рд╡реЗрдЧрд│реЗ рдУрд│рдЦрддрд╛ рдпреЗрддрд╛рдд
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдореБрдЦреНрдп рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рд╡рд░ ЁЯУМ рдЖрдЬрдЪреНрдпрд╛ рд╕реВрдЪрдиреЗрдЪреНрдпрд╛ рджреЛрди copies рдЕрд╕рддрд╛рдд, рдореНрд╣рдгрдЬреЗ рдЧрд░реНрджреА рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдиреА рд╡рд╛рдЪреВ рд╢рдХрддреЗ. рдирд╡реА рдЖрд╡реГрддреНрддреА рдпреЗрддреЗ. рддреА рдХрд╢реА рдмрджрд▓рд╛рдпрдЪреА?
Rolling ЁЯФБ: рдЬреБрдиреНрдпрд╛ рджреЛрдШреАрдВрдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рдПрдХ рдирд╡реА copy рд▓рд╛рд╡рд╛ (рдХреНрд╖рдгрднрд░ рдлрд▓рдХрд╛рд╡рд░ рддреАрди), рддреА рдЦрд░реЛрдЦрд░ рд╡рд╛рдЪрддрд╛ рдпреЗрддреЗ рдпрд╛рдЪреА рдХреЛрдгреА рдЦрд╛рддреНрд░реА рдХрд░реЗрдкрд░реНрдпрдВрдд рдерд╛рдВрдмрд╛ ("рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?" тАФ рд╣рд╛рдЪ readiness probe), рдордЧ рдПрдХ рдЬреБрдиреА copy рдХрд╛рдврд╛. рдкреБрдиреНрд╣рд╛ рддрд╕реЗрдЪ рдХрд░рд╛. рдкреВрд░реНрдг рд╡реЗрд│ рдлрд▓рдХ рд╡рд╛рдЪрддрд╛ рдпреЗрддреЛ. рдпрд╛ repo рдЪрд╛ Deployment рд╣реЗрдЪ рдХрд░рддреЛ.
Recreate ЁЯз╣ рджреЛрдиреНрд╣реА рдЬреБрдиреНрдпрд╛ copies рдлрд╛рдбреВрди рдХрд╛рдврддреЛ, рдордЧ рдирд╡реНрдпрд╛ рд▓рд╛рд╡рддреЛ тАФ рд╕реЛрдкреЗ, рдкрдг рдХрд╛рд╣реА рд╕реЗрдХрдВрдж рдлрд▓рдХ рд░рд┐рдХрд╛рдорд╛ рд░рд╛рд╣рддреЛ. Blue/green ЁЯФ╡ЁЯЯв рджреЛрди рдкреВрд░реНрдг рдлрд▓рдХ рдареЗрд╡рддреЛ: рдирд╡реА рд╕реВрдЪрдирд╛ рд░рд┐рдХрд╛рдореНрдпрд╛ рдлрд▓рдХрд╛рд╡рд░ рд▓рд╛рд╡рд╛, рддрдкрд╛рд╕рд╛, рдордЧ "рдЗрдереЗ рд╡рд╛рдЪрд╛ тЖТ" рдкрд╛рдЯреА рддрд┐рдХрдбреЗ рдлрд┐рд░рд╡рд╛. Undo = рдкрд╛рдЯреА рдкрд░рдд рдлрд┐рд░рд╡рд╛.
Canary ЁЯРд: рдирд╡реА рд╕реВрдЪрдирд╛ рдЖрдзреА рдПрдХрд╛рдЪ рд╡рд░реНрдЧрд╛рд▓рд╛ рджрд╛рдЦрд╡рд╛. рддреНрдпрд╛рдВрдиреА рддрдХреНрд░рд╛рд░ рдХреЗрд▓реА рдирд╛рд╣реА рддрд░ рд╕рдЧрд│реНрдпрд╛рдВрдирд╛ рджрд╛рдЦрд╡рд╛. Argo Rollouts рдЖрдгрд┐ Flagger рд╕рд╛рд░рдЦреА tools "рддреНрдпрд╛рдВрдиреА рддрдХреНрд░рд╛рд░ рдХреЗрд▓реА рдирд╛рд╣реА рддрд░" рдпрд╛рдЪреЗ рдЖрдкреЛрдЖрдк рдирд┐рд░реНрдгрдпрд╛рдд рд░реВрдкрд╛рдВрддрд░ рдХрд░рддрд╛рдд тАФ рддреА рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЖрд╣реЗрдд, рдЖрдкрдг рдЗрдереЗ рдлрдХреНрдд рддреНрдпрд╛рдВрдЪреА рдирд╛рд╡реЗ рдШреЗрддреЛ.
рдЖрдгрд┐ rollback тПк рдореНрд╣рдгрдЬреЗ рдЬрд╛рджреВ рдирд╛рд╣реА: рдХрд╛рд▓рдЪреА рд╕реВрдЪрдирд╛ рдЕрдЬреВрдирд╣реА рд▓реЙрдХрд░рдордзреНрдпреЗ рдЖрд╣реЗ, рдХрд╛рд▓рдЪреНрдпрд╛ commit рдЪреЗ label рд▓рд╛рд╡реВрди. рддреА рдкреБрдиреНрд╣рд╛ рд▓рд╛рд╡рд╛.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
old["ЁЯУМ board: old, old<br/>2 replicas ready"]
surge["ЁЯУМ old, old, NEW<br/>maxSurge 1 тЖТ three pins"]
probe{"тЭУ GET /healthz<br/>readiness probe"}
step["ЁЯУМ old, NEW<br/>one old pin comes down"]
done["ЁЯУМ NEW, NEW<br/>rollout complete"]
stall["тП╕я╕П stalls тАФ old pins stay up<br/>maxUnavailable 0"]
old -->|"1 apply new image"| surge
surge -->|"2 asks the new pod"| probe
probe -->|"3 ok"| step
step -->|"4 repeat once more"| done
probe -.->|"5 not ok"| stall
тЭУ рдХрд╛рдп
- RollingUpdate = pods рд╣рд│реВрд╣рд│реВ рдмрджрд▓рдгреЗ.
maxSurge= рдмрджрд▓ рдЪрд╛рд▓реВ рдЕрд╕рддрд╛рдирд╛ рдХрд┐рддреА рдЬрд╛рд╕реНрддреАрдЪреЗ pods рдЕрд╕реВ рд╢рдХрддрд╛рдд;maxUnavailable= рдХрд┐рддреА рдХрдореА рдЕрд╕реВ рд╢рдХрддрд╛рдд. рд╣рд╛ repo: surge 1, unavailable 0 тЖТ рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд 3 pods, рдЖрдгрд┐ controller рдХрд┐рдорд╛рди 2 ready рдареЗрд╡рддреЛ. - Readiness probe = Service рдирд╡реНрдпрд╛ pod рд▓рд╛ traffic рдкрд╛рдард╡рдгреНрдпрд╛рдЖрдзреА рдЖрдгрд┐ rollout рдкреБрдвреЗ
рд╕рд░рдХрдгреНрдпрд╛рдЖрдзреА рддреНрдпрд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рд▓реЗрд▓рд╛ рдкреНрд░рд╢реНрди. рдЗрдереЗ: port 3000 рд╡рд░
GET /healthz(Kubernetes рд╢рд╛рд│рд╛ L07). - Recreate =
strategy: { type: Recreate }: рдЬреБрдиреЗ pods рдерд╛рдВрдмрддрд╛рдд, рдордЧ рдирд╡реЗ рд╕реБрд░реВ рд╣реЛрддрд╛рдд. рд░рдЪрдиреЗрдиреБрд╕рд╛рд░рдЪ downtime; рджреЛрди versions рдПрдХрддреНрд░ рд░рд╛рд╣реВ рд╢рдХрдд рдирд╕рддреАрд▓ рддреЗрд╡реНрд╣рд╛рд╕рд╛рдареА. - Blue/green = рджреЛрди Deployments, рдПрдХ Service; Service рдЪрд╛
selectorрдХреЛрдгрддрд╛ live рдЖрд╣реЗ рддреЗ рдард░рд╡рддреЛ. рд▓рдЧреЗрдЪ switch, рд▓рдЧреЗрдЪ undo, рдХрд╛рд╣реА рдХрд╛рд│ рджреБрдкреНрдкрдЯ pods. - Canary = traffic рдЪрд╛ рдЫреЛрдЯрд╛ рд╡рд╛рдЯрд╛ рдЖрдзреА рдирд╡реНрдпрд╛ version рд▓рд╛. рдПрдХрд╛ cluster рдордзреНрдпреЗ: рддреНрдпрд╛рдЪ Service рдорд╛рдЧреЗ рджреБрд╕рд░рд╛, рдЫреЛрдЯрд╛ Deployment. рдкреВрд░реНрдг stacks рдордзреНрдпреЗ: Route 53 weighted records (AWS рд╢рд╛рд│рд╛ L23).
- Rollback = рдорд╛рдЧрдЪреЗ version deploy рдХрд░рдгреЗ. рдкреНрд░рд╛рдзрд╛рдиреНрдп: рдХрд╛рд▓рдЪреНрдпрд╛ image tag рд╕рд╣ deploy
рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓рд╡рд╛ тАФ tag рд╣реЗрдЪ version рдЖрд╣реЗ, рдЖрдгрд┐ run log рд╣реЛрддреЛ.
рдЖрдгреАрдмрд╛рдгреАрдЪрд╛ рд▓рд┐рд╡реНрд╣рд░:
kubectl rollout undo, рдЬреЛ рдорд╛рдЧрдЪреНрдпрд╛ ReplicaSet рдХрдбреЗ рдкрд░рдд рдлрд┐рд░рд╡рддреЛ. - Deploy тЙа release: deploy рдореНрд╣рдгрдЬреЗ code рдлрд▓рдХрд╛рд╡рд░ рд▓рд╛рд╡рдгреЗ; release рдореНрд╣рдгрдЬреЗ users рдирд╛ рддреЛ рджрд┐рд╕реВ рджреЗрдгреЗ. Feature flag рджреЛрдиреНрд╣реА рд╡реЗрдЧрд│реЗ рдХрд░рддреЛ, рдореНрд╣рдгрдЬреЗ deploy рдХрдВрдЯрд╛рд│рд╡рд╛рдгрд╛ рд░рд╛рд╣реВ рд╢рдХрддреЛ.
ЁЯза рдЬреБрдиреЗ рдЖрдгрд┐ рдирд╡реЗ рдПрдХрд╛рдЪ рд╡реЗрд│реА рдЪрд╛рд▓рддрд╛рдд тАФ рддреНрдпрд╛рдЪреЗ рдирд┐рдпреЛрдЬрди рдХрд░рд╛
rolling update ┬╖ replicas 2 ┬╖ maxSurge 1 ┬╖ maxUnavailable 0
t0 old old 2 ready apply the new image
t1 old old NEW 2 ready + 1 starting probe asks NEW: GET /healthz
t2 old NEW 2 ready one old pod gone, second NEW starting
t3 NEW NEW 2 ready rollout status exits 0 тЖТ the van reports тЬЕ
t1 рдЖрдгрд┐ t3 рджрд░рдореНрдпрд╛рди рджреЛрдиреНрд╣реА versions traffic serve рдХрд░рддрд╛рдд. рдореНрд╣рдгреВрдирдЪ database рдмрджрд▓рд╛рд╕рд╛рдареА expand / contract рд▓рд╛рдЧрддреЗ: рдЖрдзреА рджреЛрдиреНрд╣реА versions рдирд╛ рдЪрд╛рд▓реЗрд▓ рдЕрд╕реЗ schema рдкрд╛рдард╡рд╛ (рдирд╡рд╛ column рдЬреЛрдбрд╛, рдЬреБрдирд╛ рдареЗрд╡рд╛), рдордЧ рддреЛ рд╡рд╛рдкрд░рдгрд╛рд░рд╛ code рдкрд╛рдард╡рд╛, рдЖрдгрд┐ рдЬреБрдиреНрдпрд╛ code рд▓рд╛ рдЬреЗ рд▓рд╛рдЧрдд рд╣реЛрддреЗ рддреЗ рдирдВрддрд░рдЪ рдХрд╛рдврд╛. Rolling update рдЪрд╛рд▓реВ рдЕрд╕рддрд╛рдирд╛ рдПрдХрдЪ "column rename рдХрд░рд╛" migration рдЬреЗ version рдЕрдЬреВрди рдЪрд╛рд▓реВ рдЕрд╕реЗрд▓ рддреЗ рдореЛрдбрддреЗ.
ЁЯдФ рдХрд╛
YAML apply рдХрд░рдгрд╛рд░реА pipeline рддреНрдпрд╛ YAML рдордзрд▓реНрдпрд╛ strategy рдЗрддрдХреАрдЪ рд╕реБрд░рдХреНрд╖рд┐рдд рдЕрд╕рддреЗ.
maxUnavailable: 0 рдЖрдгрд┐ probe рдЕрд╕реЗрд▓ рддрд░ рддреБрдЯрд▓реЗрд▓реА image site рдмрдВрдж рдкрд╛рдбрдгреНрдпрд╛рдРрд╡рдЬреА рдЕрдбрдХреВрди рдерд╛рдВрдмрддреЗ
тАФ rollout status рд╡рд╛рдЯ рдкрд╛рд╣рдд рдЕрд╕рддрд╛рдирд╛ рдЬреБрдиреЗ pods serve рдХрд░рдд рд░рд╛рд╣рддрд╛рдд рдЖрдгрд┐ рд╢реЗрд╡рдЯреА job fail рд╣реЛрддреЛ.
Probe рдирд╕реЗрд▓ рддрд░ process рд╕реБрд░реВ рд╣реЛрддрд╛рдХреНрд╖рдгреА Kubernetes рдирд╡реНрдпрд╛ pod рд▓рд╛ рдареАрдХ рдорд╛рдиреЗрд▓ рдЖрдгрд┐ рдЬреБрдиреЗ
рдирд┐рд╡реГрддреНрдд рдХрд░реЗрд▓. Kubernetes рд╢рд╛рд│рд╛ rollout рдЪреА рдпрдВрддреНрд░рдгрд╛
L11 рдордзреНрдпреЗ рд╢рд┐рдХрд╡рддреЗ;
рдЗрдереЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рд╡реНрд╣реЕрдирд▓рд╛ рдХрд╛рдп рджрд┐рд╕рддреЗ рддреНрдпрд╛рдЪреА рдХрд╛рд│рдЬреА рдЖрд╣реЗ: рдкрд╛рд╕ рдХрд┐рдВрд╡рд╛ fail рд╣реЛрдгрд╛рд░реЗ рдПрдХ рдЧреЗрдЯ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
Strategy manifest рдордзреНрдпреЗ рд░рд╛рд╣рддреЗ, рдХреЛрдгрддреНрдпрд╛рд╣реА pipeline file рдордзреНрдпреЗ рдирд╛рд╣реА тАФ рдЪрд╛рд░рд╣реА рдмреЛрд▓реА рддреАрдЪ k8s/deployment.yaml apply рдХрд░рддрд╛рдд:
spec:
replicas: 2
selector:
matchLabels: { app: hello-courier }
strategy:
type: RollingUpdate # lesson 09: replace the pins one at a time
rollingUpdate: { maxSurge: 1, maxUnavailable: 0 }
template:
metadata:
labels: { app: hello-courier }
spec:
containers:
- name: web
image: IMAGE_PLACEHOLDER # CI swaps in ACCOUNT.dkr.ecr.REGION.amazonaws.com/hello-courier:<sha>
ports: [{ containerPort: 3000 }]
readinessProbe: # the rollout only proceeds when the new pod answers /healthz
httpGet: { path: /healthz, port: 3000 }
initialDelaySeconds: 2
periodSeconds: 5
рд╡реНрд╣реЕрди рдмрджрд▓ рдкреВрд░реНрдг рд╣реЛрдгреНрдпрд╛рдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рддреЗ рдЖрдгрд┐ timeout рдореНрд╣рдгрдЬреЗ рдЕрдпрд╢рд╕реНрд╡реА delivery рдорд╛рдирддреЗ (deploy.yml, production job):
kubectl apply -n production -f k8s/
kubectl rollout status -n production deployment/hello-courier --timeout=180s
# rollback = kubectl rollout undo deployment/hello-courier -n production (lesson 09)
# тАжor, better, re-run this workflow with yesterday's image tag: the tag IS the version.
Blue/green рдпрд╛ repo рдордзреНрдпреЗ рдирд╛рд╣реА; рддреНрдпрд╛рдЪрд╛ рдЖрдХрд╛рд░ рдореНрд╣рдгрдЬреЗ рджреЛрди Deployments (pod labels рдордзреНрдпреЗ color: blue,
color: green) рдЖрдгрд┐ Service рдордзрд▓рд╛ рдПрдХрд╛ рдУрд│реАрдЪрд╛ рдмрджрд▓:
# illustrative тАФ k8s/service.yaml with a color in the selector
spec:
selector: { app: hello-courier, color: blue } # flip to green once green passes its checks
ports: [{ port: 80, targetPort: 3000 }]
ЁЯФБ рд╣реЗрдЪ CircleCI рдордзреНрдпреЗ
kubectl apply -n << parameters.namespace >> -f k8s/
kubectl rollout status -n << parameters.namespace >> deployment/hello-courier --timeout=180s
ЁЯжК рд╣реЗрдЪ GitLab CI рдордзреНрдпреЗ
- kubectl apply -n "$NAMESPACE" -f k8s/
- kubectl rollout status -n "$NAMESPACE" deployment/hello-courier --timeout=180s
ЁЯОй рд╣реЗрдЪ Jenkins рдордзреНрдпреЗ
kubectl apply -n ${namespace} -f k8s/
kubectl rollout status -n ${namespace} deployment/hello-courier --timeout=180s
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
AWS рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА тАФ рд╕реНрдерд╛рдирд┐рдХ cluster рд╡рд░ pins рд╣рд▓рддрд╛рдирд╛ рджрд┐рд╕рддрд╛рдд.
# 0) a local cluster: kind (below) or Docker Desktop тЖТ Settings тЖТ Kubernetes тЖТ Enable
kind create cluster --name school
kubectl create namespace staging
# 1) photocopy v1 with a tag (CI uses the full commit SHA; any tag except "latest" works locally)
docker build --build-arg APP_VERSION=v1 -t hello-courier:v1 app
kind load docker-image hello-courier:v1 --name school # kind only; Docker Desktop shares its daemon
# 2) pin it: the same placeholder swap as deploy.yml, piped so your working tree stays clean
sed "s|IMAGE_PLACEHOLDER|hello-courier:v1|" k8s/deployment.yaml | kubectl apply -n staging -f -
kubectl apply -n staging -f k8s/service.yaml
kubectl rollout status -n staging deployment/hello-courier --timeout=180s
# 3) v2: new tag, same manifest тАФ watch the pins move one at a time
docker build --build-arg APP_VERSION=v2 -t hello-courier:v2 app
kind load docker-image hello-courier:v2 --name school
kubectl get pods -n staging -w & # leave the watcher running
sed "s|IMAGE_PLACEHOLDER|hello-courier:v2|" k8s/deployment.yaml | kubectl apply -n staging -f -
kubectl rollout status -n staging deployment/hello-courier --timeout=180s
kill %1
kubectl run -n staging smoke --rm -i --restart=Never --image=curlimages/curl -- -fsS http://hello-courier/
# тЖТ ЁЯУо hello from hello-courier-тАж ┬╖ version v2
# 4) rollback, both ways
kubectl rollout undo -n staging deployment/hello-courier # the emergency lever
kubectl rollout history -n staging deployment/hello-courier
sed "s|IMAGE_PLACEHOLDER|hello-courier:v1|" k8s/deployment.yaml | kubectl apply -n staging -f - # preferred: redeploy yesterday's tag
# cleanup
kind delete cluster --name school
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- readiness probe рдирд╕рд▓реЗрд▓рд╛ Deployment рдкрд╛рдард╡рдгреЗ тАФ rollout "requests рдирд╛ рдЙрддреНрддрд░ рджреЗрддреЛ" рд╡рд░ рдирд╡реНрд╣реЗ рддрд░ "process рд╕реБрд░реВ рдЭрд╛рд▓реА" рд╡рд░ рдкреБрдвреЗ рдЬрд╛рддреЛ, рдЖрдгрд┐ рддреБрдЯрд▓реЗрд▓реА image рдЪрд╛рдВрдЧрд▓реЗ pods рдмрджрд▓реВрди рдЯрд╛рдХрддреЗ
kubectl rollout undoрдиреЗ rollback рдХрд░реВрди рдХрд╛рдо рд╕рдВрдкрд▓реЗ рдЕрд╕реЗ рдорд╛рдирдгреЗ тАФ рдЖрддрд╛ cluster рд╣реЗ pipeline рдиреЗ рд╢реЗрд╡рдЯреА apply рдХреЗрд▓реЗрд▓реНрдпрд╛рдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реЗ рдЖрд╣реЗ; рдЬреБрдирд╛ tag рдкреБрдиреНрд╣рд╛ deploy рдХрд░рд╛ рдореНрд╣рдгрдЬреЗ run log рдЖрдгрд┐ рдлрд▓рдХ рдЬреБрд│рддреАрд▓- code рдмрджрд▓рд╛рдЪреНрдпрд╛рдЪ deploy рдордзреНрдпреЗ рд╡рд┐рдзреНрд╡рдВрд╕рдХ schema migration рдЪрд╛рд▓рд╡рдгреЗ тАФ rollout рдЪрд╛рд▓реВ рдЕрд╕реЗрдкрд░реНрдпрдВрдд рдЬреБрдиреЗ pods рддреНрдпрд╛рдЪ database рд╢реА рдмреЛрд▓рдд рдЕрд╕рддрд╛рдд
тПня╕П рдкреБрдвреЗ
рд╡реНрд╣реЕрди рдлрд▓рдХрд╛рд╡рд░ рдХрд╛рдп рдХрд░рддреЗ рддреЗ рддреБрдореНрд╣реА рдкрд╛рд╣рд┐рд▓реЗ. рдЖрддрд╛ рд╡реНрд╣реЕрди рд╕реНрд╡рддрдГ: pipeline рд▓рд╛ cluster рдордзреНрдпреЗ day pass рдХрд╕рд╛ рдорд┐рд│рддреЛ, рддреА placeholder рдХрд╕рд╛ рдмрджрд▓рддреЗ, рдЖрдгрд┐ рдШрд░реА рдкрд░рдд рдХреЗрд╡реНрд╣рд╛ рдЬрд╛рдпрдЪреЗ рд╣реЗ рддрд┐рд▓рд╛ рдХрд╕реЗ рдХрд│рддреЗ.
git checkout lesson-10-deploy-to-kubernetes