成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Istio 結合 Flagger 進行灰度發布

云計算 云原生
Flagger 是一個漸進式交付的 Kubernetes Operator,它可以自動執行 Kubernetes 上運行的應用程序的發布過程。它通過在測量指標和運行一致性測試的同時逐漸將流量轉移到新版本,降低了在生產中引入新軟件版本的風險。

灰度發布也叫金絲雀部署 ,是指通過控制流量的比例,實現新老版本的逐步替換。比如對于服務 A 有兩個版本(藍和綠兩個版本),當前兩個版本同時部署,但是 version1 比例 90% ,version2 比例 10% ,然后我們可以觀察 version2 的實際運行效果,如果符合預期,則可以逐步調整流量占比,比如調整為 80:20 -> 70:30 -> 10:90 -> 0:100 ,最終 version1 版本下線,全部替換成 version2 版本。如果驗證失敗,切換 100%流量回 v1 版本(回滾)。灰度發布的特點是:

flagger

在 Istio 中要實現灰度發布有多種方案,比如 Flagger、Argo Rollouts 等。

Flagger

Flagger 是一個漸進式交付的 Kubernetes Operator,它可以自動執行 Kubernetes 上運行的應用程序的發布過程。它通過在測量指標和運行一致性測試的同時逐漸將流量轉移到新版本,降低了在生產中引入新軟件版本的風險。

Flagger 通過使用服務網格(App Mesh、Istio、Linkerd、Kuma、Open Service Mesh)或 Ingress 控制器(Contour、Gloo、NGINX、Skipper、 Traefik、APISIX)用于流量路由。對于發布分析,Flagger 可以查詢 Prometheus、InfluxDB、Datadog、New Relic、CloudWatch、Stackdriver 或 Graphite,并使用 Slack、MS Teams、Discord 和 Rocket 來發出警報。

Flagger

Flagger 可以使用 Kubernetes CRD 進行配置,并且與任何為 Kubernetes 制作的 CI/CD 解決方案兼容。由于 Flagger 是聲明性的對 Kubernetes 事件做出反應,因此它可以與諸如此類的工具一起在 GitOps 管道中使用。

安裝 Flagger

要使用 Flagger,需要先選擇一個受支持的路由提供商(比如我們這里使用 Istio),然后使用 Helm 或 Kustomize 安裝 Flagger。

Flagger 需要 Kubernetes 集群 v1.16 或更高版本以及 Istio v1.5 或更高版本。

首先當然需要安裝 Istio,并開啟 Prometheus 插件:

# demo 或者 default 都可以
istioctl manifest install --set profile=demo -y

# istio 根目錄
kubectl apply -f samples/addons/prometheus.yaml

然后在 istio-system 命名空間安裝 Flagger:

$ git clone https://github.com/fluxcd/flagger && cd flagger
$ kubectl apply -k kustomize/istio
$ kubectl get pods -n istio-system -l app=flagger
NAME                      READY   STATUS    RESTARTS   AGE
flagger-ff76bfdff-kkcmz   1/1     Running   0          17m

測試應用

下面我們創建一個名為 test 的命名空間,并為其啟用 Istio sidecar 自動注入:

kubectl create ns test
kubectl label namespace test istio-injectinotallow=enabled

接下來我們使用 flagger 官方提供的 podinfo 應用來進行測試:

kubectl apply -k kustomize/podinfo

該命令會為 podinfo 應用創建對應的 Deployment 和一個 HPA 對象。

$ kubectl get deployment -n test
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
podinfo   2/2     2            0           96s
$ kubectl get hpa -n test
NAME      REFERENCE            TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
podinfo   Deployment/podinfo   <unknown>/99%   2         4         2          60s

部署后,我們可以看到 podinfo 應用的容器數量已經變成了 2 個(自動注入了 istio sidecar),而且 HPA 也已經生效。

```bash
$ kubectl get pods -n test
NAME                                  READY   STATUS            RESTARTS   AGE
podinfo-584c4546df-fzw4d              0/2     PodInitializing   0          5m26s
podinfo-584c4546df-n28cf              0/2     PodInitializing   0          5m11s

接著我們再部署一個負載測試服務用于在金絲雀分析期間生成流量:

kubectl apply -k kustomize/tester

創建金絲雀

接下來我們就可以創建一個 Canary 自定義資源來實現我們的金絲雀發布了。Canary 對象是 Flagger 的核心,它描述了金絲雀發布的目標。如下所示,我們為 podinfo 應用創建一個 Canary 對象:

# podinfo-canary.yaml
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef: # deployment 引用
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60 # 金絲雀部署升級最大處理時間(以秒為單位)(默認600秒)
  autoscalerRef: # HPA 引用(可選)
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    port: 9898
    targetPort: 9898
    gateways: # Istio 網關(可選)
      - istio-system/public-gateway
    hosts: # VirtualService 主機名 (optional)
      - podinfo.k8s.local
    trafficPolicy: # Istio 流量策略(可選)
      tls:
        # use ISTIO_MUTUAL when mTLS is enabled
        mode: DISABLE
    retries: # Istio 重試策略(可選)
      attempts: 3
      perTryTimeout: 1s
      retryOn: "gateway-error,connect-failure,refused-stream"
  analysis: # 金絲雀分析
    interval: 1m # 金絲雀分析間隔時間(默認 60s)
    threshold: 5 # 金絲雀分析失敗閾值(默認 5)
    maxWeight: 50 # 金絲雀最大流量權重(默認 50)
    stepWeight: 10 # 金絲雀流量權重步長(默認 10)
    metrics:
      - name: request-success-rate
        # minimum req success rate (non 5xx responses)
        # percentage (0-100)
        thresholdRange:
          min: 99
        interval: 1m
      - name: request-duration
        # maximum req duration P99
        # milliseconds
        thresholdRange:
          max: 500
        interval: 30s
    # testing (optional)
    webhooks:
      - name: acceptance-test
        type: pre-rollout
        url: http://flagger-loadtester.test/
        timeout: 30s
        metadata:
          type: bash
          cmd: "curl -sd 'test' http://podinfo-canary:9898/token | grep token"
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          # 使用 hey 工具對 podinfo-canary 進行為期1分鐘的負載測試,每秒發送10個請求,且測試過程中會維持2個并發連接。
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"

上面的配置文件中,我們定義了 podinfo 應用的金絲雀發布策略,其中 targetRef 指定了要進行金絲雀發布的 Deployment 對象,service 指定了金絲雀發布的服務,analysis 指定了金絲雀分析策略,這里我們指定了兩個內置的指標檢查:request-success-rate 和 request-duration,其中 request-success-rate 指定了 HTTP 請求成功率,request-duration 指定了請求持續時間。對于每個指標,你可以使用 thresholdRange 和窗口大小或時間序列指定可接受的值范圍和時間間隔。內置檢查適用于每個服務網格/Ingress 控制器,并通過 Prometheus 查詢實現。

在 service 中我們指定了 Istio 的 Gateway(istio-system/public-gateway)以及 VirtualService 要使用的主機名,首先我們可以為該應用創建一個 Gateway 對象:

# public-gateway.yaml
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:
        - "*"

另外我們在上面的對象中通過 webhooks 字段指定了金絲雀分析期間要執行的測試,其中 acceptance-test 用于在金絲雀分析開始之前執行,load-test 用于在金絲雀分析期間執行。

金絲雀部署

接下來我們可以直接創建 Canary 對象了:

kubectl apply -f podinfo-canary.yaml

當創建了 Canary 對象后,Flagger 會自動創建一個名為 pod-info-primary 的 Deployment 以及兩個版本的 Service 對象:

$ kubectl get deploy -n test
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
flagger-loadtester   1/1     1            1           42m
podinfo              0/0     0            0           46m
podinfo-primary      2/2     2            2           7m3s
$ kubectl get svc -ntest
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
flagger-loadtester   ClusterIP   10.106.172.190   <none>        80/TCP     35m
podinfo-canary       ClusterIP   10.101.184.213   <none>        9898/TCP   39s
podinfo-primary      ClusterIP   10.110.105.36    <none>        9898/TCP   39s

可以看到我們原本的 podinfo 應用已經從 podinfo 這個 Deployment 遷移到了 podinfo-primary 這個 Deployment 之上。

此外還有 Istio 相關的對象:

$ kubectl get vs -ntest
NAME      GATEWAYS                          HOSTS                             AGE
podinfo   ["istio-system/public-gateway"]   ["podinfo.k8s.local","podinfo"]   91s
$ kubectl get dr -ntest
NAME              HOST              AGE
podinfo-canary    podinfo-canary    95s
podinfo-primary   podinfo-primary   95s

我們可以查看下自動生成的 VirtualService 對象:

$ kubectl get vs -ntest podinfo -oyaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: podinfo
  namespace: test
spec:
  gateways:
  - istio-system/public-gateway
  hosts:
  - podinfo.k8s.local
  - podinfo
  http:
  - retries:
      attempts: 3
      perTryTimeout: 1s
      retryOn: gateway-error,connect-failure,refused-stream
    route:
    - destination:
        host: podinfo-primary
      weight: 100
    - destination:
        host: podinfo-canary
      weight: 0

從上面的配置中我們可以看到當前 podinfo 應用的流量全部被路由到了 podinfo-primary 對象上,而 podinfo-canary 對象的流量權重為 0,當然同樣可以查看 DestinationRule 對象:

$ kubectl get dr podinfo-primary -ntest -oyaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: podinfo-primary
  namespace: test
spec:
  host: podinfo-primary
  trafficPolicy:
    tls:
      mode: DISABLE
$ kubectl get dr podinfo-canary -ntest -oyaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: podinfo-canary
  namespace: test
spec:
  host: podinfo-canary
  trafficPolicy:
    tls:
      mode: DISABLE

所以默認情況下現在我們訪問到的就是 podinfo-primary 這個 Deployment 對象,也就是目前的默認版本。我們可以在瀏覽器中訪問 podinfo 來查看當前的版本:

podinfo

自動金絲雀發布

我們可以看到現在的版本是 podinfo v6.0.0,接下來我們來升級應用觸發金絲雀發布。要觸發金絲雀發布,可以由以下任何對象的更改來觸發:

  • Deployment PodSpec(容器鏡像、命令、端口、環境變量、資源等)
  • 作為卷掛載或映射到環境變量的 ConfigMaps
  • 作為卷掛載或映射到環境變量的 Secrets

比如我們可以直接修改 Deployment 對象的鏡像版本來觸發自動化的金絲雀發布:

kubectl -n test set image deployment/podinfo podinfod=ghcr.io/stefanprodan/podinfo:6.0.1

Flagger 檢測到 Deployment 更改后就會開始新的部署:

$ kubectl describe canaries podinfo -ntest
# ......
Events:
  Type     Reason  Age                From     Message
  ----     ------  ----               ----     -------
  Warning  Synced  15m                flagger  podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less than desired generation
  Normal   Synced  14m (x2 over 15m)  flagger  all the metrics providers are available!
  Normal   Synced  14m                flagger  Initialization done! podinfo.test
  Normal   Synced  56s                flagger  New revision detected! Scaling up podinfo.test

需要注意在金絲雀分析期間對 Deployment 應用新的更改,Flagger 將重新啟動分析。第一步是先會去擴容 podinfo 應用:

$ kubectl get pods -ntest
NAME                                  READY   STATUS    RESTARTS   AGE
flagger-loadtester-78dd9787d4-dq5fc   2/2     Running   0          67m
podinfo-5d5dbc4d84-f2mp6              2/2     Running   0          31s
podinfo-5d5dbc4d84-gd8ln              2/2     Running   0          31s
podinfo-primary-64f865cf4-bhr79       2/2     Running   0          3m31s
podinfo-primary-64f865cf4-tgsdj       2/2     Running   0          3m31s

然后就會根據我們在 Canary 對象中定義的金絲雀分析策略來進行分析,并一步步將金絲雀版本的權重提高。

Warning Synced 4m4s flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less than desired generation
Normal Synced 3m4s (x2 over 4m4s) flagger all the metrics providers are available!
Normal Synced 3m4s flagger Initialization done! podinfo.test
Normal Synced 64s flagger New revision detected! Scaling up podinfo.test
Normal Synced 4s flagger Starting canary analysis for podinfo.test
Normal Synced 4s flagger Pre-rollout check acceptance-test passed
Normal Synced 4s flagger Advance podinfo.test canary weight 10

最后會自動將流量全部切換到金絲雀版本上。

金絲雀版本

整個過程就是通過控制 VirtualService 的權重來實現的金絲雀發布。

自動回滾

在金絲雀分析期間,我們可以生成 HTTP 500 錯誤和高延遲來測試 Flagger 是否暫停發布。

比如我們觸發另一個金絲雀發布:

kubectl -n test set image deployment/podinfo podinfod=ghcr.io/stefanprodan/podinfo:6.0.2

然后進入 loadtester 容器:

kubectl -n test exec -it flagger-loadtester-xx-xx sh

使用下面的命令來生成 HTTP 500 錯誤:

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

也可以添加延遲:

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

當失敗檢查的次數達到金絲雀分析配置的閾值時,流量將路由回主節點,金絲雀將縮放為零,并將部署標記為失敗。

Normal   Synced  8m10s (x3 over 45m)  flagger  New revision detected! Scaling up podinfo.test
Normal   Synced  7m10s (x2 over 44m)  flagger  Pre-rollout check acceptance-test passed
Normal   Synced  7m10s (x2 over 44m)  flagger  Advance podinfo.test canary weight 10
Normal   Synced  7m10s (x2 over 44m)  flagger  Starting canary analysis for podinfo.test
Warning  Synced  6m10s                flagger  Halt podinfo.test advancement success rate 55.86% < 99%
Warning  Synced  5m10s                flagger  Halt podinfo.test advancement success rate 97.61% < 99%
Warning  Synced  4m10s                flagger  Halt podinfo.test advancement success rate 8.00% < 99%
Warning  Synced  3m10s                flagger  Halt podinfo.test advancement success rate 98.13% < 99%
Warning  Synced  2m10s                flagger  Halt podinfo.test advancement success rate 7.69% < 99%
Warning  Synced  70s (x2 over 14m)    flagger  Canary failed! Scaling down podinfo.test
Warning  Synced  70s                  flagger  Rolling back podinfo.test failed checks threshold reached 5

關于 Flagger 的更多使用請關注后續文章。

責任編輯:姜華 來源: k8s技術圈
相關推薦

2019-05-23 10:55:22

Istio灰度發布ServiceMesh

2022-12-05 10:47:08

RocketMQ灰度消息

2021-06-03 05:48:58

GitOps 云原生Kubernetes

2023-12-12 07:30:54

IstioWasm前端

2019-06-09 09:13:14

Istio負載均衡架構

2024-01-05 00:29:36

全鏈路灰度發布云原生

2022-01-19 18:31:54

前端灰度代碼

2021-12-27 15:01:21

KubernetesLinux命令

2021-11-18 10:01:00

Istio 全鏈路灰度微服務框架

2018-04-10 14:17:09

藍綠發布滾動發布灰度發布

2023-11-02 08:46:19

微服務開發Istio

2021-02-20 08:06:37

CTO灰度系統

2024-12-16 13:34:35

2022-04-28 09:22:46

Vue灰度發布代碼

2024-05-17 16:18:45

微服務灰度發布金絲雀發布

2023-02-20 10:13:00

灰度發布實現

2012-07-20 14:48:54

Nginx測試

2022-02-15 14:22:46

灰度發布互聯網業務

2025-04-03 08:00:00

灰度發布Java開發

2021-08-27 07:47:07

Nacos灰度源碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 狠狠操狠狠| av日韩高清 | 日韩免费中文字幕 | 国产婷婷精品 | 精品久久久久久亚洲精品 | 精品国产视频 | 日本电影一区二区 | 欧美精品一区二区在线观看 | 亚洲一区二区三区高清 | 69av网| 精品久久精品 | 欧美aaa| 婷婷丁香在线视频 | 中文字幕久久精品 | 国产精品视频一区二区三区不卡 | 人人射人人插 | 亚洲国产欧美91 | 精品精品视频 | 草草草草视频 | 精品久久久久久亚洲精品 | 秋霞在线一区 | av电影一区 | 91久久精品 | 日韩欧美在线不卡 | 欧美日韩一区二区三区四区 | 在线播放中文字幕 | 日韩精品一区二区三区四区 | 久久精品免费一区二区三 | 精品视频一区二区三区在线观看 | 久热国产在线 | 日皮视频免费 | 在线观看av网站永久 | 国产精品久久久久久久免费大片 | 黄色亚洲| 久久久久亚洲精品 | 一级毛片免费 | 天天操网 | 欧美精品久久久 | 久久91 | 精品视频一区二区三区在线观看 | 亚洲精品粉嫩美女一区 |