рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рд╕реАрдбреА рдХреЛ рдПрдХ рдЙрджреНрдпрдо рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЕрднреНрдпрд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реИ рдФрд░ рдпрд╣ рд╕реНрдерд╛рдкрд┐рдд рд╕реАрдЖрдИ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╡рд┐рдХрд╛рд╕ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реАрдбреА рдЕрднреА рднреА рдХрд╛рдлреА рджреБрд░реНрд▓рдн рд╣реИ, рд╢рд╛рдпрдж рдкреНрд░рдмрдВрдзрди рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЕрд╕рдлрд▓ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рдбрд░ рдХреЗ рдХрд╛рд░рдгред

рдлреНрд▓реИрдЧрд░ рдПрдХ рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдСрдкрд░реЗрдЯрд░ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд░рд┐рд╢реНрддреЛрдВ рдХреЛ рдЦрддреНрдо рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдПрдХ рдкреНрд░рдмрдВрдзрд┐рдд рд░реЛрд▓рдЖрдЙрдЯ рдХреЗ рджреМрд░рд╛рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Istio рдЯреНрд░реИрдлрд╝рд┐рдХ рдСрдлрд╝рд╕реЗрдЯ рдФрд░ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреИрдирд░реА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рдкреНрд░рдЪрд╛рд░ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред

рдиреАрдЪреЗ Google Kubernetes Engine (GKE) рдкрд░ рдлрд╝реНрд▓реИрдЧрд░ рдХреЛ рд╕реЗрдЯ рдЕрдк рдХрд░рдиреЗ рдФрд░ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░рдг-рджрд░-рдЪрд░рдг рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рджреА рдЧрдИ рд╣реИред

рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреНрд▓рд╕реНрдЯрд░ рдХреА рд╕реНрдерд╛рдкрдирд╛

рдЖрдк Istio рдРрдб-рдСрди рдХреЗ рд╕рд╛рде GKE рдХреНрд▓рд╕реНрдЯрд░ рдмрдирд╛рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ (рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ GCP рдЦрд╛рддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рд╕рд╛рдЗрди рдЕрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╣рд╛рдВ - рдореБрдлреНрдд рдХреНрд░реЗрдбрд┐рдЯ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП)ред

Google рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╕рд╛рдЗрди рдЗрди рдХрд░реЗрдВ, рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд┐рд▓рд┐рдВрдЧ рд╕рдХреНрд╖рдо рдХрд░реЗрдВред рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ gcloud рдФрд░ рдХреЗ рд╕рд╛рде рдЕрдкрдирд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗрдЯ рдХрд░реЗрдВ gcloud init.

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗрдЯ рдХрд░реЗрдВ, рдХреНрд╖реЗрддреНрд░ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ, рдФрд░ рдЬрд╝реЛрди (рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ PROJECT_ID рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП):

gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a

GKE рд╕реЗрд╡рд╛ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░реЗрдВ рдФрд░ HPA рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдРрдб-рдСрди рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рдмрдирд╛рдПрдБ:

gcloud services enable container.googleapis.com
K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]')
gcloud beta container clusters create istio 
--cluster-version=${K8S_VERSION} 
--zone=us-central1-a 
--num-nodes=2 
--machine-type=n1-standard-2 
--disk-size=30 
--enable-autorepair 
--no-enable-cloud-logging 
--no-enable-cloud-monitoring 
--addons=HorizontalPodAutoscaling,Istio 
--istio-config=auth=MTLS_PERMISSIVE

рдЙрдкрд░реЛрдХреНрдд рдЖрджреЗрд╢ рджреЛ рд╡реАрдПрдо рд╕рд╣рд┐рдд рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдиреЛрдб рдкреВрд▓ рдмрдирд╛рдПрдЧрд╛ n1-standard-2 (рд╡реАрд╕реАрдкреАрдпреВ: 2, рд░реИрдо 7,5 рдЬреАрдмреА, рдбрд┐рд╕реНрдХ: 30 рдЬреАрдмреА)ред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдЖрдкрдХреЛ рдЗрд╕реНрддрд┐рдпреЛ рдШрдЯрдХреЛрдВ рдХреЛ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрднрд╛рд░ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдЗрд╕реНрддрд┐рдпреЛ рдкреЙрдбреНрд╕ рдХреЛ рд╕рдорд░реНрдкрд┐рдд рдиреЛрдбреНрд╕ рдкреВрд▓ рдореЗрдВ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдХреЛрдИ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред Istio рдореЗрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ GKE рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдкреВрд░реНрд╡рд╡рдд рдХрд░ рджреЗрдЧрд╛, рдЬреИрд╕реЗ рдиреЛрдб рд╕реЗ рд▓рд┐рдВрдХ рдХрд░рдирд╛ рдпрд╛ рдкреЙрдб рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ред

рдХреЗ рд▓рд┐рдП рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рд╕реЗрдЯ рдХрд░реЗрдВ kubectl:

gcloud container clusters get-credentials istio

рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рд░реЛрд▓ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдмрдирд╛рдПрдБ:

kubectl create clusterrolebinding "cluster-admin-$(whoami)" 
--clusterrole=cluster-admin 
--user="$(gcloud config get-value core/account)"

рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЯреВрд▓ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ рдкрддрд╡рд╛рд░:

brew install kubernetes-helm

Homebrew 2.0 рдЕрдм рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрд▓рдмреНрдз рд╣реИ Linux.

рдЯрд┐рд▓рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡рд╛ рдЦрд╛рддрд╛ рдФрд░ рдХреНрд▓рд╕реНрдЯрд░ рд░реЛрд▓ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдмрдирд╛рдПрдБ:

kubectl -n kube-system create sa tiller && 
kubectl create clusterrolebinding tiller-cluster-rule 
--clusterrole=cluster-admin 
--serviceaccount=kube-system:tiller

рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ рдЯрд┐рд▓рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВ kube-system:

helm init --service-account tiller

рдЖрдкрдХреЛ рд╣реЗрд▓рдо рдФрд░ рдЯрд┐рд▓рд░ рдХреЗ рдмреАрдЪ рдПрд╕рдПрд╕рдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдкрдиреА рд╣реЗрд▓реНрдо рд╕реНрдерд╛рдкрдирд╛ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рджреЗрдЦреЗрдВ рдбреЙрдХреНрд╕.рд╣реЗрд▓реНрдо.рд╢

рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВ:

kubectl -n istio-system get svc

рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж, GCP рдХреЛ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд╣рд░реА IP рдкрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП istio-ingressgateway.

рдЗрд╕реНрддрд┐рдпреЛ рдЗрдирдЧреНрд░реЗрд╕ рдЧреЗрдЯрд╡реЗ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛

рдПрдХ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдерд┐рд░ IP рдкрддрд╛ рдмрдирд╛рдПрдБ istio-gatewayрдЗрд╕реНрддрд┐рдпреЛ рдЧреЗрдЯрд╡реЗ рдХреЗ рдЖрдИрдкреА рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:

export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip)
gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1

рдЕрдм рдЖрдкрдХреЛ рдПрдХ рдЗрдВрдЯрд░рдиреЗрдЯ рдбреЛрдореЗрди рдФрд░ рдЕрдкрдиреЗ DNS рд░рдЬрд┐рд╕реНрдЯреНрд░рд╛рд░ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рджреЛ рдП рд░рд┐рдХреЙрд░реНрдб рдЬреЛрдбрд╝реЗрдВ (рдмрджрд▓реЗрдВ example.com рдЖрдкрдХреЗ рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдП):

istio.example.com   A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}

рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ рдХрд┐ DNS рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ:

watch host test.istio.example.com

HTTP рдкрд░ рд╕рд░реНрд╡рд┐рд╕ рдореЗрд╢ рдХреЗ рдмрд╛рд╣рд░ рд╕реЗрд╡рд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЗрд╕реНрддрд┐рдпреЛ рдЧреЗрдЯрд╡реЗ рдмрдирд╛рдПрдВ:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

рдЙрдкрд░реЛрдХреНрдд рд╕рдВрд╕рд╛рдзрди рдХреЛ public-gateway.yaml рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

kubectl apply -f ./public-gateway.yaml

рдПрд╕рдПрд╕рдПрд▓ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рднреА рдЙрддреНрдкрд╛рджрди рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рд╕реЗрд╡рд╛рдПрдВ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рд╕рд░реНрдЯрд┐рдлрд┐рдХреЗрдЯ-рдореИрдиреЗрдЬрд░, CloudDNS рдФрд░ рд▓реЗрдЯреНрд╕ рдПрдирдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде Istio рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреГрдкрдпрд╛ рдкрдврд╝реЗрдВ рдкреНрд░рд▓реЗрдЦрди рдлреНрд▓реИрдЧрд░ рдЬреА.рдХреЗ.рдИ.

рдлреНрд▓реИрдЧрд░ рд╕реНрдерд╛рдкрдирд╛

GKE Istio рдРрдб-рдСрди рдореЗрдВ Prometheus рдЙрджрд╛рд╣рд░рдг рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ рдЬреЛ Istio рдЯреЗрд▓реАрдореЗрдЯреНрд░реА рд╕реЗрд╡рд╛ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рддрд╛ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рдлреНрд▓реИрдЧрд░ рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддрд┐рдпреЛ рдПрдЪрдЯреАрдЯреАрдкреА рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЗрд╕реНрддрд┐рдпреЛ рд╣реЗрд▓реНрдо рд╕реНрдХреАрдорд╛ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рд╕рдорд╛рди рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml

рдлрд╝реНрд▓реИрдЧрд░ рд╣реЗрд▓реНрдо рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЬреЛрдбрд╝реЗрдВ:

helm repo add flagger [https://flagger.app](https://flagger.app/)

рдлреНрд▓реИрдЧрд░ рдХреЛ рдиреЗрдорд╕реНрдкреЗрд╕ рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рдХрд░реЗрдВ istio-systemрд╕реБрд╕реНрдд рд╕реВрдЪрдирд╛рдУрдВ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдХреЗ:

helm upgrade -i flagger flagger/flagger 
--namespace=istio-system 
--set metricsServer=http://prometheus.istio-system:9090 
--set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID 
--set slack.channel=general 
--set slack.user=flagger

рдЖрдк рдлрд╝реНрд▓реИрдЧрд░ рдХреЛ рдХрд┐рд╕реА рднреА рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ рддрдм рддрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рд╡рд╣ рдкреЛрд░реНрдЯ 9090 рдкрд░ рдЗрд╕реНрддрд┐рдпреЛ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдлреНрд▓реИрдЧрд░ рдХреЗ рдкрд╛рд╕ рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреНрд░рд╛рдлрд╛рдирд╛ рдбреИрд╢рдмреЛрд░реНрдб рд╣реИред рдЧреНрд░рд╛рдлрд╛рдирд╛ рдХреЛ рдиреЗрдорд╕реНрдкреЗрд╕ рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ istio-system:

helm upgrade -i flagger-grafana flagger/grafana 
--namespace=istio-system 
--set url=http://prometheus.istio-system:9090 
--set user=admin 
--set password=change-me

рдПрдХ рдЖрднрд╛рд╕реА рд╕реЗрд╡рд╛ рдмрдирд╛рдХрд░ рдПрдХ рдЦреБрд▓реЗ рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреНрд░рд╛рдлрд╛рдирд╛ рдХрд╛ рдкрд░реНрджрд╛рдлрд╛рд╢ рдХрд░реЗрдВ (рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди example.com рдЖрдкрдХреЗ рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдП):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grafana
  namespace: istio-system
spec:
  hosts:
    - "grafana.istio.example.com"
  gateways:
    - public-gateway.istio-system.svc.cluster.local
  http:
    - route:
        - destination:
            host: flagger-grafana

рдЙрдкрд░реЛрдХреНрдд рд╕рдВрд╕рд╛рдзрди рдХреЛ grafana-virtual-service.yaml рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

kubectl apply -f ./grafana-virtual-service.yaml

рдЪрд▓рддреЗ рд╕рдордп http://grafana.istio.example.com рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ, рдЖрдкрдХреЛ рдЧреНрд░рд╛рдлрд╛рдирд╛ рд▓реЙрдЧрд┐рди рдкреГрд╖реНрда рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдлрд╝реНрд▓реИрдЧрд░ рдХреЗ рд╕рд╛рде рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░рд┐рдирд┐рдпреЛрдЬрд┐рдд рдХрд░рдирд╛

рдлрд╝реНрд▓реИрдЧрд░ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреЛ рддреИрдирд╛рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ (HPA) рдХреЛ рдорд╛рдкрддрд╛ рд╣реИ, рдлрд┐рд░ рд╡рд╕реНрддреБрдУрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдмрдирд╛рддрд╛ рд╣реИ (Kubernetes рдкрд░рд┐рдирд┐рдпреЛрдЬрди, ClusterIP рд╕реЗрд╡рд╛рдПрдБ рдФрд░ Istio рд╡рд░реНрдЪреБрдЕрд▓ рд╕реЗрд╡рд╛рдПрдБ)ред рдпреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕реЗрд╡рд╛ рдЬрд╛рд▓ рдореЗрдВ рдЙрдЬрд╛рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдкреНрд░рдЧрддрд┐ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рдЗрд╕реНрддрд┐рдпреЛ рд╕рд╛рдЗрдбрдХрд╛рд░ рдЗрдВрдЬреЗрдХреНрд╢рди рд╕рдХреНрд╖рдо рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░реАрдХреНрд╖рдг рдирд╛рдо рд╕реНрдерд╛рди рдмрдирд╛рдПрдБ:

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml

рдПрдХ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдФрд░ рдПрдХ рдкреЙрдб рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕реНрдХреЗрд▓-рдЖрдЙрдЯ рдЯреВрд▓ рдмрдирд╛рдПрдБ:

kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml

рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди рдЯреНрд░реИрдлрд╝рд┐рдХ рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрд╕реНрдЯ рд▓реЛрдб рд╕реЗрд╡рд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрд┐рдд рдХрд░реЗрдВ:

helm upgrade -i flagger-loadtester flagger/loadtester 
--namepace=test

рдПрдХ рдХрд╕реНрдЯрдо рдХреИрдирд░реА рд╕рдВрд╕рд╛рдзрди рдмрдирд╛рдПрдБ (рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ example.com рдЖрдкрдХреЗ рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдП):

apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  autoscalerRef:
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    port: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.istio.example.com
  canaryAnalysis:
    interval: 30s
    threshold: 10
    maxWeight: 50
    stepWeight: 5
    metrics:
    - name: istio_requests_total
      threshold: 99
      interval: 30s
    - name: istio_request_duration_seconds_bucket
      threshold: 500
      interval: 30s
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"

рдЙрдкрд░реЛрдХреНрдд рд╕рдВрд╕рд╛рдзрди рдХреЛ podinfo-canary.yaml рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

kubectl apply -f ./podinfo-canary.yaml

рдЙрдкрд░реЛрдХреНрдд рд╡рд┐рд╢реНрд▓реЗрд╖рдг, рд╕рдлрд▓ рд╣реЛрдиреЗ рдкрд░, рдкрд╛рдБрдЪ рдорд┐рдирдЯ рддрдХ рдЪрд▓реЗрдЧрд╛, рд╣рд░ рдЖрдзреЗ рдорд┐рдирдЯ рдореЗрдВ HTTP рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ред рдЖрдк рдирд┐рдореНрди рд╕реВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреИрдирд░реА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдФрд░ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдиреНрдпреВрдирддрдо рд╕рдордп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: interval * (maxWeight / stepWeight). рдХреИрдирд░реА рд╕реАрдЖрд░рдбреА рдлрд╝реАрд▓реНрдб рдкреНрд░рд▓реЗрдЦрд┐рдд рд╣реИрдВ рдпрд╣рд╛рдВ.

рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж, рдлрд╝реНрд▓реИрдЧрд░ рдХреИрдирд░реА рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдЧрд╛:

# applied 
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
canary.flagger.app/podinfo
# generated 
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
virtualservice.networking.istio.io/podinfo

рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЦреЛрд▓реЗрдВ рдФрд░ рдкрд░ рдЬрд╛рдПрдВ app.istio.example.com, рдЖрдкрдХреЛ рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ рджреЗрдЦрдиреА рдЪрд╛рд╣рд┐рдП рдбреЗрдореЛ рдРрдкреНрд╕.

рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдкреНрд░рдЪрд╛рд░

рдлреНрд▓реИрдЧрд░ рдПрдХ рдирд┐рдпрдВрддреНрд░рдг рд▓реВрдк рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдЬреЛ HTTP рдЕрдиреБрд░реЛрдз рд╕рдлрд▓рддрд╛ рджрд░, рдФрд╕рдд рдЕрдиреБрд░реЛрдз рдЕрд╡рдзрд┐ рдФрд░ рдкреЙрдб рд╕реНрд╡рд╛рд╕реНрдереНрдп рдЬреИрд╕реЗ рдкреНрд░рдореБрдЦ рдкреНрд░рджрд░реНрд╢рди рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рдорд╛рдкрддреЗ рд╣реБрдП рдзреАрд░реЗ-рдзреАрд░реЗ рдХреИрдирд░реА рдореЗрдВ рдЯреНрд░реИрдлрд╝рд┐рдХ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред KPI рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдХреИрдирд░реА рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╕реНрд▓реИрдХ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рдирд┐рдореНрди рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдиреЗ рдкрд░ рдХреИрдирд░реА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рд╢реБрд░реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:

  • рдкреЙрдбрд╕реНрдкреЗрдХ (рдХрдВрдЯреЗрдирд░ рдЫрд╡рд┐, рдХрдорд╛рдВрдб, рдкреЛрд░реНрдЯ, рдПрдирд╡реА, рдЖрджрд┐) рдХреЛ рддреИрдирд╛рдд рдХрд░реЗрдВред
  • ConfigMaps рдХреЛ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд░реЛрд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рд▓рд┐рдП рдореИрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рд░рд╛рдЬрд╝ рдХреЛ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдЙрдВрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рдХрдВрдЯреЗрдирд░ рдЫрд╡рд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп рдХреИрдирд░реА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдЪрд▓рд╛рдПрдБ:

kubectl -n test set image deployment/podinfo 
podinfod=quay.io/stefanprodan/podinfo:1.4.1

рдлреНрд▓реИрдЧрд░ рдкрддрд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рд╕рдВрд╕реНрдХрд░рдг рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ:

kubectl -n test describe canary/podinfo

Events:

New revision detected podinfo.test
Scaling up podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Advance podinfo.test canary weight 20
Advance podinfo.test canary weight 25
Advance podinfo.test canary weight 30
Advance podinfo.test canary weight 35
Advance podinfo.test canary weight 40
Advance podinfo.test canary weight 45
Advance podinfo.test canary weight 50
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test

рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди, рдЧреНрд░рд╛рдлрд╛рдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреИрдирд░реА рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдореЗрдВ рдирдП рдкрд░рд┐рд╡рд░реНрддрди рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдлреНрд▓реИрдЧрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЪрд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдЧрд╛ред

рдЕрдкрдиреЗ рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рд╕рднреА рдХреИрдирд░реА рдХреА рд╕реВрдЪреА рдмрдирд╛рдПрдВ:

watch kubectl get canaries --all-namespaces
NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   15       2019-01-16T14:05:07Z
prod        frontend  Succeeded     0        2019-01-15T16:15:07Z
prod        backend   Failed        0        2019-01-14T17:05:07Z

рдпрджрд┐ рдЖрдкрдиреЗ рд╕реНрд▓реИрдХ рд╕реВрдЪрдирд╛рдПрдВ рд╕рдХреНрд╖рдо рдХреА рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдирд┐рдореНрди рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдВрдЧреЗ:

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реЛрд▓рдмреИрдХ

рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди, рдЖрдк рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдереЗрдЯрд┐рдХ HTTP 500 рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдФрд░ рдЙрдЪреНрдЪ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╡рд┐рд▓рдВрдмрддрд╛ рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдлрд╝реНрд▓реИрдЧрд░ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ рдпрд╛ рдирд╣реАрдВред

рдПрдХ рдЯреЗрд╕реНрдЯ рдкреЙрдб рдмрдирд╛рдПрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░реЗрдВ:

kubectl -n test run tester 
--image=quay.io/stefanprodan/podinfo:1.2.1 
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx sh

HTTP 500 рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛:

watch curl http://podinfo-canary:9898/status/500

рд╡рд┐рд▓рдВрдм рдкреАрдврд╝реА:

watch curl http://podinfo-canary:9898/delay/1

рдЬрдм рд╡рд┐рдлрд▓ рдЬрд╛рдВрдЪреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рджрд╣рд▓реАрдЬ рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рддреА рд╣реИ, рддреЛ рдпрд╛рддрд╛рдпрд╛рдд рдХреЛ рдкреНрд░рд╛рдердорд┐рдХ рдЪреИрдирд▓ рдкрд░ рд╡рд╛рдкрд╕ рднреЗрдЬ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреИрдирд░реА рдХреЛ рд╢реВрдиреНрдп рдкрд░ рд╕реНрдХреЗрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рд╡рд┐рдлрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХреИрдирд░реА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдФрд░ рд╡рд┐рд▓рдВрдмрддрд╛ рд╕реНрдкрд╛рдЗрдХреНрд╕ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдШрдЯрдирд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЙрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдлреНрд▓реИрдЧрд░ рджреНрд╡рд╛рд░рд╛ JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд▓реЙрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

kubectl -n istio-system logs deployment/flagger -f | jq .msg

Starting canary deployment for podinfo.test
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Halt podinfo.test advancement success rate 69.17% < 99%
Halt podinfo.test advancement success rate 61.39% < 99%
Halt podinfo.test advancement success rate 55.06% < 99%
Halt podinfo.test advancement success rate 47.00% < 99%
Halt podinfo.test advancement success rate 37.00% < 99%
Halt podinfo.test advancement request duration 1.515s > 500ms
Halt podinfo.test advancement request duration 1.600s > 500ms
Halt podinfo.test advancement request duration 1.915s > 500ms
Halt podinfo.test advancement request duration 2.050s > 500ms
Halt podinfo.test advancement request duration 2.515s > 500ms
Rolling back podinfo.test failed checks threshold reached 10
Canary failed! Scaling down podinfo.test

рдпрджрд┐ рдЖрдкрдиреЗ рд╕реБрд╕реНрдд рд╕реВрдЪрдирд╛рдУрдВ рдХреЛ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╕рдордп рд╕реАрдорд╛ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдпрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ рд╡рд┐рдлрд▓ рдЬрд╛рдБрдЪреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдкрд░ рдЖрдкрдХреЛ рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛:

рдлреНрд▓реИрдЧрд░ рдФрд░ рдЗрд╕реНрддрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдХреИрдирд░реА рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреИрдирд╛рддреА

рдЕрдВрдд рдореЗрдВ

рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЗрд╕реНрддрд┐рдпреЛ рдЬреИрд╕реЗ рд╕рд░реНрд╡рд┐рд╕ рдореЗрд╢ рдЪрд▓рд╛рдиреЗ рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдореЗрдЯреНрд░рд┐рдХреНрд╕, рд▓реЙрдЧ рдФрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдЙрдкрд▓рдмреНрдз рд╣реЛрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдХрд╛рд░реНрдпрднрд╛рд░ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдЕрднреА рднреА рдмрд╛рд╣рд░реА рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдлрд╝реНрд▓реИрдЧрд░ рдХрд╛ рд▓рдХреНрд╖реНрдп рдЗрд╕реНрддрд┐рдпреЛ рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рдмрджрд▓рдирд╛ рд╣реИ рдкреНрд░рдЧрддрд┐рд╢реАрд▓ рдЖрдкреВрд░реНрддрд┐.

рдлреНрд▓реИрдЧрд░ рдХрд┐рд╕реА рднреА рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рд╕реАрдЖрдИ/рд╕реАрдбреА рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИ, рдФрд░ рдХреИрдирд░реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ webhooks рд╕рд┐рд╕реНрдЯрдо рдПрдХреАрдХрд░рдг/рд╕реНрд╡реАрдХреГрддрд┐ рдкрд░реАрдХреНрд╖рдг, рд▓реЛрдб рдкрд░реАрдХреНрд╖рдг, рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдХрд╕реНрдЯрдо рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдЪреВрдБрдХрд┐ рдлреНрд▓реИрдЧрд░ рдШреЛрд╖рдгрд╛рддреНрдордХ рд╣реИ рдФрд░ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдШрдЯрдирд╛рдУрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ GitOps рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рд╡реЗрд╡ рдлреНрд▓рдХреНрд╕ рдпрд╛ рдЬреЗрдирдХрд┐рдВрд╕рдХреНрд╕. рдпрджрд┐ рдЖрдк рдЬреЗрдирдХрд┐рдиреНрд╕рдПрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдк рдлреНрд▓реИрдЧрд░ рдХреЛ рдЬреЗрдПрдХреНрд╕ рдПрдбреЙрдиреНрд╕ рдХреЗ рд╕рд╛рде рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдлреНрд▓реИрдЧрд░ рд╕рдорд░реНрдерд┐рдд рдмреБрдирд╛рдИ рдХрд╛ рдХрд╛рдо рдФрд░ рдХреИрдирд░реА рдХреА рддреИрдирд╛рддреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдмрд╛рджрд▓ рдмреБрдиреЗрдВ. рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдЬреАрдХреЗрдИ, рдИрдХреЗрдПрд╕ рдФрд░ рдХреБрдмреЗрдПрдбрдо рдХреЗ рд╕рд╛рде рдирдВрдЧреЗ рдзрд╛рддреБ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдлрд╝реНрд▓реИрдЧрд░ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд╕реБрдЭрд╛рд╡ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ GitHub рдкрд░ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдпрд╛ PR рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВ рд╕реНрдЯреАрдлрдирдкреНрд░реЛрдбрд╛рди/рдлреНрд▓реИрдЧрд░. рдпреЛрдЧрджрд╛рди рд╕реНрд╡рд╛рдЧрдд рд╕реЗ рдЕрдзрд┐рдХ рд╣реИрдВ!

рдзрдиреНрдпрд╡рд╛рдж рд░реЗ рддреНрд╕рд╛рдВрдЧ.

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ