Contour 學習筆記(二):使用級聯功能實現藍綠部署和金絲雀發布


上篇文章介紹了 Contour 分布式架構的工作原理,順便簡單介紹了下 IngressRoute 的使用方式。本文將探討 IngressRoute 更高級的用法,其中級聯功能是重點。

1. IngressRoute 大入門

上篇文章在 examples/example-workload 目錄下創建了一個示例應用,我們來回顧一下它的 IngressRoute 配置:

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata: 
  labels:
    app: kuard
  name: kuard
  namespace: default
spec: 
  virtualhost:
    fqdn: kuard.local
  routes: 
    - match: /
      services: 
        - name: kuard
          port: 80
  • virtualhost : 該字段是 root IngressRoute,表示此域的頂級入口點。
  • fqdn : 該字段指定了完整的域名,可以通過在 HTTP 請求頭中指定 Host: 字段來訪問該服務。

這是最簡單是使用方法,看起來沒什么特別的,我們來稍作修改一下:

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata: 
  labels:
    app: kuard
  name: kuard
  namespace: default
spec: 
  virtualhost:
    fqdn: kuard.local
  routes: 
    - match: /test
      services: 
        - name: kuard
          port: 80

match: / 改為 match: /test,然后重新應用新規則。這時如果你訪問 url kuard.local/test 是不通的,因為 kuard 服務本身並沒有 /test 這個路徑,我們可以強制將路徑重寫為 /

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata: 
  labels:
    app: kuard
  name: kuard
  namespace: default
spec: 
  virtualhost:
    fqdn: kuard.local
  routes: 
    - match: /test
      prefixRewrite: "/"
      services: 
        - name: kuard
          port: 80

重新 apply 之后,再次訪問 url kuard.local/test 就通了。

這里可以和標准的 ingress 對象對比一下,IngressRoute 的優勢在於它可以分別對每個路由設置 rewrite 規則,而 Nginx Ingress Controller 只能設置全局的 rewrite 規則,因為它用的是 annotations。雖然可以通過其他手段來實現,但相對來說會比較麻煩。

2. 級聯功能介紹

下面我們來看看 IngressRoute 的級聯功能,這是個非常有特色的功能,你可以通過級聯多個路由規則,上層 IngressRoute 的配置被下層繼承。例如,我們可以將 url 路徑 / 的路由規則級聯到其他的 IngressRoute 中,其他的 IngressRoute 可以來自不同的 namespace。

舉個例子,我們可以先創建一個這樣的 IngressRoute:

$ cat > delegate-from-main.yaml <<EOF
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: delegate-from-main
spec:
  routes:
    - match: /
      services:
        - name: kuard
          port: 80
EOF
$ kubectl apply -f delegate-from-main.yaml

$ kubectl get ingressroute delegate-from-main -o jsonpath='{.status.currentStatus}'
orphaned

該 IngressRoute 的狀態為 orphaned,因為它沒有包含一個合法的 fqdn。接下來需要創建一個 root IngressRoute 來和它進行級聯:

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata: 
  labels:
    app: kuard
  name: kuard
  namespace: default
spec: 
  virtualhost:
    fqdn: kuard.local
  routes: 
    - match: /
      delegate:
        name: delegate-from-main
        namespace: default

這時如果再檢查 IngressRoute delegate-from-main 的狀態,就會發現它從 orphaned 狀態變成了 valid 狀態,kuard.local 也能夠順利訪問。

了解了級聯功能的用法之后,下面就來看看它的應用場景。

  • 場景一:可以使用級聯功能來做藍綠部署和灰度發布,只需要在上層 IngressRoute 中稍作修改,切換到另一個下層 IngressRoute,就可以切換流量的處理規則。
  • 場景二:管理員可以利用級聯功能將部分 ingress 的權限放行到其他的 namespace 中,在這些 namespace 中,用戶可以自由更新與 root IngressRoute 級聯的相關的 IngressRoute。例如,如果管理員想防止其他用戶配置非法的域名或路徑,可以將該部分的配置權限放到 root IngressRoute 中,其他 namespace 中的下層 IngressRoute 中只能配置各自的路徑相關信息。

接下來主要探討場景一。

3. 藍綠部署

藍綠部署簡單來講就是在生產環境中有兩套系統:一套是正在提供服務的系統,標記為“綠色”;另一套是准備發布的系統,標記為“藍色”。兩套系統都是功能完善的,並且正在運行的系統,只是系統版本和對外服務情況不同。

最初,沒有任何系統,沒有藍綠之分。

然后,第一套系統開發完成,直接上線,這個過程只有一個系統,也沒有藍綠之分。

后來,開發了新版本,要用新版本替換線上的舊版本,在線上的系統之外,搭建了一個使用新版本代碼的全新系統。 這時候,一共有兩套系統在運行,正在對外提供服務的老系統是綠色系統,新部署的系統是藍色系統。

藍色系統不對外提供服務,用來做啥?

用來做發布前測試,測試過程中發現任何問題,可以直接在藍色系統上修改,不干擾用戶正在使用的系統。(注意,兩套系統沒有耦合的時候才能百分百保證不干擾)

藍色系統經過反復的測試、修改、驗證,確定達到上線標准之后,直接將用戶切換到藍色系統:

切換后的一段時間內,依舊是藍綠兩套系統並存,但是用戶訪問的已經是藍色系統。這段時間內觀察藍色系統(新系統)工作狀態,如果出現問題,直接切換回綠色系統。

當確信對外提供服務的藍色系統工作正常,不對外提供服務的綠色系統已經不再需要的時候,藍色系統正式成為對外提供服務系統,成為新的綠色系統。 原先的綠色系統可以銷毀,將資源釋放出來,用於部署下一個藍色系統。

通過 IngressRoute 的級聯功能可以很方便地實現藍綠部署策略,首先創建一個上層的 root IngressRoute(假設名為 root-blog),然后將域名 yangcs.net/blogs 的路由策略級聯到下層的 IngressRoute(名為 blog)。我們會同時部署”藍色“版本和”綠色“版本的應用,此時只有”綠色“版本接收流量。

---
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: root-blog
  namespace: root-ingressroute
spec:
  virtualhost:
    fqdn: yangcs.net
    tls:
      secretName: yangcs-net
  routes:
    - match: /blog
      delegate:
        name: blog
        namespace: marketing
---
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: blog
  namespace: marketing
spec:
  routes:
    - match: /blog
      services:
        - name: green
          port: 80

---
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: blog2
  namespace: marketing
spec:
  routes:
    - match: /blog
      services:
        - name: blue
          port: 80

在對藍色版本進行測試驗證之后,就可以將用戶切換到藍色應用了:

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: root-blog
  namespace: root-ingressroute
spec:
  virtualhost:
    fqdn: yangcs.net
    tls:
      secretName: yangcs-net
  routes:
    - match: /blog
      delegate:
        name: blog2
        namespace: marketing

4. 金絲雀發布

金絲雀發布(Canary)也是一種發布策略,和國內常說的灰度發布是同一類策略。它和藍綠有點像,但是它更加規避風險。你可以階段性的進行,而不用一次性從藍色版本切換到綠色版本。

采用金絲雀部署,你可以在生產環境的基礎設施中小范圍的部署新的應用代碼。一旦應用簽署發布,只有少數用戶被路由到它,可以最大限度的降低影響。

如果沒有錯誤發生,把剩余的 V1 版本全部升級為 V2 版本。如果有錯誤發生,則直接回退到老版本,發布失敗。下圖示范了金絲雀部署:

其實金絲雀發布的名稱來源於一個典故。在 17 世紀,英國礦井工人發現,金絲雀對瓦斯這種氣體特別敏感,空氣中哪怕有極其微量的瓦斯,金絲雀也會停止唱歌。當瓦斯含量超過一定限度時,人類毫無察覺,但金絲雀卻會毒發身亡。當時在采礦設備相對簡陋的條件下,工人們每次下井都會帶上一只金絲雀作為”瓦斯檢測指標“,以便在危險情況下緊急撤離。映射到這里就是先發布一小部分來試探整體是否能夠正常運行,如果能正常運行則進行完全部署的發布方式,目前仍然是不少成長型技術組織的主流發布方式。

IngressRoute 可以通過分配權重來實現金絲雀發布,和藍綠部署一樣,首先創建一個上層的 root IngressRoute(名為 root-blog),然后將域名 yangcs.net/blogs 的路由策略級聯到下層的 IngressRoute(名為 blog)。在下層的 IngressRoute 中將流量按不同權重轉發到不同的后端服務。

apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: blog
  namespace: marketing
spec:
  routes:
    - match: /blog
      services:
        - name: green
          port: 5
        - name: blue
          port: 95

如果沒有錯誤發生,就將 green 的權重調整為 100,blue 的權重調整為 0。至此就完成了金絲雀發布。

本文主要介紹了 IngressRoute 級聯功能的用法,探討了如何使用級聯功能來實現藍綠部署和金絲雀發布,后面的文章將會陸續探討其他的流量治理功能。

5. 參考資料

微信公眾號

掃一掃下面的二維碼關注微信公眾號,在公眾號中回復◉加群◉即可加入我們的雲原生交流群,和孫宏亮、張館長、陽明等大佬一起探討雲原生技術


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM