Статьи

Стратегии развертывания с Kubernetes и Istio

В этом посте я собираюсь обсудить различные стратегии развертывания и способы их реализации с помощью K8 и Istio. В основном реализация всех стратегий основана на способности K8 одновременно запускать несколько версий микросервиса и на концепции, что потребители могут получить доступ к микросервису только через какую-то точку входа. В этой точке входа мы можем контролировать, на какую версию микросервиса должен направляться потребитель.

Пример приложения для этого поста будет простым приложением Spring Boot, помещенным в образ Docker. Итак, есть два изображения
superapp: old и superapp: new, представляющие старую и новую версии приложения соответственно:

docker run -d –name old -p 9001: 8080 eugeneflexagon / superapp: old

docker run -d –name new -p 9002: 8080 eugeneflexagon / superapp: new

curl http: // localhost: 9001 / version

{ «ID»: 1,»содержание»:»старый»}

curl http: // localhost: 9002 / version

{ «ID»: 1,»содержание»:»новый»}

Предположим, старая версия приложения развернута в кластере K8s, работающем на Oracle Kubernetes Engine, со следующим манифестом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp
spec:
  replicas: 3
  template:
    metadata:
       labels:
         app: superapp
    spec:
      containers:
        - name: superapp
          image: eugeneflexagon/superapp:old
          ports:
            - containerPort: 8080

Таким образом, есть три копии модуля, на котором запущена старая версия приложения. Существует также сервис, направляющий трафик на эти модули:

01
02
03
04
05
06
07
08
09
10
apiVersion: v1
kind: Service
metadata:
  name: superapp
spec:
  selector:
    app: superapp  
  ports:
    - port: 8080
      targetPort: 8080      

Rolling Update

Эта стратегия развертывания обновляет модули по мере обновления, меняя их одну за другой.

Стратегии развертывания

Это стратегия по умолчанию, которая обрабатывается самим кластером K8s, поэтому нам просто нужно обновить развертывание superapp со ссылкой на новый образ:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp
spec:
  replicas: 3
  template:
    metadata:
       labels:
         app: superapp
    spec:
      containers:
        - name: superapp
          image: eugeneflexagon/superapp:new
          ports:
            - containerPort: 8080

Тем не менее, мы можем точно настроить алгоритм скользящего обновления , предоставив параметры для этой стратегии развертывания в файле манифеста:

1
2
3
4
5
6
7
8
9
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
       maxSurge: 30%
       maxUnavailable: 30%  
  template:
  ...

Параметр maxSurge определяет максимальное количество модулей, которое может быть создано за желаемое количество модулей. Это может быть процент или абсолютное число. Значение по умолчанию составляет 25%.

Параметр maxUnavailable   определяет максимальное количество модулей, которые могут быть недоступны в процессе обновления. Это может быть процент или абсолютное число. Значение по умолчанию составляет 25%.

Recreate

Эта стратегия развертывания убивает все старые модули, а затем создает новые.

Стратегии развертывания
1
2
3
4
5
6
spec:
  replicas: 3
  strategy:
    type: Recreate
  template:
  ...

Очень простой.

Цвет морской волны

Эта стратегия определяет старую версию приложения как зеленую, а новую версию — как синюю . Пользователи всегда имеют доступ только к зеленой версии.

Стратегии развертывания
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp-01
spec:
  template:
    metadata:
       labels:
         app: superapp
         version: "01"
...
 
 
 
apiVersion: v1
kind: Service
metadata:
  name: superapp
spec:
  selector:
    app: superapp
    version: "01"
...

Сервис направляет трафик только на пакеты с версией «01» .

Мы внедряем «голубую» версию в кластер K8s и делаем ее доступной только для обеспечения качества или для инструмента автоматизации тестирования (через отдельный сервис или прямую переадресацию портов).

Стратегии развертывания
01
02
03
04
05
06
07
08
09
10
11
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp-02
spec:
  template:
    metadata:
       labels:
         app: superapp
         version: "02"
...

После тестирования новой версии мы переключаем сервис на нее и уменьшаем старую версию:

Стратегии развертывания
1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Service
metadata:
  name: superapp
spec:
  selector:
    app: superapp
    version: "02"
...
1
kubectl scale deployment superapp-01 --replicas=0

Сделав это, все пользователи работают с новой версией.

Так что Истио пока нет. Все обрабатывается кластером K8s из коробки. Давайте перейдем к следующей стратегии.

канарейка

Мне нравится эта стратегия развертывания, поскольку она позволяет пользователям тестировать новую версию приложения, и они даже не знают об этом. Идея заключается в том, что мы развертываем новую версию приложения и направляем на него 10% трафика. Пользователи понятия не имеют об этом.

Стратегии развертывания

Если это работает некоторое время, мы можем сбалансировать трафик 70/30, затем 50/50 и, в конечном итоге, 0/100.

Даже если эту стратегию можно реализовать с помощью ресурсов K8s, только играя с количеством старых и новых модулей, гораздо удобнее реализовать ее с помощью Istio.

Таким образом, старое и новое приложения определяются как следующие развертывания:

01
02
03
04
05
06
07
08
09
10
11
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp-01
spec:
  template:
    metadata:
       labels:
         app: superapp
         version: "01"
...
01
02
03
04
05
06
07
08
09
10
11
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: superapp-02
spec:
  template:
    metadata:
       labels:
         app: superapp
         version: "02"
...

Служба направляет трафик на них обоих:

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Service
metadata:
  name: superapp
spec:
  selector:
    app: superapp
...

Кроме того, мы собираемся использовать следующие ресурсы Istio:
VirtualService и DestinationRule.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: superapp
spec:
  host: superapp
  subsets:
  - name: green
    labels:
      version: "01"
  - name: blue
    labels:
      version: "02"
---    
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: superapp
spec:
  hosts:
    - superapp  
  http:
  - match:
    - uri:
        prefix: /version
    route:
    - destination:
        port:
          number: 8080
        host: superapp
        subset: green
      weight: 90
    - destination:
        port:
          number: 8080
        host: superapp    
        subset: blue  
      weight: 10

VirtualService направит весь трафик, поступающий в службу superapp (хосты), к зеленым и синим модулям в соответствии с предоставленными весами (90/10).

A / B Тестирование

С помощью этой стратегии мы можем точно контролировать, какие пользователи, с каких устройств, отделов и т. Д. Перенаправляются в новую версию приложения.

Стратегии развертывания

Например, здесь мы собираемся проанализировать заголовок запроса, и если его пользовательский тег «конечный пользователь» равен «xammer», он будет перенаправлен в новую версию приложения. Остальные запросы будут перенаправлены на старый:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: superapp
spec:
  gateways:
    - superapp
  hosts:
    - superapp  
  http:
  - match:
    - headers:
        end-user:
          exact: xammer                
    route:
    - destination:
        port:
          number: 8080
        host: superapp
        subset: blue
  - route:
    - destination:
        port:
          number: 8080
        host: superapp
        subset: green

Все примеры и файлы манифеста для этого поста доступны на GitHub, так что вы можете самостоятельно поиграть с различными стратегиями и сложными правилами маршрутизации. Вам просто нужен кластер K8s (например, Minikube на вашем ноутбуке) с предустановленным Istio. Счастливого развертывания!

Это оно!

Опубликовано на Java Code Geeks с разрешения Евгения Федоренко, партнера нашей программы JCG . Смотреть оригинальную статью здесь: Стратегии развертывания с Kubernetes и Istio

Мнения, высказанные участниками Java Code Geeks, являются их собственными.