Linkerd 使用指南
前言
該文章已歸檔到 ofollow,noindex">kubernetes-handbook 第五章【領域應用】中,一切內容以 kubernetes-handbook 為準,該文件可能不會及時更新。
以下內容參考: Kubernetes_Final.pdf" target="_blank" rel="nofollow,noindex">A Service Mesh for Kubernetes
Linkerd 作為一款 service mesh 與kubernetes 結合後主要有以下幾種用法:
- 作為服務閘道器,可以監控 kubernetes 中的服務和例項
- 使用 TLS 加密服務
- 通過流量轉移到持續交付
- 開發測試環境(Eat your own dog food)、Ingress 和邊緣路由
- 給微服務做 staging
- 分散式 tracing
- 作為 Ingress controller
- 使用 gRPC 更方便
以下我們著重講解在 kubernetes 中如何使用 linkerd 作為 kubernetes 的 Ingress controller,並作為邊緣節點代替 Traefik 的功能,詳見 邊緣節點的配置 。
準備
安裝測試時需要用到的映象有:
buoyantio/helloworld:0.1.4 buoyantio/jenkins-plus:2.60.1 buoyantio/kubectl:v1.4.0 buoyantio/linkerd:1.1.2 buoyantio/namerd:1.1.2 buoyantio/nginx:1.10.2 linkerd/namerctl:0.8.6 openzipkin/zipkin:1.20 tutum/dnsutils:latest
這些映象可以直接通過 Docker Hub 獲取,我將它們下載下來並上傳到了自己的私有映象倉庫 sz-pg-oam-docker-hub-001.tendcloud.com 中,下文中用到的映象皆來自我的私有映象倉庫,yaml 配置見 linkerd 目錄,並在使用時將配置中的映象地址修改為你自己的。
部署
首先需要先建立 RBAC,因為使用 namerd 和 ingress 時需要用到。
$ kubectl create -f linkerd-rbac-beta.yml
Linkerd 提供了 Jenkins 示例,在部署的時候使用以下命令:
$ kubectl create -f jenkins-rbac-beta.yml $ kubectl create -f jenkins.yml
訪問 http://jenkins.jimmysong.io


注意:要訪問 Jenkins 需要在 Ingress 中增加配置,下文會提到。
在 kubernetes 中使用 Jenkins 的時候需要注意 Pipeline 中的配置:
def currentVersion = getCurrentVersion() def newVersion = getNextVersion(currentVersion) def frontendIp = kubectl("get svc l5d -o jsonpath=\"{.status.loadBalancer.ingress[0].*}\"").trim() def originalDst = getDst(getDtab())
frontendIP 的地址要配置成 service 的 Cluster IP ,因為我們沒有用到LoadBalancer。
需要安裝 namerd,namerd 負責 dtab 資訊的儲存,當然也可以儲存在 etcd、consul中。dtab 儲存的是路由規則資訊,支援遞迴解析,詳見 dtab 。
流量切換主要是通過 dtab 來實現的,通過在 HTTP 請求的 header 中增加 l5d-dtab 和 Host 資訊可以對流量分離到 kubernetes 中的不同 service 上。
遇到的問題
Failed with the following error(s) Error signal dtab is already marked as being deployed!
因為該 dtab entry 已經存在,需要刪除後再執行。

dtab 儲存在 namerd 中,該頁面中的更改不會生效,需要使用命令列來操作。
使用 namerctl 來操作。
$ namerctl --base-url http://namerd-backend.jimmysong.io dtab update internal file
注意:update 時需要將更新文字先寫入檔案中。
部署 Linkerd
直接使用 yaml 檔案部署,注意修改映象倉庫地址。
# 建立 namerd $ kubectl create -f namerd.yaml # 建立 ingress $ kubectl create -f linkerd-ingress.yml # 建立測試服務 hello-world $ kubectl create -f hello-world.yml # 建立 API 服務 $ kubectl create -f api.yml # 建立測試服務 world-v2 $ kubectl create -f world-v2.yml
為了在本地除錯 linkerd,我們將 linkerd 的 service 加入到 ingress 中,詳見 邊緣節點配置 。
在 Ingress 中增加如下內容:
- host: linkerd.jimmysong.io http: paths: - path: / backend: serviceName: l5d servicePort: 9990 - host: linkerd-viz.jimmysong.io http: paths: - path: / backend: serviceName: linkerd-viz servicePort: 80 - host: l5d.jimmysong.io http: paths: - path: / backend: serviceName: l5d servicePort: 4141 - host: jenkins.jimmysong.io http: paths: - path: / backend: serviceName: jenkins servicePort: 80
在本地/etc/hosts中新增如下內容:
172.20.0.119 linkerd.jimmysong.io 172.20.0.119 linkerd-viz.jimmysong.io 172.20.0.119 l5d.jimmysong.io
測試路由功能
使用 curl 簡單測試。
單條測試
$ curl -s -H "Host: www.hello.world" 172.20.0.120:4141 Hello (172.30.60.14) world (172.30.71.19)!!%
請注意請求返回的結果,表示訪問的是 world-v1 service。
$ for i in $(seq 0 10000);do echo $i;curl -s -H "Host: www.hello.world" 172.20.0.120:4141;done
使用 ab test。
$ ab -c 4 -n 10000 -H "Host: www.hello.world" http://172.20.0.120:4141/ This is ApacheBench, Version 2.3 <$Revision: 1757674 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 172.20.0.120 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Server Hostname: 172.20.0.120 Server Port: 4141 Document Path: / Document Length: 43 bytes Concurrency Level: 4 Time taken for tests: 262.505 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 2210000 bytes HTML transferred: 430000 bytes Requests per second: 38.09 [#/sec] (mean) Time per request: 105.002 [ms] (mean) Time per request: 26.250 [ms] (mean, across all concurrent requests) Transfer rate: 8.22 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 36 51 91.1 39 2122 Processing: 39 54 29.3 46 585 Waiting: 39 52 20.3 46 362 Total: 76 105 96.3 88 2216 Percentage of the requests served within a certain time (ms) 50% 88 66% 93 75% 99 80% 103 90% 119 95% 146 98% 253 99% 397 100% 2216 (longest request)
監控 Kubernets 中的服務與例項
訪問 http://linkerd.jimmysong.io 檢視流量情況
Outcoming

Incoming

訪問 http://linkerd-viz.jimmysong.io 檢視應用 metric 監控

測試路由
測試在 http header 中增加 dtab 規則。
$ curl -H "Host: www.hello.world" -H "l5d-dtab:/host/world => /srv/world-v2;" 172.20.0.120:4141 Hello (172.30.60.14) earth (172.30.94.40)!!
請注意呼叫返回的結果,表示呼叫的是 world-v2 的 service。
另外再對比 ab test 的結果與 linkerd-viz 頁面上的結果,可以看到結果一致。
但是我們可能不想把該功能暴露給所有人,所以可以在前端部署一個 nginx 來過濾 header 中的 l5d-dtab 打頭的欄位,並通過設定 cookie 的方式來替代 header 裡的 l5d-dtab 欄位。
$ http_proxy=http://172.20.0.120:4141 curl -s http:/hello Hello (172.30.60.14) world (172.30.71.19)!!
將 Linkerd 作為 Ingress Controller
將 Linkerd 作為 kubernetes ingress controller 的方式跟將 Treafik 作為 ingress controller 的過程過程完全一樣,可以直接參考 邊緣節點配置 。
架構如下圖所示。

(圖片來自 A Service Mesh for Kubernetes – Buoyant.io)
當然可以繞過 kubernetes ingress controller 直接使用 linkerd 作為邊界路由,通過 dtab 和 linkerd 前面的 nginx 來路由流量。
後記
看了 Linkerd 的官方示例 linkerd-examples 和 A Service Mesh for Kubernetes 個人感覺兩者配合起來講解的不是很清楚,每個章節不是特別的獨立,也不是很有邏輯性。
Linkerd 跟 Istio 一樣都是 service mesh,可以在服務間做很多事情,但是 istio 使用起來更加簡單靈活,兩者的功能基本一樣,不過我更傾向於 Istio,因為它更輕量級,不需要在每個節點都部署一個 DaemonSet,並且使用 ingress 也更方便與 kubernetes 整合。
本文轉自中文社群- Linkerd 使用指南