天天看點

使用 KubeSphere 實作微服務的灰階釋出

前言

今天來說一說,在 KubeSphere 中兩個 " 小姐姐 " 如何來回切換,這是什麼意思哩?其實就是網際網路産品中常用的灰階釋出方式。

網際網路産品需要快速疊代上線,既要保證新功能運作正常,又要保證品質,一旦出現問題可以很快控制局面,就需要設計一套灰階釋出系統。用大白話講就是某個 APP 的新版本已經開發完成了,而老版本使用者正在正常使用着,這個時候要是直接上線新版本,那麼所有的使用者都會用新版本,但是這種情況下,一旦出現問題,将導緻所有的使用者都不可用,是以會有政策的挑選一部分使用者先用新版本,即使出現問題,也隻是一小部分使用者,友善復原到舊版本,提升使用者良好的體驗性。

概述

灰階釋出(又名金絲雀釋出)是指在黑與白之間,能夠平滑過渡的一種釋出方式。在其上可以進行 A/B testing,即讓一部分使用者繼續用産品特性 A,一部分使用者開始用産品特性 B,如果使用者對 B 沒有什麼反對意見,那麼逐漸擴大範圍,把所有使用者都遷移到 B 上面來。灰階釋出可以保證整體系統的穩定,在初始灰階的時候就可以發現、調整問題,以保證其影響度。

我們假設這個 A/B,就是 A 小姐姐和 B 小姐姐。

KubeSphere 的微服務治理功能

KubeSphere 基于 Istio 微服務架構提供可視化的微服務治理功能,如果您在 Kubernetes 上運作和伸縮微服務,您可以為您的分布式系統配置基于 Istio 的微服務治理功能。KubeSphere 提供統一的操作界面,便于您內建并管理各類工具,包括 Istio、Envoy 和 Jaeger 等。

流量治理

  • 金絲雀釋出提供靈活的灰階政策,将流量按照所配置的比例轉發至目前不同的灰階版本
  • 藍綠部署支援零當機部署,讓應用程式可以在獨立的環境中測試新版本的功能和特性
  • 流量鏡像模拟生産環境,将實時流量的副本發送給被鏡像的服務
  • 熔斷機制支援為服務設定對單個主機的調用限制

在 KubeSphere 中應用治理可以以可插拔式方式開啟。開啟後如下:

使用 KubeSphere 實作微服務的灰階釋出

準備工作

建立一個 SpringBoot 的項目用于測試,如下 pom.xml 檔案:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.pkulaw</groupId>
  <artifactId>ServiceA</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>ServiceA</name>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <docker.image.prefix>springboot</docker.image.prefix>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- 引入Actuator監控依賴 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.0</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>ServiceA</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
      

controller 代碼:

@RestController
@Slf4j
public class CommonController {

    /**
     * 傳回A/B小姐姐圖檔
     * @param response
     * @throws IOException
     */
    @RequestMapping(method = RequestMethod.GET, produces = "image/jpeg")
    public void getImage2(HttpServletResponse response) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("images/B.jpg");
        InputStream  inputStream = classPathResource.getInputStream();
        //将InputStream 轉 File
        File file = asFile(inputStream);
        FileCopyUtils.copy(new FileInputStream(file), response.getOutputStream());
        response.setHeader("Content-Type", "application/octet-stream");
    }

    /**
     * InputStream To File
     * @param in
     * @return
     * @throws IOException
     */
    public static File asFile(InputStream in) throws IOException {
        File tempFile = File.createTempFile("test", ".tmp");
        tempFile.deleteOnExit();
        FileOutputStream out = new FileOutputStream(tempFile);
        IOUtils.copy(in, out);
        return tempFile;
    }
}      
注:直接通過接口傳回一張圖檔。

項目目錄結構如下:

使用 KubeSphere 實作微服務的灰階釋出

鏡像建構

在 KubeSphere 中有個超炫的功能叫鏡像建構器,鏡像建構器(Image Builder)是将代碼或者制品制作成容器鏡像的工具。您可以通過簡單的設定将制品或代碼直接制作成容器鏡像,無需 Dockerfile 檔案。

使用 KubeSphere 實作微服務的灰階釋出
上面圖檔來自 KubeSphere 鏡像建構官方介紹。

3.3.0 版本中就長下面這個樣子:

使用 KubeSphere 實作微服務的灰階釋出

harbor 中建立項目

使用 KubeSphere 實作微服務的灰階釋出

建立鏡像建構器

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
gitlab 倉庫秘鑰和 harbor 鏡像服務提前設定好。鏡像名稱為 service-a/service-a,鏡像标簽設定為 v1。

建立成功後,開始運作

使用 KubeSphere 實作微服務的灰階釋出
建構成功如上所示。

harbor 中檢視 v1 标簽的鏡像

使用 KubeSphere 實作微服務的灰階釋出
以上就是 v1 版本由來的整個過程,我們簡稱為 A 小姐姐。

接下來制作 B 小姐姐,建立一個代碼分支為 release, 調整代碼傳回為 B 小姐姐。

使用 KubeSphere 實作微服務的灰階釋出

建構 v2 版本的鏡像,也就是我們的 B 小姐姐。

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出

項目網關

KubeSphere 項目中的網關是一個 NGINX Ingress 控制器。KubeSphere 内置的用于 HTTP 負載均衡的機制稱為應用路由 (Ingress 路由規則),它定義了從外部到叢集服務的連接配接規則。如需允許從外部通路服務,使用者可建立路由資源來定義 URI 路徑、後端服務名稱等資訊。

KubeSphere 除了提供項目範圍的網關外,還提供叢集範圍的網關,使得所有項目都能共享全局網關。

在 KubeSphere 中開啟項目網關以從外部通路服務和路由。

使用 KubeSphere 實作微服務的灰階釋出

自制應用

在 KubeSphere 中實作金絲雀釋出,必須先開啟應用治理,且必須有一個可用的應用。

使用 KubeSphere 實作微服務的灰階釋出
KubeSphere 支援基于模闆的應用和自制應用。基于模闆的應用建立自 KubeSphere 應用商店或應用模闆,自制應用由使用者自定義。這裡我們以自制應用為例。

建立自制應用

使用 KubeSphere 實作微服務的灰階釋出

建立服務

使用 KubeSphere 實作微服務的灰階釋出

選擇無狀态服務

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
容器端口為 ServiceA 服務的端口 7777
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
在這裡添加路由規則後,KubeSphere 會自動幫我們建立 ingress 路由規則。

建立成功後如下:

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出

應用路由下會自動生成 ingress 路由規則,如下:

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出

配置本地 hosts, 如:192.168.0.156 ​​servicea.com​​

點選通路服務,立即傳回 A 小姐姐,如下:

使用 KubeSphere 實作微服務的灰階釋出

金絲雀釋出

建立金絲雀釋出任務

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
可以指定流量進行配置設定,也可以指定請求參數
使用 KubeSphere 實作微服務的灰階釋出

建立成功,檢視任務狀态

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出
預設 v1 和 v2 各占 50% 流量。

請求服務來檢視流量走向,v1 和 v2 各占 50% 流量

使用 KubeSphere 實作微服務的灰階釋出
使用 KubeSphere 實作微服務的灰階釋出

總結

繼續閱讀