Linkerd Service Mesh 快速上手

Linkerd 是 Kubernetes 的一個完全開源的服務網格實現。它通過爲你提供運行時調試、可觀測性、可靠性和安全性,使運行服務更輕鬆、更安全,所有這些都不需要對你的代碼進行任何更改。

Linkerd 通過在每個服務實例旁邊安裝一組超輕、透明的代理來工作。這些代理會自動處理進出服務的所有流量。由於它們是透明的,這些代理充當高度儀表化的進程外網絡堆棧,向控制平面發送遙測數據並從控制平面接收控制信號。這種設計允許 Linkerd 測量和操縱進出你的服務的流量,而不會引入過多的延遲。爲了儘可能小、輕和安全,Linkerd 的代理採用 Rust 編寫。

功能概述

安裝

我們可以通過在本地安裝一個 Linkerd 的 CLI 命令行工具,通過該 CLI 可以將 Linkerd 的控制平面安裝到 Kubernetes 集羣上。

所以首先需要在本地運行 kubectl 命令,確保可以訪問一個可用的 Kubernetes 集羣,如果沒有集羣,可以使用 KinD 在本地快速創建一個。

$ kubectl version --short
Client Version: v1.23.5
Server Version: v1.22.8

可以使用下面的命令在本地安裝 Linkerd 的 CLI 工具:

$ curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh

如果是 Mac 系統,同樣還可以使用 Homebrew 工具一鍵安裝:

$ brew install linkerd

同樣直接前往 Linkerd Release 頁面 https://github.com/linkerd/linkerd2/releases/ 下載安裝即可。

安裝後使用下面的命令可以驗證 CLI 工具是否安裝成功:

$ linkerd  version
Client version: stable-2.11.1
Server version: unavailable

正常我們可以看到 CLI 的版本信息,但是會出現 Server version: unavailable 信息,這是因爲我們還沒有在 Kubernetes 集羣上安裝控制平面造成的,所以接下來我們就來安裝 Server 端。

Kubernetes 集羣可以通過多種不同的方式進行配置,在安裝 Linkerd 控制平面之前,我們需要檢查並驗證所有配置是否正確,要檢查集羣是否已準備好安裝 Linkerd,可以執行下面的命令:

$ linkerd check --pre
Linkerd core checks
===================

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected

linkerd-version
---------------
√ can determine the latest version
‼ cli is up-to-date
    is running version 2.11.1 but the latest stable version is 2.11.4
    see https://linkerd.io/2.11/checks/#l5d-version-cli for hints

Status check results are √

如果一切檢查都 OK 則可以開始安裝 Linkerd 的控制平面了,直接執行下面的命令即可一鍵安裝:

$ linkerd install | kubectl apply -f -

在此命令中,linkerd install 會生成一個 Kubernetes 資源清單文件,其中包含所有必要的控制平面資源,然後使用 kubectl apply 命令即可將其安裝到 Kubernetes 集羣中。

可以看到會將 Linkerd 控制面安裝到一個名爲 linkerd 的命名空間之下,安裝完成後會有如下幾個 Pod 運行:

$ kubectl get pods -n linkerd
NAME                                      READY   STATUS    RESTARTS       AGE
linkerd-destination-79d6fc496f-dcgfx      4/4     Running   0              166m
linkerd-identity-6b78ff444f-jwp47         2/2     Running   0              166m
linkerd-proxy-injector-86f7f649dc-v576m   2/2     Running   0              166m

安裝完成後通過運行以下命令等待控制平面準備就緒,並可以驗證安裝結果是否正常:

$ linkerd check

Linkerd core checks
===================

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ control plane pods are ready
√ cluster networks contains all node podCIDRs

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-webhooks-and-apisvc-tls
-------------------------------
√ proxy-injector webhook has valid cert
√ proxy-injector cert is valid for at least 60 days
√ sp-validator webhook has valid cert
√ sp-validator cert is valid for at least 60 days
√ policy-validator webhook has valid cert
√ policy-validator cert is valid for at least 60 days

linkerd-version
---------------
√ can determine the latest version
‼ cli is up-to-date
    is running version 2.11.1 but the latest stable version is 2.11.4
    see https://linkerd.io/2.11/checks/#l5d-version-cli for hints

control-plane-version
---------------------
√ can retrieve the control plane version
‼ control plane is up-to-date
    is running version 2.11.1 but the latest stable version is 2.11.4
    see https://linkerd.io/2.11/checks/#l5d-version-control for hints
√ control plane and cli versions match

linkerd-control-plane-proxy
---------------------------
√ control plane proxies are healthy
‼ control plane proxies are up-to-date
    some proxies are not running the current version:
        * linkerd-destination-79d6fc496f-dcgfx (stable-2.11.1)
        * linkerd-identity-6b78ff444f-jwp47 (stable-2.11.1)
        * linkerd-proxy-injector-86f7f649dc-v576m (stable-2.11.1)
    see https://linkerd.io/2.11/checks/#l5d-cp-proxy-version for hints
√ control plane proxies and cli versions match

Status check results are √

當出現上面的 Status check results are √ 信息後表示 Linkerd 的控制平面安裝成功了。除了使用 CLI 工具的方式安裝控制平面之外,我們也可以通過 Helm Chart 的方式來安裝,如下所示:

$ helm repo add linkerd https://helm.linkerd.io/stable
# set expiry date one year from now, in Mac:exp=$(date -v+8760H +"%Y-%m-%dT%H:%M:%SZ")
# in Linux:
$ exp=$(date -d '+8760 hour' +"%Y-%m-%dT%H:%M:%SZ")

$ helm install linkerd2 \
  --set-file identityTrustAnchorsPEM=ca.crt \
  --set-file identity.issuer.tls.crtPEM=issuer.crt \
  --set-file identity.issuer.tls.keyPEM=issuer.key \
  --set identity.issuer.crtExpiry=$exp \
  linkerd/linkerd2

此外該 chart 包含一個 values-ha.yaml 文件, 它覆蓋了一些默認值,以便在高可用性場景下進行設置, 類似於 linkerd install 中的 --ha 選項。我們可以通過獲取 chart 文件來獲得 values-ha.yaml

$ helm fetch --untar linkerd/linkerd2

然後使用 -f flag 提供覆蓋文件,例如:

## see above on how to set $exp
helm install linkerd2 \
  --set-file identityTrustAnchorsPEM=ca.crt \
  --set-file identity.issuer.tls.crtPEM=issuer.crt \
  --set-file identity.issuer.tls.keyPEM=issuer.key \
  --set identity.issuer.crtExpiry=$exp \
  -f linkerd2/values-ha.yaml \
  linkerd/linkerd2

採用哪種方式進行安裝均可,到這裏我們現在就完成了 Linkerd 的安裝,重新執行 linkerd version 命令就可以看到 Server 端版本信息了:

$ linkerd version
Client version: stable-2.11.1
Server version: stable-2.11.1

示例

接下來我們安裝一個簡單的示例應用 Emojivoto,該應用是一個簡單的獨立 Kubernetes 應用程序,它混合使用 gRPC 和 HTTP 調用,允許用戶對他們最喜歡的表情符號進行投票。

通過運行以下命令可以將 Emojivoto 安裝到 emojivoto 命名空間中:

$ curl -fsL https://run.linkerd.io/emojivoto.yml | kubectl apply -f -
namespace/emojivoto created
serviceaccount/emoji created
serviceaccount/voting created
serviceaccount/web created
service/emoji-svc created
service/voting-svc created
service/web-svc created
deployment.apps/emoji created
deployment.apps/vote-bot created
deployment.apps/voting created
deployment.apps/web created

該應用下可以看到一共包含 4 個 Pod 服務。

$ kubectl get pods -n emojivoto
NAME                        READY   STATUS    RESTARTS   AGE
emoji-66ccdb4d86-6vqvt      1/1     Running   0          91s
vote-bot-69754c864f-k26fb   1/1     Running   0          91s
voting-f999bd4d7-k44nb      1/1     Running   0          91s
web-79469b946f-bz295        1/1     Running   0          91s
$ kubectl get svc -n emojivoto
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
emoji-svc    ClusterIP   10.111.7.125     <none>        8080/TCP,8801/TCP   2m49s
voting-svc   ClusterIP   10.105.192.118   <none>        8080/TCP,8801/TCP   2m48s
web-svc      ClusterIP   10.111.236.171   <none>        80/TCP              2m48s

我們可以通過 port-forward 來暴露 web-svc 服務,然後便可在瀏覽器中訪問該應用。

$ kubectl -n emojivoto port-forward svc/web-svc 8080:80

現在我們可以在瀏覽器通過 http://localhost:8080 訪問 Emojivoto 應用了。

我們可以選擇頁面中喜歡的表情進行投票,但是選擇某些表情後會出現一些錯誤,比如當我們點擊甜甜圈表情符號的時候會得到一個 404 頁面。

不過不用擔心,這是應用中故意留下的錯誤,爲的是後面使用 Linkerd 來識別該問題。

接下來我們可以將上面的示例應用加入到 Service Mesh 中來,向其添加 Linkerd 的數據平面代理,直接運行下面的命令即可將 Emojivoto 應用網格化:

$ kubectl get -n emojivoto deploy -o yaml \
 | linkerd inject - \
 | kubectl apply -f -

deployment "emoji" injected
deployment "vote-bot" injected
deployment "voting" injected
deployment "web" injected

deployment.apps/emoji configured
deployment.apps/vote-bot configured
deployment.apps/voting configured
deployment.apps/web configured

上面的命令首先獲取在 emojivoto 命名空間中運行的所有 Deployments,然後通過 linkerd inject 運行它們的清單,然後將其重新應用到集羣。

注意 linkerd inject 命令只是在 Pod 規範中添加一個 linkerd.io/inject: enabled 的註解,並不會直接注入一個 Sidecar 容器,該註解即可指示 Linkerd 在創建 Pod 時將代理注入到其中,所以執行上面的命令後應用 Pod 中會新增一個 sidecar 的代理容器。

$ kubectl get pods -n emojivoto
NAME                        READY   STATUS    RESTARTS   AGE
emoji-696d9d8f95-8wrmg      2/2     Running   0          34m
vote-bot-6d7677bb68-c98kb   2/2     Running   0          34m
voting-ff4c54b8d-rdtmk      2/2     Running   0          34m
web-5f86686c4d-qh5bz        2/2     Running   0          34m

可以看到每個 Pod 現在都有 2 個容器,相較於之前多了一個 Linkerd 的 sidecar 代理容器。

當應用更新完成後,我們就成功將應用引入到 Linkerd 的網格服務中來了,新增的代理容器組成了數據平面,我們也可以通過下面的命令檢查數據平面狀態:

$ linkerd -n emojivoto check --proxy
Linkerd core checks
===================

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ control plane pods are ready
√ cluster networks contains all node podCIDRs

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-webhooks-and-apisvc-tls
-------------------------------
√ proxy-injector webhook has valid cert
√ proxy-injector cert is valid for at least 60 days
√ sp-validator webhook has valid cert
√ sp-validator cert is valid for at least 60 days
√ policy-validator webhook has valid cert
√ policy-validator cert is valid for at least 60 days

linkerd-identity-data-plane
---------------------------
√ data plane proxies certificate match CA

linkerd-version
---------------
√ can determine the latest version
‼ cli is up-to-date
    is running version 2.11.1 but the latest stable version is 2.11.4
    see https://linkerd.io/2.11/checks/#l5d-version-cli for hints

linkerd-control-plane-proxy
---------------------------
√ control plane proxies are healthy
‼ control plane proxies are up-to-date
    some proxies are not running the current version:
        * linkerd-destination-79d6fc496f-dcgfx (stable-2.11.1)
        * linkerd-identity-6b78ff444f-jwp47 (stable-2.11.1)
        * linkerd-proxy-injector-86f7f649dc-v576m (stable-2.11.1)
    see https://linkerd.io/2.11/checks/#l5d-cp-proxy-version for hints
√ control plane proxies and cli versions match

linkerd-data-plane
------------------
√ data plane namespace exists
√ data plane proxies are ready
‼ data plane is up-to-date
    some proxies are not running the current version:
        * emoji-696d9d8f95-8wrmg (stable-2.11.1)
        * vote-bot-6d7677bb68-c98kb (stable-2.11.1)
        * voting-ff4c54b8d-rdtmk (stable-2.11.1)
        * web-5f86686c4d-qh5bz (stable-2.11.1)
    see https://linkerd.io/2.11/checks/#l5d-data-plane-version for hints
√ data plane and cli versions match
√ data plane pod labels are configured correctly
√ data plane service labels are configured correctly
√ data plane service annotations are configured correctly
√ opaque ports are properly annotated

Status check results are √

當然,我們還是可以通過 http://localhost:8080 訪問應用,當然在使用上和之前沒什麼區別,我們可以通過 Linkerd 去查看應用實際上做了哪些事情,但是我們需要去單獨安裝一個插件,由於 Linkerd 的核心控制平面非常輕量級, 所以 Linkerd 附帶了一些插件,這些插件爲 Linkerd 添加了一些非關鍵但通常有用的功能,包括各種儀表板,比如我們可以安裝一個 viz 插件,Linkerd-Viz 插件包含 Linkerd 的可觀察性和可視化組件。安裝命令如下所示:

$ linkerd viz install | kubectl apply -f -

上面的命令會創建一個名爲 linkerd-viz 的命名空間,會在該命名空間中安裝監控相關的應用,比如 Prometheus、Grafana 等。

$ kubectl get pods -n linkerd-viz
NAME                            READY   STATUS    RESTARTS   AGE
grafana-8d54d5f6d-wwtdz         2/2     Running   0          3h1m
metrics-api-6c59967bf4-pjwdq    2/2     Running   0          4h22m
prometheus-7bbc4d8c5b-5rc8r     2/2     Running   0          4h22m
tap-599c774dfb-m2kqz            2/2     Running   0          4h22m
tap-injector-748d54b7bc-jvshs   2/2     Running   0          4h22m
web-db97ff489-5599v             2/2     Running   0          4h22m

安裝完成後,我們可以使用下面的命令打開一個 dashboard 頁面:

$ linkerd viz dashboard &

viz 插件部署完成後,執行上面的命令後會自動在瀏覽器中打開一個 Linkerd 的可觀察性的 Dashboard。

此外我們也可以通過 Ingress 來暴露 viz 服務,創建如下所示的資源對象:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  namespace: linkerd-viz
  annotations:
    nginx.ingress.kubernetes.io/upstream-vhost: $service_name.$namespace.svc.cluster.local:8084
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header Origin "";
      proxy_hide_header l5d-remote-ip;
      proxy_hide_header l5d-server-id;
spec:
  ingressClassName: nginx
  rules:
    - host: linkerd.k8s.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 8084

應用後就可以通過 linkerd.k8s.local 訪問 viz 了。

還可以顯示自動生成的拓撲圖。

在頁面上我們可以找到每個 Emojivoto 組件的實時指標,就可以確定哪個組件出現了部分故障了,這樣就可以有針對性的去解決問題了。

在對應的資源後面包含一個 Grafana 的圖標,點擊可以自動跳轉到 Grafana 的監控頁面。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZRheNX1Gs8rZKmQy2XOkSQ