Istio 太複雜?KubeSphere基於Ingress-Nginx實現灰度發佈

来源:https://www.cnblogs.com/kubesphere/archive/2019/08/27/11419213.html
-Advertisement-
Play Games

在 "Bookinfo 微服務的灰度發佈示例" 中,KubeSphere 基於 Istio 對 Bookinfo 微服務示例應用實現了灰度發佈。有用戶表示自己的項目還沒有上 Istio,要如何實現灰度發佈? 在 "Ingress Nginx (0.21.0 版本)" 中,引入了一個新的 Canary ...


Bookinfo 微服務的灰度發佈示例 中,KubeSphere 基於 Istio 對 Bookinfo 微服務示例應用實現了灰度發佈。有用戶表示自己的項目還沒有上 Istio,要如何實現灰度發佈?

Ingress-Nginx (0.21.0 版本) 中,引入了一個新的 Canary 功能,可用於為網關入口配置多個後端服務,還可以使用指定的 annotation 來控制多個後端服務之間的流量分配。 KubeSphere 在 2.0.2 的版本 中,升級了項目網關 (Ingress Controller) 版本至 0.24.1,支持基於 Ingress-Nginx 的灰度發佈。

上一篇文章已經對灰度發佈的幾個應用場景進行了詳細介紹,本文將直接介紹和演示基於 KubeSphere 使用應用路由 (Ingress) 和項目網關 (Ingress Controller) 實現灰度發佈。

說明: 本文用到的示例 yaml 源文件及代碼已上傳至 GitHub,可 clone 至本地方便參考。

Ingress-Nginx Annotation 簡介

KubeSphere 基於 Nginx Ingress Controller 實現了項目的網關,作為項目對外的流量入口和項目中各個服務的反向代理。而 Ingress-Nginx 支持配置 Ingress Annotations 來實現不同場景下的灰度發佈和測試,可以滿足金絲雀發佈、藍綠部署與 A/B 測試等業務場景。

Nginx Annotations 支持以下 4 種 Canary 規則:

  • nginx.ingress.kubernetes.io/canary-by-header:基於 Request Header 的流量切分,適用於灰度發佈以及 A/B 測試。當 Request Header 設置為 always 時,請求將會被一直發送到 Canary 版本;當 Request Header 設置為 never 時,請求不會被髮送到 Canary 入口;對於任何其他 Header 值,將忽略 Header,並通過優先順序將請求與其他金絲雀規則進行優先順序的比較。
  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用於通知 Ingress 將請求路由到 Canary Ingress 中指定的服務。當 Request Header 設置為此值時,它將被路由到 Canary 入口。該規則允許用戶自定義 Request Header 的值,必須與上一個 annotation (即:canary-by-header)一起使用。
  • nginx.ingress.kubernetes.io/canary-weight:基於服務權重的流量切分,適用於藍綠部署,權重範圍 0 - 100 按百分比將請求路由到 Canary Ingress 中指定的服務。權重為 0 意味著該金絲雀規則不會向 Canary 入口的服務發送任何請求。權重為 100 意味著所有請求都將被髮送到 Canary 入口。
  • nginx.ingress.kubernetes.io/canary-by-cookie:基於 Cookie 的流量切分,適用於灰度發佈與 A/B 測試。用於通知 Ingress 將請求路由到 Canary Ingress 中指定的服務的cookie。當 cookie 值設置為 always 時,它將被路由到 Canary 入口;當 cookie 值設置為 never 時,請求不會被髮送到 Canary 入口;對於任何其他值,將忽略 cookie 並將請求與其他金絲雀規則進行優先順序的比較。

註意:金絲雀規則按優先順序進行如下排序:

canary-by-header - > canary-by-cookie - > canary-weight

把以上的四個 annotation 規則可以總體劃分為以下兩類:

  • 基於權重的 Canary 規則

  • 基於用戶請求的 Canary 規則

第一步:創建項目和 Production 版本的應用

1.1. 在 KubeSphere 中創建一個企業空間 (workspace) 和項目 (namespace) ,可參考 多租戶管理快速入門。如下已創建了一個示例項目。

1.2. 為了快速創建應用,在項目中創建工作負載和服務時可通過 編輯 yaml 的方式,或使用 KubeSphere 右下角的工具箱打開 web kubectl 並使用以下命令和 yaml 文件創建一個 Production 版本的應用並暴露給集群外訪問。如下創建 Production 版本的 deploymentservice

$ kubectl appy -f production.yaml -n ingress-demo
deployment.extensions/production created
service/production created

其中用到的 yaml 文件如下:

production.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: production
spec:
  replicas: 1
  selector:
    matchLabels:
      app: production
  template:
    metadata:
      labels:
        app: production
    spec:
      containers:
      - name: production
        image: mirrorgooglecontainers/echoserver:1.10
        ports:
        - containerPort: 8080
        env:
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP

---

apiVersion: v1
kind: Service
metadata:
  name: production
  labels:
    app: production
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: production

1.3. 創建 Production 版本的應用路由 (Ingress)。

$ kubectl appy -f production.ingress -n ingress-demo
ingress.extensions/production created

其中用到的 yaml 文件如下:

production.ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: production
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: kubesphere.io
    http:
      paths:
      - backend:
          serviceName: production
          servicePort: 80

第二步:訪問 Production 版本的應用

2.1. 此時,在 KubeSphere UI 的企業空間 demo-workspace 下,可以看到 ingress-demo 項目下的所有資源。

Deployment

Service

Ingress

2.2. 訪問 Production 版本的應用需確保當前項目已開啟了網關,在外網訪問下打開網關,類型為 NodePort

2.3. 如下訪問 Production 版本的應用。

$ curl kubesphere.io:30205

Hostname: production-6b4bb8d58d-7r889

Pod Information:
    node name:  ks-allinone
    pod name:   production-6b4bb8d58d-7r889
    pod namespace:  ingress-demo
    pod IP: 10.233.87.165

Server values:
    server_version=nginx: 1.12.2 - lua: 10010

Request Information:
    client_address=10.233.87.225
    method=GET
    real path=/
    query=
    request_version=1.1
    request_scheme=http
    request_uri=http://kubesphere.io:8080/

Request Headers:
    accept=*/*
    host=kubesphere.io:30205
    user-agent=curl/7.29.0
apiVersion: extensions/v1beta1
    x-forwarded-for=192.168.0.88
    x-forwarded-host=kubesphere.io:30205
    x-forwarded-port=80
    x-forwarded-proto=http
    x-original-uri=/
    x-real-ip=192.168.0.88
    x-request-id=9596df96e994ea05bece2ebbe689a2cc
    x-scheme=http

Request Body:
    -no body in request-

第三步:創建 Canary 版本

參考將上述 Production 版本的 production.yaml 文件,再創建一個 Canary 版本的應用,包括一個 Canary 版本的 deploymentservice (為方便快速演示,僅需將 production.yaml 的 deployment 和 service 中的關鍵字 production 直接替換為 canary,實際場景中可能涉及業務代碼變更)。

第四步:Ingress-Nginx Annotation 規則

基於權重 (Weight)

基於權重的流量切分的典型應用場景就是藍綠部署,可通過將權重設置為 0 或 100 來實現。例如,可將 Green 版本設置為主要部分,並將 Blue 版本的入口配置為 Canary。最初,將權重設置為 0,因此不會將流量代理到 Blue 版本。一旦新版本測試和驗證都成功後,即可將 Blue 版本的權重設置為 100,即所有流量從 Green 版本轉向 Blue。

4.1. 使用以下 canary.ingress 的 yaml 文件再創建一個基於權重的 Canary 版本的應用路由 (Ingress)。

註意:要開啟灰度發佈機制,首先需設置 nginx.ingress.kubernetes.io/canary: "true" 啟用 Canary,以下 Ingress 示例的 Canary 版本使用了基於權重進行流量切分的 annotation 規則,將分配 30% 的流量請求發送至 Canary 版本。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
  rules:
  - host: kubesphere.io
    http:
      paths:
      - backend:
          serviceName: canary
          servicePort: 80

4.2. 訪問應用的功能變數名稱。

說明:應用的 Canary 版本基於權重 (30%) 進行流量切分後,訪問到 Canary 版本的概率接近 30%,流量比例可能會有小範圍的浮動。

基於 Request Header

4.3. 基於 Request Header 進行流量切分的典型應用場景即灰度發佈或 A/B 測試場景。參考以下截圖,在 KubeSphere 給 Canary 版本的 Ingress 新增一條 annotation nginx.ingress.kubernetes.io/canary-by-header: canary (這裡的 annotation 的 value 可以是任意值),使當前的 Ingress 實現基於 Request Header 進行流量切分。

說明:金絲雀規則按優先順序 canary-by-header - > canary-by-cookie - > canary-weight 進行如下排序,因此以下情況將忽略原有 canary-weight 的規則。

4.4. 在請求中加入不同的 Header 值,再次訪問應用的功能變數名稱。

說明:

舉兩個例子,如開篇提到的當 Request Header 設置為 neveralways 時,請求將不會一直被髮送到 Canary 版本;

對於任何其他 Header 值,將忽略 Header,並通過優先順序將請求與其他 Canary 規則進行優先順序的比較(如下第二次請求已將基於 30% 權重作為第一優先順序)。

4.5. 此時可以在上一個 annotation (即 canary-by-header)的基礎上添加一條 nginx.ingress.kubernetes.io/canary-by-header-value: user-value 。用於通知 Ingress 將請求路由到 Canary Ingress 中指定的服務。

4.6. 如下訪問應用的功能變數名稱,當 Request Header 滿足此值時,所有請求被路由到 Canary 版本(該規則允許用戶自定義 Request Header 的值)。

4.7. 與基於 Request Header 的 annotation 用法規則類似。例如在 A/B 測試場景 下,需要讓地域為北京的用戶訪問 Canary 版本。那麼當 cookie 的 annotation 設置為 nginx.ingress.kubernetes.io/canary-by-cookie: "users_from_Beijing",此時後臺可對登錄的用戶請求進行檢查,如果該用戶訪問源來自北京則設置 cookie users_from_Beijing 的值為 always,這樣就可以確保北京的用戶僅訪問 Canary 版本。

總結

灰度發佈可以保證整體系統的穩定,在初始灰度的時候就可以對新版本進行測試、發現和調整問題,以保證其影響度。本文通過多個示例演示和說明瞭基於 KubeSphere 使用應用路由 (Ingress) 和項目網關 (Ingress Controller) 實現灰度發佈,並詳細介紹了 Ingress-Nginx 的四種 Annotation,還未使用 Istio 的用戶也能藉助 Ingress-Nginx 輕鬆實現灰度發佈與金絲雀發佈。

參考

  • NGINX Ingress Controller - Annotations
  • canary deployment with ingress-nginx
  • Canary Deployments on Kubernetes without Service Mesh
    KubeSphere (https://github.com/kubesphere/kubesphere) 是一個開源的以應用為中心的容器管理平臺,支持部署在任何基礎設施之上,並提供簡單易用的 UI,極大減輕日常開發、測試、運維的複雜度,旨在解決 Kubernetes 本身存在的存儲、網路、安全和易用性等痛點,幫助企業輕鬆應對敏捷開發與自動化監控運維、端到端應用交付、微服務治理、多租戶管理、多集群管理、服務與網路管理、鏡像倉庫、AI 平臺、邊緣計算等業務場景。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實際的生產環境中,總會做一些定期的任務,比如數據備份,我們不可能總等到那個時間去手動執行,這時計劃任務就派上用場了。 ...
  • Windows 有任務管理器來管理進程,Linux 也有相應的命令來管理進程。 ...
  • Linux伺服器線上打包遇到的問題 轉載請標明出處: "https://dujinyang.blog.csdn.net/article/details/80110942" 本文出自:【奧特曼超人的博客】 線上打包的流程 遇到奇怪的BUG(Linux apktool 包體變大) 1. 線上打包的流程 ...
  • 如何控制服務的運行狀態?如何切換不同的運行級別? 服務控制 ntsysv 仿圖形交互界面,集中配置各種服務啟動狀態 :同時對指定運行級別中的服務進行管理,不加僅管理當前運行級別中的服務。 systemctl systemctl {選項} name.servive :啟動 :停止 :重啟,先停止,再啟 ...
  • 一、awk介紹 全稱:由Aho Weinberger Kernaighan三個人的首字母組合而成 1970年第一次出現在Unix機器上,後來在開源領域使用它 awk是一種單獨的編程語言解釋器 awk報告生成器:通過模式匹配以及自己本身的語言格式,來獲取並輸出客戶所需要的內容 示例:獲取系統上面用戶i ...
  • 參考資料: An introduction to the Linux boot and startup processes 這篇隨筆,可以理解為是對這篇英文文章的翻譯與個人理解、筆記的整合。 擴展閱讀: GNU GRUB - Wikipedia systemd - Wikipedia BIOS in ...
  • date指令-顯示當前日期 基本語法: 1)date (功能描述:顯示當前時間) 2)date +%Y (功能描述:顯示當前年份) 3)date +%m (功能描述:顯示當前月份) 4)date +%d (功能描述:顯示當前是哪一天) 5)date “+%Y-%m-%d %H:%M:%S” (功能描 ...
  • 安裝vncserver[root@elegant-snap-3 ~]# yum install tigervnc-server -yLoaded plugins: fastestmirrorDetermining fastest mirrors * base: mirror.fileplanet.c... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...