6 Eylül 2022 Salı

Yazılım Mimarisi Deployment - Canlıya Geçirme Blue/Green Deployment - İki Sistem Yanyanadır, Yük Yenisine Aktarılır

Giriş
Hem microservice hem de monolith ile kullanılabilir. Açıklaması şöyle. Mevcut sisteme blue denilir. Yeni sisteme de green. 
Blue Green deployments (2010) predates cloud computing (2013), microservice architectures (2014) and cloud native software patterns (2019)
Her iki sistem de yan yana kuruludur. Açıklaması şöyle
In a blue-green technique, both blue and green versions get deployed simultaneously, but only one version will be active and live at a time. Let’s consider blue as the old version and green as the new version. So, all the traffic is sent to blue by default at first, and if the latest version (green) meets all the requirements, then the old version traffic is diverted to the new version (from blue to green). 
Blue/Green deployment'ı active/passive olarak anlayanlar da var. Açıklaması şöyle. Ama bence bu doğru terminoloji değil.
Blue/Green deployment refers to a software technique which can be used to reduce system downtime by deploying two mirrored production environments, referred to as blue (active) and green (idle). One of the environments is running in production while the other is in active standby.

The Jet client can be configured to switch to the other cluster in case when a connection to the production environment fails.
Downtime Gerektirmeyen Yöntem
Yeni sistem kurulur ve açılır. Her şey tam olarak çalıştıktan sonra load-balancer ayarları değiştirilerek akış yeni sisteme yönlendirilir. Eğer sorun yoksa mavi sistem kaldırılır. 

Downtime Gerektiren Yöntem - Recreate
Bu yöntemde bir miktar downtime olabilir, çünkü mavi sistemi tam olarak tüm işlemlerin bittiği noktada kapatmak mümkün değil dolayısıyla önce sistem ara bir state'e geçiriliyor. Açıklaması şöyle
It’s not always possible to have your “green” stack 100% ready to serve customers at the point at which you disconnect “blue”. What if blue is writing state to the database that green will need in order to process subsequent requests? For applications where some downtime is required between the start and end of the cutover, we introduce a third state; some sort of “we’re down for maintenance” stub that can respond to customers gracefully whilst we make the final updates necessary to green. Then, once green is ready, we flip the load balancer back over to the green stack and away we go again.
Downtime Gerektirmeyen Yöntem
Kubernetes ortamında sadece servis'i yeni pod'a yönlendirerek yapılıyor.

Argo Rollouts
İlk defa burada gördüm.  Blue/Green veya Canary Deployment işini kolaylaştıran bir Custom Resource Definition (CRD)

Örnek - Bu Örnek Çok İyi Değil
blue.yaml şöyle olsun. Burada deployment version 1.0 kullanıyor. Service için önemli olan şey selector alanı. "version : 1.0" olmalı
aapiVersion: apps/v1
kind: Deployment metadata: name: app spec: selector: matchLabels: app: app version: "1.0" replicas: 2 template: metadata: labels: app: app version: "1.0" spec: containers: - name: service image: pkw0301/app:1.0 imagePullPolicy: Always ports: - containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: app spec: type: LoadBalancer ports: - name: http protocol: TCP port: 5000 targetPort: 5000 selector: app: app version: "1.0"
green.yaml şöyle olsun. Deployment ismi aynı. Burada image ismi değişiyor. Ayrıca LoadBalancer service version 2.0 olan pod'lara yönlendiriliyor
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  selector:
    matchLabels:
      app: app
      version: "2.0"
  replicas: 2
  template:
    metadata:
      labels:
        app: app
        version: "2.0"
    spec:
      containers:
      - name: service
        image: pkw0301/app:2.0
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: LoadBalancer
  ports:
  - name: http
    protocol: TCP
    port: 5000
    targetPort: 5000
  selector:
    app:  app
Örnek - Bu Daha İyi Bir Örnek
Elimizde version v1.0.0 deployment olsun
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v1
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v1.0.0
  template:
    metadata:
      labels:
        app: my-app
        version: v1.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9101"
    spec:
      containers:
      - name: my-app
        image: containersol/k8s-deployment-strategies
        ports:
        - name: http
          containerPort: 8080
        - name: probe
          containerPort: 8086
        env:
        - name: VERSION
          value: v1.0.0
        livenessProbe:
          httpGet:
            path: /live
            port: probe
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: probe
          periodSeconds: 5
Service şöyle olsun
apiVersion: v1
kind: Service
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: http
  # Note here that we match both the app and the version
  selector:
    app: my-app
    version: v1.0.0
Yeni deployment için şöyle yaparız. Deployment ismi değiştiriliyor
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v2
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v2.0.0
  template:
    metadata:
      labels:
        app: my-app
        version: v2.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9101"
    spec:
      containers:
      - name: my-app
        image: containersol/k8s-deployment-strategies
        ports:
        - name: http
          containerPort: 8080
        - name: probe
          containerPort: 8086
        env:
        - name: VERSION
          value: v2.0.0
        livenessProbe:
          httpGet:
            path: /live
            port: probe
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: probe
          periodSeconds: 5
Yeni service için şöyle yaparız
kubectl patch service my-app -p '{"spec":{"selector":{"version":"v2.0.0"}}}'
Eski deployment'ı silmek için şöyle yaparız
kubectl delete deploy my-app-v1






Hiç yorum yok:

Yorum Gönder