Canary Deployment у Kubernetes #3: Istio

Використання Istio+Kiali для запуску та візуалізації Canary деплою

Canary Deployment у Kubernetes #3: Istio

Статті цього циклу

  1. Canary Deployment у Kubernetes #1: Gitlab CI
  2. Canary Deployment в Kubernetes #2: Argo Rollouts
  3. (ця стаття)
  4. Canary Deployment використовуючи Jenkins-X Istio Flagger

Канарське розгортання

Сподіваємось, що ви читали першу частину, де ми коротко пояснювали, що таке Canary deployments і показували як його реалізувати за допомогою стандартних ресурсів Kubernetes.

Істіо

І ми припускаємо, що читаючи цю статтю, ви вже знаєте, що таке Istio. Якщо ні, то ви можете почитати про нього тут.

Додаток для тестів

Canary Deployment у Kubernetes #3: Istio

Кожен під містить два контейнери: наш додаток та istio-proxy.

Ми будемо використовувати простий тестовий додаток з подами frontend-nginx і backend на python. Під з nginx просто перенаправляти кожен запит на під з backend і працювати як проксі. Деталі можна переглянути докладніше в наступних yamls:

Запуск тестової програми самостійно

Якщо ви хочете наслідувати мій приклад і використовувати цей тестовий додаток самостійно, див. readme проекту.

Початковий Deployment

При запуску першого Deployment бачимо, що поди нашої програми мають всього по 2 контейнери, тобто Istio sidecar поки що тільки впроваджується:

Canary Deployment у Kubernetes #3: Istio

І також бачимо Istio Gateway Loadbalancer у namespace istio-system:

Canary Deployment у Kubernetes #3: Istio

Створення трафіку

Ми будемо використовувати наступний IP, щоб згенерувати трафік, який буде прийнятий frontend подами і перенаправлений на backend поди:

while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done

Ми також додамо frontend.istio-test у нашому hosts файл.

Перегляд Mesh через Kiali

Ми встановили тестовий додаток та Istio разом з Tracing, Grafana, Prometheus та Kiali (докладніше див. readme проекту). Отже, ми можемо використовувати Kiali через:

istioctl dashboard kiali # admin:admin

Canary Deployment у Kubernetes #3: Istio

Kiali візуалізує поточний трафік через Mesh

Як ми бачимо, 100% трафіку потрапляє на frontend service, потім на під фронтенда з label v1, тому що ми використовуємо простий nginx-проксі, який перенаправляє запити на backend service, який у свою чергу перенаправляє їх на backend поди з label v1.

Kiali працює відмінно разом з Istio та надає коробкове рішення для візуалізації Mesh. Просто чудово.

Канарське розгортання

Наш бекенд вже має два k8s deployments, один для v1 та один для v2. Тепер нам просто сказати Istio перенаправляти певний відсоток запитів на v2.

Крок 1: 10%

І все, що нам потрібно зробити це відрегулювати вагу VirtualService в istio.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Canary Deployment у Kubernetes #3: Istio

Ми бачимо, що 10% запитів перенаправлено на v2.

Крок 2: 50%

І тепер досить просто збільшити його до 50%:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
...
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 50
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 50

Canary Deployment у Kubernetes #3: Istio

Крок 3: 100%

Тепер Canary deployment може вважатися завершеним і весь трафік перенаправляється на v2:

Canary Deployment у Kubernetes #3: Istio

Тестування Canary вручну

Допустимо, зараз ми відправляємо на бекенд v2 10% від усіх запитів. Що, якщо ми хочемо вручну протестувати v2, щоб переконатися, що все працює, як ми очікуємо?

Ми можемо додати спеціальне відповідне правило, засноване на заголовках HTTP:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - headers:
        canary:
          exact: "canary-tester"
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Тепер використовуючи curl ми можемо примусово запросити v2 надіславши заголовок:

Canary Deployment у Kubernetes #3: Istio

Запити без заголовка все ще керуватимуться співвідношенням 1/10:

Canary Deployment у Kubernetes #3: Istio

Canary для двох залежних версій

Тепер ми розглянемо варіант, де ми маємо версію v2 і для frontend і для backend. Для обох ми вказали, що 10% трафіку має йти до v2:

Canary Deployment у Kubernetes #3: Istio

Ми бачимо, що frontend v1 та v2 обидва пересилають трафік у співвідношенні 1/10 на backend v1 та v2.

А що якби ми нам потрібно було пересилати трафік з frontend-v2 тільки на backend-v2, тому що він не сумісний з v1? Для цього ми встановимо 1/10 співвідношення для frontend, який контролює який трафік потрапляє на backend-v2 використовуючи узгодження з sourceLabels :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
...
  - match:
    - sourceLabels:
        app: frontend
        version: v2
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100

В результаті отримуємо те, що потрібно:

Canary Deployment у Kubernetes #3: Istio

Відмінності від ручного Canary підходу

В першій частині ми виконували Canary deployment вручну, також використовуючи два k8s deployments. Там ми керували співвідношенням запитів, змінюючи кількість реплік. Такий підхід працює, але має серйозні вади.

Istio дає можливість визначати співвідношення запитів, незалежно від кількості реплік. Це означає, наприклад, що ми можемо використовувати HPAs (Horizontal Pod Autoscalers — горизонтальне масштабування подів) і його не потрібно налаштовувати відповідно до поточного стану Canary деплою.

Підсумок

Istio працює чудово і використовуючи його разом із Kiali отримуємо дуже потужну комбінацію. Наступний у моєму списку інтересів це комбінація Spinnaker з Istio для автоматизації та Canary-аналітики.

Джерело: habr.com

Додати коментар або відгук