ΠΡΠΈΠΌ. ΠΏΠ΅ΡΠ΅Π².: ΠΡΠΎΡ ΠΎΠ±Π·ΠΎΡΠ½ΡΠΉ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π» ΠΎΡ Weaveworks Π·Π½Π°ΠΊΠΎΠΌΠΈΡ Ρ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΡΠΌΠΈ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡΠΌΠΈ Π²ΡΠΊΠ°ΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ ΡΠ°ΡΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΡ ΠΈΠ· Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Kubernetes-ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° Flagger. ΠΠ½ Π½Π°ΠΏΠΈΡΠ°Π½ ΠΏΡΠΎΡΡΡΠΌ ΡΠ·ΡΠΊΠΎΠΌ ΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°Π³Π»ΡΠ΄Π½ΡΠ΅ ΡΡ Π΅ΠΌΡ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠ΅ ΡΠ°Π·ΠΎΠ±ΡΠ°ΡΡΡΡ Π² Π²ΠΎΠΏΡΠΎΡΠ΅ Π΄Π°ΠΆΠ΅ Π½Π°ΡΠΈΠ½Π°ΡΡΠΈΠΌ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠ°ΠΌ.
Π‘Ρ
Π΅ΠΌΠ° Π²Π·ΡΡΠ° ΠΈΠ·
ΠΠ΄Π½ΠΎΠΉ ΠΈΠ· ΡΠ°ΠΌΡΡ Π±ΠΎΠ»ΡΡΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΠΏΡΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ cloud native-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΡΠ΅Π³ΠΎΠ΄Π½Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΠΊΠΎΡΠ΅Π½ΠΈΠ΅ Π΄Π΅ΠΏΠ»ΠΎΡ. ΠΡΠΈ ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΡΠ½ΠΎΠΌ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΡΠΆΠ΅ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΌΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌΠΈ ΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΡΡΡ ΠΈΡ , ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΠΈΡΠ°ΡΡ ΠΊΠΎΠ΄ ΠΈ Π²Π½ΠΎΡΠΈΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
ΠΠΎΠ»Π΅Π΅ ΠΊΠΎΡΠΎΡΠΊΠΈΠ΅ ΠΈ ΡΠ°ΡΡΡΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΠΈΠΌΠ΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°:
- Π‘ΠΎΠΊΡΠ°ΡΠ°Π΅ΡΡΡ Π²ΡΠ΅ΠΌΡ Π²ΡΡ ΠΎΠ΄Π° Π½Π° ΡΡΠ½ΠΎΠΊ.
- ΠΠΎΠ²ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π±ΡΡΡΡΠ΅Π΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ ΠΊ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΠΌ.
- ΠΡΠΊΠ»ΠΈΠΊΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ Π±ΡΡΡΡΠ΅Π΅ Π΄ΠΎΡ ΠΎΠ΄ΡΡ Π΄ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ². ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΌΠΎΠΆΠ΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈ ΠΈΡΠΏΡΠ°Π²Π»ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎ.
- ΠΠΎΠ²ΡΡΠ°Π΅ΡΡΡ ΠΌΠΎΡΠ°Π»ΡΠ½ΡΠΉ Π΄ΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ²: Ρ Π±ΠΎΠ»ΡΡΠΈΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΉ Π² ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π΅Π΅ ΡΠ°Π±ΠΎΡΠ°ΡΡ.
ΠΠΎ Ρ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ°ΡΡΠΎΡΡ ΡΠ΅Π»ΠΈΠ·ΠΎΠ² ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠ²ΡΡΠ°ΡΡΡΡ ΡΠ°Π½ΡΡ Π½Π΅Π³Π°ΡΠΈΠ²Π½ΠΎ ΠΏΠΎΠ²Π»ΠΈΡΡΡ Π½Π° Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΎΠΏΡΡ. ΠΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΡΡΠΎΠΌΡ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΠΈ DevOps Π²Π°ΠΆΠ½ΠΎ ΡΡΡΠΎΠΈΡΡ ΠΏΡΠΎΡΠ΅ΡΡΡ ΠΈ ΡΠΏΡΠ°Π²Π»ΡΡΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡΠΌΠΈ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΈΡΠΊ Π΄Π»Ρ ΠΏΡΠΎΠ΄ΡΠΊΡΠ° ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ. (Π£Π·Π½Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΎΠ± Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΠΈ CI/CD-ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° ΠΌΠΎΠΆΠ½ΠΎ
Π ΡΡΠΎΠΉ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΌΡ ΠΎΠ±ΡΡΠ΄ΠΈΠΌ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ Π΄Π΅ΠΏΠ»ΠΎΡ Π² Kubernetes, Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ rolling-ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠ΅ (canary) Π²ΡΠΊΠ°ΡΡ ΠΈ ΠΈΡ ΡΠ°Π·Π½ΠΎΠ²ΠΈΠ΄Π½ΠΎΡΡΠΈ.
Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΠΈ Π΄Π΅ΠΏΠ»ΠΎΡ
Π‘ΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠΈΠΏΠΎΠ² ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΉ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ, ΠΊΠΎΠΈΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠ΅Π»ΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ Π²Π½Π΅ΡΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² Π½Π΅ΠΊΠΎΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΈΠ»ΠΈ Π² ΠΏΠΎΠ΄ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ/ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ², ΠΈΠ»ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΡΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡ , ΠΏΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΡΠ΄Π΅Π»Π°ΡΡ Π½Π΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠ±ΡΠ΅Π΄ΠΎΡΡΡΠΏΠ½ΠΎΠΉ.
Rolling (ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΡΠΉ, Β«Π½Π°ΠΊΠ°ΡΡΠ²Π°Π΅ΠΌΡΠΉΒ» Π΄Π΅ΠΏΠ»ΠΎΠΉ)
ΠΡΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ Π² Kubernetes. ΠΠ½Π° ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ, ΠΎΠ΄ΠΈΠ½ Π·Π° Π΄ΡΡΠ³ΠΈΠΌ, Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ pod’Ρ ΡΠΎ ΡΡΠ°ΡΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π° pod’Ρ Ρ Π½ΠΎΠ²ΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ β Π±Π΅Π· ΠΏΡΠΎΡΡΠΎΡ ΠΊΠ»Π°ΡΡΠ΅ΡΠ°.
Kubernetes Π΄ΠΎΠΆΠΈΠ΄Π°Π΅ΡΡΡ Π³ΠΎΡΠΎΠ²Π½ΠΎΡΡΠΈ Π½ΠΎΠ²ΡΡ
pod’ΠΎΠ² ΠΊ ΡΠ°Π±ΠΎΡΠ΅ (ΠΏΡΠΎΠ²Π΅ΡΡΡ ΠΈΡ
Ρ ΠΏΠΎΠΌΠΎΡΡΡ
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: awesomeapp
spec:
replicas: 3
template:
metadata:
labels:
app: awesomeapp
spec:
containers:
- name: awesomeapp
image: imagerepo-user/awesomeapp:new
ports:
- containerPort: 8080
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π½Π°ΠΊΠ°ΡΡΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠΎΡΠ½ΠΈΡΡ Π² ΡΠ°ΠΉΠ»Π΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°:
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
...
Recreate (ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅)
Π ΡΡΠΎΠΌ ΠΏΡΠΎΡΡΠ΅ΠΉΡΠ΅ΠΌ ΡΠΈΠΏΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΡΡΠ°ΡΡΠ΅ pod’Ρ ΡΠ±ΠΈΠ²Π°ΡΡΡΡ Π²ΡΠ΅ ΡΠ°Π·ΠΎΠΌ ΠΈ Π·Π°ΠΌΠ΅Π½ΡΡΡΡΡ Π½ΠΎΠ²ΡΠΌΠΈ:
Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ°ΠΊ:
spec:
replicas: 3
strategy:
type: Recreate
template:
...
Blue/Green (ΡΠΈΠ½Π΅-Π·Π΅Π»Π΅Π½ΡΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ)
Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ ΡΠΈΠ½Π΅-Π·Π΅Π»Π΅Π½ΠΎΠ³ΠΎ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ (ΠΈΠ½ΠΎΠ³Π΄Π° Π΅Π΅ Π΅ΡΡ Π½Π°Π·ΡΠ²Π°ΡΡ red/black, Ρ.Π΅. ΠΊΡΠ°ΡΠ½ΠΎ-ΡΡΡΠ½ΠΎΠΉ) ΠΏΡΠ΅Π΄ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅Ρ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅ ΡΡΠ°ΡΠΎΠΉ (Π·Π΅Π»Π΅Π½ΠΎΠΉ) ΠΈ Π½ΠΎΠ²ΠΎΠΉ (ΡΠΈΠ½Π΅ΠΉ) Π²Π΅ΡΡΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎΡΠ»Π΅ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΠ±Π΅ΠΈΡ Π²Π΅ΡΡΠΈΠΉ ΠΎΠ±ΡΡΠ½ΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ Π·Π΅Π»Π΅Π½ΠΎΠΉ, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ ΡΠΈΠ½ΡΡ Π΄ΠΎΡΡΡΠΏΠ½Π° Π΄Π»Ρ QA-ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π΄Π»Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΠΈ ΡΠ΅ΡΡΠΎΠ² ΡΠ΅ΡΠ΅Π· ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²ΠΈΡ ΠΈΠ»ΠΈ ΠΏΡΡΠΌΠΎΠΉ ΠΏΡΠΎΠ±ΡΠΎΡ ΠΏΠΎΡΡΠΎΠ²:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: awesomeapp-02
spec:
template:
metadata:
labels:
app: awesomeapp
version: "02"
ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠΈΠ½ΡΡ (Π½ΠΎΠ²Π°Ρ) Π²Π΅ΡΡΠΈΡ Π±ΡΠ»Π° ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½Π° ΠΈ Π±ΡΠ» ΠΎΠ΄ΠΎΠ±ΡΠ΅Π½ Π΅Π΅ ΡΠ΅Π»ΠΈΠ·, ΡΠ΅ΡΠ²ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π½Π° Π½Π΅Ρ, Π° Π·Π΅Π»Π΅Π½Π°Ρ (ΡΡΠ°ΡΠ°Ρ) ΡΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ:
apiVersion: v1
kind: Service
metadata:
name: awesomeapp
spec:
selector:
app: awesomeapp
version: "02"
...
Canary (ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ)
ΠΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠ΅ Π²ΡΠΊΠ°ΡΡ ΠΏΠΎΡ
ΠΎΠΆΠΈ Π½Π° ΡΠΈΠ½Π΅-Π·Π΅Π»Π΅Π½ΡΠ΅, Π½ΠΎ Π»ΡΡΡΠ΅ ΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ
ΠΡΠ° ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΡΡΠ°ΡΡ Π½Π΅ΠΊΡΡ Π½ΠΎΠ²ΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, Π² Π±ΡΠΊΠ΅Π½Π΄Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π‘ΡΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° Π² ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π΄Π²Π° ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ°: ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ, Π° Π΄ΡΡΠ³ΠΎΠΉ, Ρ Π½ΠΎΠ²ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ, ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π΅Ρ Π»ΠΈΡΡ Π½Π΅Π±ΠΎΠ»ΡΡΡΡ ΠΏΠΎΠ΄Π³ΡΡΠΏΠΏΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΡΡΠ°Π²Π½ΠΈΠ²Π°ΡΡΡΡ. ΠΡΠ»ΠΈ Π²ΡΠ΅ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡ Π±Π΅Π· ΠΎΡΠΈΠ±ΠΎΠΊ, Π½ΠΎΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ Π²ΡΠΊΠ°ΡΡΠ²Π°Π΅ΡΡΡ Π½Π° Π²ΡΡ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ.
Π₯ΠΎΡΡ Π΄Π°Π½Π½ΡΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΡΠ΅Π΄ΡΡΠ²Π°ΠΌΠΈ Kubernetes, Π·Π°ΠΌΠ΅Π½ΡΡ ΡΡΠ°ΡΡΠ΅ pod’Ρ Π½Π° Π½ΠΎΠ²ΡΠ΅, Π³ΠΎΡΠ°Π·Π΄ΠΎ ΡΠ΄ΠΎΠ±Π½Π΅Π΅ ΠΈ ΠΏΡΠΎΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ service mesh Π²ΡΠΎΠ΄Π΅ Istio.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ Π²Π°Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π΄Π²Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° Π² Git: ΠΎΠ±ΡΡΠ½ΡΠΉ Ρ ΡΠ΅Π³ΠΎΠΌ 0.1.0 ΠΈ Β«ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠΉΒ» Ρ ΡΠ΅Π³ΠΎΠΌ 0.2.0. ΠΠ·ΠΌΠ΅Π½ΡΡ Π²Π΅ΡΠ° Π² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ΅ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ»ΡΠ·Π° Istio, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΏΡΠ°Π²Π»ΡΡΡ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ ΡΡΠ°ΡΠΈΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠΈΠΌΠΈ Π΄Π²ΡΠΌΡ deployment’Π°ΠΌΠΈ:
ΠΠΎΡΠ°Π³ΠΎΠ²ΠΎΠ΅ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ΠΏΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΡ
ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Istio ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Π΅
ΠΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ Ρ Weaveworks Flagger
Flagger Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΡΠ΅Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π½ΠΈΠΌΠΈ. ΠΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Istio ΠΈΠ»ΠΈ AWS App Mesh Π΄Π»Ρ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΠΈ ΠΈ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠ°ΡΠΈΠΊΠ°, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Prometheus Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π° ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ². ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, Π°Π½Π°Π»ΠΈΠ· ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΡ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Π²Π΅Π±Ρ ΡΠΊΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ ΠΏΡΠΈΠ΅ΠΌΠΎΡΠ½ΡΡ (acceptance) ΡΠ΅ΡΡΠΎΠ², Π½Π°Π³ΡΡΠ·ΠΎΡΠ½ΡΡ ΠΈ Π»ΡΠ±ΡΡ Π΄ΡΡΠ³ΠΈΡ ΡΠΈΠΏΠΎΠ² ΠΏΡΠΎΠ²Π΅ΡΠΎΠΊ.
ΠΠ° ΠΎΡΠ½ΠΎΠ²Π΅ deployment’Π° Kubernetes ΠΈ, ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π³ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ pod’ΠΎΠ² (HPA), Flagger ΡΠΎΠ·Π΄Π°Π΅Ρ Π½Π°Π±ΠΎΡΡ ΠΈΠ· ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² (deployment’Ρ Kubernetes, ΡΠ΅ΡΠ²ΠΈΡΡ ClusterIP ΠΈ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠ΅ΡΠ²ΠΈΡΡ Istio ΠΈΠ»ΠΈ App Mesh) Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΡ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠΉ:
Π Π΅Π°Π»ΠΈΠ·ΡΡ ΠΊΠΎΠ½ΡΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ (control loop), Flagger ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΡΠ°ΡΠΈΠΊ Π½Π° ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ, ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ ΠΈΠ·ΠΌΠ΅ΡΡΡ ΠΊΠ»ΡΡΠ΅Π²ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Π΄ΠΎΠ»Ρ ΡΡΠΏΠ΅ΡΠ½ΡΡ
HTTP-Π·Π°ΠΏΡΠΎΡΠΎΠ², ΡΡΠ΅Π΄Π½ΡΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ Π·Π°ΠΏΡΠΎΡΠ° ΠΈ Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅ pod’ΠΎΠ². ΠΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡΡ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π΅ KPI (ΠΊΠ»ΡΡΠ΅Π²ΡΡ
ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ), ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½Π°Ρ ΡΠ°ΡΡΡ Π»ΠΈΠ±ΠΎ ΡΠ°ΡΡΠ΅Ρ, Π»ΠΈΠ±ΠΎ ΡΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ, ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ Π°Π½Π°Π»ΠΈΠ·Π° ΠΏΡΠ±Π»ΠΈΠΊΡΡΡΡΡ Π² Slack. ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠ°ΡΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Π΅
Dark (ΡΠΊΡΡΡΡΠ΅) ΠΈΠ»ΠΈ Π/Π-ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ
Π‘ΠΊΡΡΡΠΎΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅ β Π΅ΡΠ΅ ΠΎΠ΄Π½Π° Π²Π°ΡΠΈΠ°ΡΠΈΡ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΠΎΠΉ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ (Ρ Π½Π΅ΠΉ, ΠΊΡΡΠ°ΡΠΈ, Flagger ΡΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ). Π Π°Π·Π½ΠΈΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΊΡΡΡΡΠΌ ΠΈ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠΌ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΡΠΊΡΡΡΡΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΠΈΠΌΠ΅ΡΡ Π΄Π΅Π»ΠΎ Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄ΠΎΠΌ, Π° Π½Π΅ Ρ Π±ΡΠΊΠ΅Π½Π΄ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠ΅.
ΠΡΡΠ³ΠΎΠ΅ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΡΡΠΈΡ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠΉ β Π/Π-ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅. ΠΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΡΠΊΡΡΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ Π½ΠΎΠ²ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΠΌ, Π΅Π΅ ΠΏΡΠ΅Π΄Π»Π°Π³Π°ΡΡ Π»ΠΈΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠΉ ΠΈΡ ΡΠ°ΡΡΠΈ. ΠΠ±ΡΡΠ½ΠΎ ΡΡΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ Π½Π΅ Π·Π½Π°ΡΡ, ΡΡΠΎ Π²ΡΡΡΡΠΏΠ°ΡΡ ΡΠ΅ΡΡΠ΅ΡΠ°ΠΌΠΈ-ΠΏΠ΅ΡΠ²ΠΎΠΏΡΠΎΡ ΠΎΠ΄ΡΠ°ΠΌΠΈ (ΠΎΡΡΡΠ΄Π° ΠΈ ΡΠ΅ΡΠΌΠΈΠ½ Β«ΡΠΊΡΡΡΠΎΠ΅ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅Β»).
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°ΡΠ΅Π»Π΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ (feature toggles) ΠΈ Π΄ΡΡΠ³ΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΡΠ»Π΅Π΄ΠΈΡΡ Π·Π° ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΡΡΡ Ρ Π½ΠΎΠ²ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ, ΡΠ²Π»Π΅ΠΊΠ°Π΅Ρ Π»ΠΈ ΠΎΠ½Π° ΠΈΡ ΠΈΠ»ΠΈ ΠΎΠ½ΠΈ ΡΡΠΈΡΠ°ΡΡ Π½ΠΎΠ²ΡΠΉ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π·Π°ΠΏΡΡΠ°Π½Π½ΡΠΌ, ΠΈ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΠΌΠ΅ΡΡΠΈΠΊ.
Flagger ΠΈ A/B-ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ
ΠΠΎΠΌΠΈΠΌΠΎ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΠΈ Ρ ΡΡΡΡΠΎΠΌ Π²Π΅ΡΠΎΠ², Flagger ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΏΡΠ°Π²Π»ΡΡΡ Π½Π° ΠΊΠ°Π½Π°ΡΠ΅Π΅ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ ΡΡΠ°ΡΠΈΠΊ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² HTTP. ΠΡΠΈ Π/Π-ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ HTTP ΠΈΠ»ΠΈ ΡΠ°ΠΉΠ»Ρ cookie Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ. ΠΡΠΎ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ Π² ΡΠ»ΡΡΠ°Π΅ frontend-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΡΡΠ΅Π±ΡΡΡΠΈΡ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΈ ΡΠ΅ΡΡΠΈΠΈ ΠΊ ΡΠ΅ΡΠ²Π΅ΡΡ (session affinity). ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Flagger.
ΠΠ²ΡΠΎΡ Π²ΡΡΠ°ΠΆΠ°Π΅Ρ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΠ½ΠΎΡΡΡ
P.S. ΠΎΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΡΠΈΠΊΠ°
Π§ΠΈΡΠ°ΠΉΡΠ΅ ΡΠ°ΠΊΠΆΠ΅ Π² Π½Π°ΡΠ΅ΠΌ Π±Π»ΠΎΠ³Π΅:
- Β«
ΠΠ±Π·ΠΎΡ ΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠΎΠ² Ingress Π΄Π»Ρ Kubernetes Β»; - Β«
werf β Π½Π°Ρ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π΄Π»Ρ CI/CD Π² Kubernetes (ΠΎΠ±Π·ΠΎΡ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ Π΄ΠΎΠΊΠ»Π°Π΄Π°) Β»; - Β«
Π‘Π±ΠΎΡΠΊΠ° ΠΈ Π΄Π΅ΠΏΠ»ΠΎΠΉ ΠΎΠ΄Π½ΠΎΡΠΈΠΏΠ½ΡΡ ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΡΠΎΠ² Ρ werf ΠΈ GitLab CI Β»; - Β«
Π§ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΊΠΎΠ΅ GitOps? Β».
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com