1. 程式人生 > >Linkerd + Namerd,實現Kubernetes 叢集的灰度釋出_Kubernetes中文社群

Linkerd + Namerd,實現Kubernetes 叢集的灰度釋出_Kubernetes中文社群

主要內容源於 https://blog.buoyant.io/2016/11/04/a-service-mesh-for-kubernetes-part-iv-continuous-deployment-via-traffic-shifting/ ,砍掉了 Jenkins 等附加部分,更換了更加易於理解的示例應用,以保證主幹突出。

Kubernetes 所提供的 rolling-update 功能提供了一種漸進式的更新過程,然而其滾動過程並不容易控制,對於灰度釋出的需要來說,仍稍顯不足,這裡介紹一種利用 Linkerd 方案進行流量切換的思路。

官網介紹:linker∙d is a transparent proxy that adds service discovery, routing, failure handling, and visibility to modern software applications。

本文從實際操作入手,上線兩個版本的簡單應用,利用這一組合完成流量的切換和測試過程。

測試目標

  • 同時上線兩個版本的應用。兩個應用均可工作,利用不同輸出進行區分。
  • 動態調整分配給兩個版本的流量。
  • 利用 CURL 進行流量分配的測試。

準備工作

這裡利用一個 1.2 以上版本的 Kubernetes 叢集進行演示:

  • API Server / Registry:10.211.55.62
  • Node:10.211.66.63

另外因某些原因,需要有能力獲取 Dockerhub 的映象。

例子程式很簡單,用一個 PHP 檔案顯示環境變數中的內容:

<?php
    echo getenv("VAR_LABEL"
);

Docker file 繼承自 dustise/lamp:latest,檔案內容如下:

FROM dustise/lamp
COPY index.php /web/codebase

利用 Docker build 建立映象,這裡命名為 lamp:gray,備用。

建立工作負載

做一個簡單的 yaml 檔案來載入藍綠兩組應用,名字、環境變數和埠三個位置需要更改:

---
kind: ReplicationController
apiVersion: v1
metadata:
  name: green
# 此處省略若干
        env:
        - name: VAR_LABEL
          value
: 'green' --- kind: Service apiVersion: v1 # 此處省略若干 type: NodePort ports: - protocol: TCP nodePort: 32001 port: 80 targetPort: 80 name: http selector: name: green

利用 kubectl create -f green.yaml ( 以及 blue.yaml )之後,可以利用 curl 或者瀏覽器檢查執行情況,如果正常,兩個埠的訪問應該分別會返回 greenblue

另外這裡的埠命名很重要,這一名稱會被後面的規則引用到。

注意,這裡 NodePort 並非必須,僅為測試方便。

執行 Namerd

此處 yaml 主要來自於官網 https://raw.githubusercontent.com/BuoyantIO/linkerd-examples/master/k8s-daemonset/k8s/namerd.yml 為適應本地環境,將原有 Loadbalancer 型別的服務改為 NodePort

略微做一下講解。

整個 yaml 由四部分組成:

ThirdPartyResource

這部分被用於做 Namerd 的儲存後端。

Configmap

作為 Namerd 的配置,其中定義了這樣幾個內容(詳情可參見 https://linkerd.io/config/0.8.5/namerd/index.html#introduction):

  • 管理埠 9990
  • storage:儲存定義,通過 8001 埠同 Kube Api Server 通訊,完成在 ThrdPartyResource 中的訪問(8001 埠由 kubectl proxy 指令開通)
  • namer:定義服務發現能力由 Kubernetes 提供。
  • interface 部分則是定義了兩種支援協議。其中 HTTP Controller 可以接收 namerctl 的控制指令。

RC

這部分不新鮮,除了 namerd 之外,還利用 kubectl proxy 提供通訊埠給 namerd,頗有蛇足之嫌。正確的開啟方式應該是直接和 Kube API Server 進行通訊。

Service

這裡注意服務型別的變更( LoadBalancer -> NodePort ),需要暴露 4180 和 9990 兩個埠,分別作為控制埠和介面埠。

利用 kubectl 啟用之後,就可以在指定的埠檢視管理介面了。此時的管理介面沒有做任何配置,因此比較單薄。

新增規則

下面來安裝 namerd 的控制工具,namerctl

go get -u github.com/buoyantio/namerctl
go install github.com/buoyantio/namerctl

接下來建立一條規則:

/host=>/#/io.l5d.k8s/default/http;
/http/*/*/*=>8*/host/blue&2*/host/green;

這段程式碼表示該服務同時連線 blue 和 green 兩個後端服務,按照 80/20 的比例進行流量分配。

利用 namerctl dtab create [file name] --base-url 這裡 base-url 取值就是我們給 namerd 設定的 Nodeport。

接下來就能夠看到管理介面上顯示出新的規則了。

執行 Linkerd

這裡同樣基於官方的 https://raw.githubusercontent.com/BuoyantIO/linkerd-examples/master/k8s-daemonset/k8s/linkerd-namerd.yml

需要注意的是,官方給出的 yaml 檔案中有一處 bug,使得這個 yaml 只能在預設的 namespace 和 domain suffix 下執行。需要糾正對 namerd 的訪問方式,刪除 Namerd 後面的default.svc.cloud.local 即可。

同樣的,他的服務埠和管理埠都應該改用 NodePort 方式進行暴露。

執行後,同樣可以看到 Linkerd 的管理介面。

測試

下面可以做一個簡單的測試,來證明流量分配的有效性:

for ((i=1;i<=300;i++)); do curl -s "http://10.211.55.63:30001/";echo ""; done | grep -i blue| wc -l

可以看到,隨著迴圈次數的增加,其結果越來越趨近於 80/20 的分配比例。

接下來,我們修改上面的 dtab 為如下內容:

/host=>/#/io.l5d.k8s/default/http;
/http/*/*/*=>8*/host/blue&8*/host/green;

重新進行測試,就可以看到,流量分配已經發生了變化。另外,還可以在 Linkerd 的管理介面上看到網路流量的變化情況。

結語

這一組合基本能夠滿足流量漸變分配的功能需求,同時也有如豆瓣這樣的大廠使用,但他的 dtab 還是個相對複雜的東西,如果在生產上進行使用,還是需要進一步的學習。

另外,按照其文件中所陳述的功能範圍內容來看,僅用來做流量分配還是頗有點大材小用的味道,從個人來說,我傾向於一些更輕量級的解決方法。

作者:崔總

本文:https://www.kubernetes.org.cn/1275.html

原文:http://blog.fleeto.us/content/linkerd-namerdshi-xian-kubernetes-ji-qun-de-hui-du-fa-bu