A Service Mesh for Kubernetes (Part 5): Dogfood Environments and Ingress
原文作者:Alex Leong
原文位址:https://dzone.com/articles/a-service-mesh-for-kubernetes-part-v-dogfood-envir
譯者微網誌:@從流域到海域
譯者部落格:blog.csdn.net/solo95
Kubernetes中的Service Mesh(第5部分):Dogfood環境和入口
在這篇文章中,我們将向您展示如何使用連結執行個體的服務網格來處理Kubernetes上的入口流量,将流量分布到網格中的每個執行個體。我們還将通過一個示例來示範linkerd的進階路由功能,方法是建立一個 dogfood 環境,将某些請求路由到較新版本的基礎應用程式,例如用于内部的釋出前測試。
(删掉了原文中的某些連結,因為會被雲+的編輯器識别為非法連結,包含所有連結的譯文可以在譯者部落格裡檢視)
這篇文章是關于使用linkerd作為流量到Kubernetes網絡的入口點。從0.9.1版本開始,linkerd将直接支援Kubernetes Ingress資源,這是本文中一些用例的一個替代的,可能更簡單的起點。有關如何使用linkerd作為Kubernetes入口控制器的資訊,請參閱Sarah的部落格文章Linkerd作為入口控制器。
這是關于linkerd,Kubernetes和service mesh的一系列文章中的一篇文章。本系列的其他部分包括:
- Service重要名額
- 以DaemonSet方式運作linkerd
- 加密所有的東西
- 通過流量切換進行連續部署
- Dogfood環境,入口和邊緣路由(本文)
- 輕松釋出微服務
- 如何使分布式跟蹤變得容易
- 使用Linkerd作為入口控制器
- gRPC樂趣和收益
- 服務網格API
- 出口
- 重試預算,截止日期傳播,和如何讓失敗變得優雅(原文:Retry budgets, deadline propagation, and failing gracefully)
- 通過頂層名額(top-line metrics)實作自動縮放
在本系列的前幾期中,我們向您展示了如何使用linkerd來捕獲頂層名額(top-line metrics),透明地在服務調用中添加TLS,并執行bluegreen部署。這些文章展示了如何在像Kubernetes這樣的環境中使用linkerd作為srevice mesh,為内部服務對服務調用增加了一層彈性和性能。在這篇文章中,我們将把這個模型擴充到入口路由。
盡管本文中的示例是針對Kubernetes的,但我們不會使用 Kubernetes提供的内置 Ingress Resource(對此請參閱 Sarah的文章)。雖然Ingress Resource是一種基本路徑和基于主機路由的簡便方法,但在撰寫本文時,它們仍相當有限。在下面的例子中,我們做的将遠遠超出Ingress Resources所提供的功能。
步驟1:部署Linkerd Service Mesh
從前面的文章中我們針對Kubernetes中的基本linkerd service mesh配置開始,我們将進行兩個更改以支援入口(ingress):我們将修改linkerd配置以添加一個額外的邏輯路由器,然後調整圍繞着linkerd展開的Kubernetes服務對象中的VIP。(完整的配置在這裡: linkerd-ingress.yml。)
以下是linkerd執行個體上新的
ingress
邏輯路由器,它将處理入口流量并将其路由到相應的服務:
routers:
- protocol: http
label: ingress
dtab: |
/srv => /#/io.l5d.k8s/default/http ;
/domain/world/hello/www => /srv/hello ;
/domain/world/hello/api => /srv/api ;
/host => /$/io.buoyant.http.domainToPathPfx/domain ;
/svc => /host ;
interpreter:
kind: default
transformers:
- kind: io.l5d.k8s.daemonset
namespace: default
port: incoming
service: l5d
servers:
- port: 4142
ip: 0.0.0.0
複制
在這個配置中,我們使用linkerd的路由文法,dtabs來将請求從一個域轉發到另一個服務中去- 在這種情況下,從“api.hello.world”到
api
服務,從“www.hello.world”到
world
服務。為了簡單起見,我們為每個域添加了一條規則,這些映射可以很容易地被聚合以實作更複雜的設定。(如果你是一個linkerd配置愛好者,我們将通過組合linkerd預設的header token identifier在主機header上實作路由轉發,
the domainToPathPfx
namer 把虛主機名轉換成分級路徑,和并且
io.l5d.k8s.daemonset
transforme将請求發送到相應的主機 本地的linkerd上。)
我們已經将此入口路由器添加到每個linkerd執行個體 - 以真正的service mesh方式,我們将在這些執行個體之間完全配置設定入口流量,以便沒有哪一個執行個體成為單點故障。
我們還需要修改我們的
k8s
服務對象,以便用端口80上的
outgoing
VIP去替換
ingress
VIP。這将允許我們将入口流量直接發送到linkerd service mesh - 主要用于調試目的,因為在點選linkerd之前,流量不會被消毒。(下一步,我們将解決這個問題。)
Kubernetes變化看起來像這樣:
---
apiVersion: v1
kind: Service
metadata:
name: l5d
spec:
selector:
app: l5d
type: LoadBalancer
ports:
- name: ingress
port: 80
targetPort: 4142
- name: incoming
port: 4141
- name: admin
port: 9990
複制
以上所有操作都可以通過運作以下指令來完成:使用完整的帶入口的linkerd service mesh配置:
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd-ingress.yml
複制
第2步:部署服務
對于在這個例子中的服務,我們将使用相同的hello and world configs 從以前的部落格文章,我們将添加兩個新的服務:一個API service,這就要求既
hello
服務 和
world
服務,以及word服務的新版本:
world-v2
,這将傳回“earth”而不是“world”這個詞 - 正在逐漸壯大的hacker團隊已經向我們證明了,他們的A/B測試顯示這一變化将使參與度提高10倍。
以下指令将把三個Hello World服務部署到預設名稱空間:
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world.yml
複制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/api.yml
複制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/world-v2.yml
複制
在這一點上,我們應該能夠通過Kubernetes的
ingress
VIP 發送流量來測試設定 。在沒有使用DNS的情況下,我們将在請求中手動設定一個主機頭:
$ INGRESS_LB=$(kubectl get svc l5d -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ curl -s -H "Host: www.hello.world" $INGRESS_LB
Hello (10.0.5.7) world (10.0.4.7)!!
$ curl -s -H "Host: api.hello.world" $INGRESS_LB
{"api_result":"api (10.0.3.6) Hello (10.0.5.4) world (10.0.1.5)!!"}
複制
成功!我們已經将linkerd設定為入口控制器,并且我們已經使用它将不同域中收到的請求路由轉發到不同的服務。正如你所看到的,生産流量正在實作
world-v1
服務 - 我們還沒有準備好把
world-v2
展示出來。
第3步:NGINX中的一層
到了這一步,我們有正在運作的入口(ingress)。但是,我們目前還沒有準備好生産。首先,我們的入口路由器不會從請求中去掉頭檔案,這意味着外部請求可能包含我們不想接受的頭檔案。例如,linkerd允許每個請求應用路由規則設定将其header設定為
l5d-dtab
。這對于新服務的臨時分級是一個非常有用的功能,但這可能不是來自外部世界的合适調用!
例如,我們可以使用
l5d-dtab
标題來覆寫使用的路由邏輯
world-v2
而不是
world-v1
外部的生産 服務:
$ curl -H "Host: www.hello.world" -H "l5d-dtab: /host/world => /srv/world-v2;" $INGRESS_LB
Hello (10.100.4.3) earth (10.100.5.5)!!
複制
在響應中請注意 earth,表示這是
world-v2
服務的結果 。這很酷,但這種權限我們絕對不想給任何人!
我們可以通過添加NGINX 來解決這個問題和其他問題(例如如何服務靜态檔案) 。如果我們配置NGINX在其代理的請求到連結入口路由之前剝離傳入的報頭,我們将得到兩全其美的好處:一個能夠安全處理外部流量的入口層,還有linkerd進行的動态的,基于服務的路由。
讓我們把nginx添加到叢集。我們将使用這個nginx.conf來配置它 。我們将使用我們的虛拟伺服器下的
www.hello.world
和
api.hello.world
的
proxy_pass
指令發送請求到linkerd執行個體,為了最大程度地發揮作用,我們将使用Headers More提供的
more_clear_input_headers
指令(使用通配符比對)。
(還有另外的方法,我們可以通過使用nginx的
proxy_set_header
指令來避免使用第三方的Nginx子產品來清除封包頭。我們會需要為每個單獨的條目剝離
l5d-ctx-
封包頭還有
l5d-dtab
和
l5d-sample
封包頭。)
請注意,從 linkerd 0.9.0開始,我們可以通過設定
clearContext: true
清除在入口路由器伺服器傳入的
l5d-*
封包頭。然而,nginx還有很多我們可以使用的功能(就像你現在看到的那樣),是以把nginx和linkerd結合使用仍然是有價值的。
對于你們這些家工作的人,我們已經釋出了一個nginx的Docker鏡像,其中把安裝了 Headers More子產品的(Dockerfile)稱為buoyantio / nginx:1.11.5。我們可以使用這個Kubernetes配置檔案把上面提到的配置用這個鏡像部署:
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/nginx.yml
複制
在等待外部IP出現之後,我們可以通過點選nginx.conf中的簡單測試終端來測試NGINX:
$ INGRESS_LB=$(kubectl get svc nginx -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ curl $INGRESS_LB
200 OK
複制
我們現在應該能夠通過NGINX向我們的服務發送流量:
$ curl -s -H "Host: www.hello.world" $INGRESS_LB
Hello (10.0.5.7) world (10.0.4.7)!!
$ curl -s -H "Host: api.hello.world" $INGRESS_LB
{"api_result":"api (10.0.3.6) Hello (10.0.5.4) world (10.0.1.5)!!"}
複制
最後,讓我們測試一下我們的封包頭技巧并嘗試一下與
world-v2
服務進行直接通信。
$ curl -H "Host: www.hello.world" -H "l5d-dtab: /host/world => /srv/world-v2;" $INGRESS_LB
Hello (10.196.1.8) world (10.196.2.13)!!
複制
第四步:Dogfood的優勢時間
好吧,我們已經做好了準備:讓我們建立一個使用
world-v2
服務的dogfood環境 ,但僅限于使用某些流量!
為了簡單起見,我們為目标流量設定一個特定的cookie, 即
special_employee_cookie
。在實踐中,你可能想要比這更複雜的東西 - 要驗證它,需要來自公司内部網絡範圍的IP等等。
在NGINX和linkerd安裝之後,完成這些将會變得很簡單。我們将使用NGINX來檢查特定cookie(指special_employee_cookie)的存在,并為linkerd設定一個dtab重載頭來調整其路由方向。相關的NGINX配置如下所示:
if ($cookie_special_employee_cookie ~* "dogfood") {
set $xheader "/host/world => /srv/world-v2;";
}
proxy_set_header 'l5d-dtab' $xheader;
複制
如果您一直在遵循上述步驟,那麼已部署的NGINX已經包含了這個配置。我們可以像這樣測試它:
$ curl -H "Host: www.hello.world" --cookie "special_employee_cookie=dogfood" $INGRESS_LB
Hello (10.196.1.8) earth (10.196.2.13)!!
複制
系統成功運作!當這個cookie被設定時,你将進入dogfood模式。沒有它,你就會進入正常生産環境的流量模式。最重要的是,dogfood模式可以包含出現在服務堆棧中的任何地方的新版本的服務 ,甚至是多層深度的服務代碼,其中包括服務代碼forwards linkerd context headers,linkerd service mesh将負責其餘的工作。
結論
在這篇文章中,我們看到了如何使用linkerd為Kubernetes叢集提供強大靈活的入口(ingress)。我們已經示範了如何部署正如其名的已經準備完畢的生産環境配置,該生産環境配置使用linkerd進行服務路由轉發。我們已經示範了如何使用linkerd的一些進階路由功能來将 traffic-serving 拓撲與 deployment拓撲分離,進而允許建立dogfood環境而不需要單獨的叢集或耗費很多的部署時間。
有關在Kubernetes中運作linkerd的更多資訊,或者如果您在配置入口時遇到任何問題,請随時通過我們的Linkerd社群Slack來查找相關資訊,發送郵件到我們的郵件清單或直接與我們聯系。