Linkerd
是 Kubernetes
的服務網格。 它通過為您提供執行時除錯(runtime debugging
)、可觀察性(observability
)、可靠性(reliability
)和安全性(security
),使執行服務更輕鬆、更安全 — 所有這些都不需要對您的程式碼進行任何更改。
服務網格是用於處理服務間通訊的專用基礎設施層。它負責通過包含現代雲原生應用程式的複雜服務拓撲來可靠地傳遞請求。實際上,服務網格通常通過一組輕量級網路代理來實現,這些代理與應用程式程式碼一起部署,而不需要感知應用程式本身。— Willian Morgan Buoyant CEO
為什麼我們需要 Service Mesh
?
- What's a service mesh? And why do I need one? 一文中做了詳細的解釋,這裡不再贅述。擁抱雲原生,微服務已進入
Service Mesh
時代。
為什麼折騰 Linkerd2
而不是 Istio
?
部署環境
- 騰訊雲 TKE K8S 叢集(或你自建的私有 K8S 叢集)
- CentOS 7.x
可先快速過一個官方上手教程,本文是基於此在騰訊雲的實戰詳解。
檢視叢集版本
kubectl version --short
Client Version: v1.16.9
Server Version: v1.16.9
Linkerd2 CLI 安裝
首先我們需要下載並安裝最新版本的 linkerd
CLI。
我們直接進入 Linkerd2
版本發行頁面,檢視最新版:
這裡我們下載 linkerd2-cli-edge-21.6.1-linux-amd64。
安裝:
wget -c https://github.com/linkerd/linkerd2/releases/download/edge-21.6.1/linkerd2-cli-edge-21.6.1-linux-amd64
mv linkerd2-cli-edge-21.6.1-linux-amd64 /usr/local/bin/linkerd
chmod 755 /usr/local/bin/linkerd
現在我們執行 linkerd
,會看到如下資訊:
Usage:
linkerd [command]
Available Commands:
check Check the Linkerd installation for potential problems
completion Output shell completion code for the specified shell (bash, zsh or fish)
diagnostics Commands used to diagnose Linkerd components
help Help about any command
identity Display the certificate(s) of one or more selected pod(s)
inject Add the Linkerd proxy to a Kubernetes config
install Output Kubernetes configs to install Linkerd
install-cni Output Kubernetes configs to install Linkerd CNI
jaeger jaeger manages the jaeger extension of Linkerd service mesh
multicluster Manages the multicluster setup for Linkerd
profile Output service profile config for Kubernetes
repair Output the secret/linkerd-config-overrides resource if it has been deleted
uninject Remove the Linkerd proxy from a Kubernetes config
uninstall Output Kubernetes resources to uninstall Linkerd control plane
upgrade Output Kubernetes configs to upgrade an existing Linkerd control plane
version Print the client and server version information
viz viz manages the linkerd-viz extension of Linkerd service mesh
Flags:
--api-addr string Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)
--as string Username to impersonate for Kubernetes operations
--as-group stringArray Group to impersonate for Kubernetes operations
--cni-namespace string Namespace in which the Linkerd CNI plugin is installed (default "linkerd-cni")
--context string Name of the kubeconfig context to use
-h, --help help for linkerd
--kubeconfig string Path to the kubeconfig file to use for CLI requests
-L, --linkerd-namespace string Namespace in which Linkerd is installed ($LINKERD_NAMESPACE) (default "linkerd")
--verbose Turn on debug logging
Additional help topics:
linkerd alpha experimental subcommands for Linkerd
Use "linkerd [command] --help" for more information about a command.
安裝 Linkerd2 控制平面
首先,我們需要驗證下叢集,使用 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
pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
部署控制平面:
linkerd install | kubectl apply -f -
檢視 linkerd
名稱空間的 pod 部署情況:
kubectl get po -n linkerd
NAME READY STATUS RESTARTS AGE
linkerd-destination-6c6bf4fc4-282gd 3/3 Running 0 5m
linkerd-identity-7cd9998969-cvzc8 2/2 Running 0 5m
linkerd-proxy-injector-855b9b6747-r8pcz 2/2 Running 0 5m
同樣,我們使用 linkerd check
檢查一下。
ok, 接下來我們部署一些常用的擴充套件,增強我們控制平面的功能。
安裝 Linkerd2 控制平面常用擴充套件
grafana
,prometheus
,jaeger
等的部署(針對 Linkerd 2
的相關指標)
使用如下命令:
linkerd viz install | kubectl apply -f - # on-cluster metrics stack
kubectl get po -n linkerd-viz #審查 namespace, 直到所 pod 都 ready
# grafana-5659477d88-txq5b 0/2 PodInitializing 0 14m
# metrics-api-6fcb849dc-k9sw5 2/2 Running 0 14m
# prometheus-798d8d4698-4x8h2 2/2 Running 0 14m
# tap-f5984d7f7-fkpf9 0/2 PodInitializing 0 14m
# tap-injector-6b455dd64b-2c82n 0/2 PodInitializing 0 14m
# web-657dbffb8f-7d2gr 0/2 PodInitializing 0 14m
如果出現某一個 pod
出現錯誤,我們可以通過 kubectl describe po
來獲取詳細錯誤資訊,如:
kubectl describe po grafana-5659477d88-txq5b -n linkerd-viz
比如說,我這裡如下映象就被卡住了(騰訊雲):
cr.l5d.io/linkerd/grafana:edge-21.6.1
cr.l5d.io/linkerd/tap:edge-21.6.1
cr.l5d.io/linkerd/web:edge-21.6.1
大家可以(連線網際網路)手動拉取。
同樣,我們再部署兩個可選的擴充套件。
部署 jaeger
:
## optional
linkerd jaeger install | kubectl apply -f - # Jaeger collector and UI
kubectl get po -n linkerd-jaeger #審查 namespace
# OR:
# docker pull cr.l5d.io/linkerd/jaeger-webhook:edge-21.6.1
# docker pull jaegertracing/all-in-one:1.19.2
部署 multicluster
:
linkerd multicluster install | kubectl apply -f - # multi-cluster components
kubectl get po -n linkerd-multicluster
# 果然報錯了
linkerd-gateway-bcb5888c5-ws6wz 1/2 ErrImagePull 0 21s
檢視報錯資訊:
kubectl describe po linkerd-gateway-bcb5888c5-ws6wz -n linkerd-multicluster
# Normal BackOff 21s (x5 over 2m13s) kubelet, k8s-master-01 Back-off pulling image "gcr.io/google_containers/pause"
# Warning Failed 21s (x5 over 2m13s) kubelet, k8s-master-01 Error: ImagePullBackOff
很明顯(gcr.io/google_containers/pause
),我們需要連線網際網路(具體怎麼做,太多教程了,這裡不討論
)。
還有一個問題比較棘手的是,這裡即使 gcr.io/google_containers/pause
已經存在於本地,部署時還是回去 gcr.io
拉取。
所以,下面提供另一種方式來弄(沒連外網的情況下)。
使用 kustomize
解決 linkerd-gateway
(騰訊雲部署)不成功的問題
kustomize
如何安裝,大家自行檢視 https://kustomize.io。
首先,匯出 linkerd multicluster
部署 yaml
檔。
linkerd multicluster install > linkerd-multicluster.yaml
然後,我們給它打個補丁patch-linkerd-multicluster.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
linkerd.io/created-by: linkerd/cli edge-21.6.1
labels:
app.kubernetes.io/name: gateway
app.kubernetes.io/part-of: Linkerd
app.kubernetes.io/version: edge-21.6.1
linkerd.io/control-plane-component: gateway
app: linkerd-gateway
linkerd.io/extension: multicluster
name: linkerd-gateway
namespace: linkerd-multicluster
spec:
replicas: 1
selector:
matchLabels:
app: linkerd-gateway
template:
metadata:
annotations:
linkerd.io/created-by: linkerd/cli edge-21.6.1
linkerd.io/inject: enabled
config.linkerd.io/proxy-require-identity-inbound-ports: "4191,4143"
config.linkerd.io/enable-gateway: "true"
labels:
app: linkerd-gateway
spec:
containers:
- name: pause
image: ccr.ccs.tencentyun.com/cloud-native/google-pause
serviceAccountName: linkerd-gateway
ccr.ccs.tencentyun.com/cloud-native/google-pause
,這是筆者上傳到騰訊雲的公開映象。
新建 kustomization.yaml
:
resources:
- linkerd-multicluster.yaml
patchesStrategicMerge:
- patch-linkerd-multicluster.yaml
使用 kustomize
重新部署:
kustomize build . | kubectl apply -f -
重新檢視一下:
kubectl get po -n linkerd-multicluster
# linkerd-gateway-6c8dc7bb49-6tghc 2/2 Running 0 92s
完美解決。
使用 Traefik Ingressroute 匯出 linkerd-web 管理皮膚
關於 traefik v2
的部署,這裡不做贅述。
使用 kustomize
對 linkerd viz
部署進行更新
我這裡使用的域名是 linkerd-web.hacker-linner.com
。
匯出 yaml
檔:
linkerd viz install > linkerd-viz.yaml
打補丁,patch-linkerd-viz-web.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
linkerd.io/created-by: linkerd/helm edge-21.6.1
labels:
linkerd.io/extension: viz
app.kubernetes.io/name: web
app.kubernetes.io/part-of: Linkerd
app.kubernetes.io/version: edge-21.6.1
component: web
namespace: linkerd-viz
name: web
namespace: linkerd-viz
spec:
replicas: 1
selector:
matchLabels:
linkerd.io/extension: viz
component: web
namespace: linkerd-viz
template:
metadata:
annotations:
linkerd.io/created-by: linkerd/helm edge-21.6.1
labels:
linkerd.io/extension: viz
component: web
namespace: linkerd-viz
spec:
nodeSelector:
beta.kubernetes.io/os: linux
containers:
- args:
- -linkerd-metrics-api-addr=metrics-api.linkerd-viz.svc.cluster.local:8085
- -cluster-domain=cluster.local
- -grafana-addr=grafana.linkerd-viz.svc.cluster.local:3000
- -controller-namespace=linkerd
- -viz-namespace=linkerd-viz
- -log-level=info
- -enforced-host=^(linkerd-web\.hacker-linner\.com|localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
image: cr.l5d.io/linkerd/web:edge-21.6.1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /ping
port: 9994
initialDelaySeconds: 10
name: web
ports:
- containerPort: 8084
name: http
- containerPort: 9994
name: admin-http
readinessProbe:
failureThreshold: 7
httpGet:
path: /ready
port: 9994
resources:
securityContext:
runAsUser: 2103
serviceAccountName: web
更新 kustomization.yaml
:
resources:
- linkerd-viz.yaml
- linkerd-multicluster.yaml
patchesStrategicMerge:
- patch-linkerd-viz-web.yaml
- patch-linkerd-multicluster.yaml
重新部署
kustomize build . | kubectl apply -f -
設定 Ingressroute & Basic Auth
ingressroute-viz.yaml
apiVersion: v1
kind: Secret
metadata:
name: linkerd-authsecret
namespace: linkerd-viz
type: Opaque
stringData:
users: # 這裡使用 htpasswd -nb 進行設定
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: linkerd-basic-auth
namespace: linkerd-viz
spec:
basicAuth:
secret: linkerd-authsecret
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: l5d-header-middleware
namespace: linkerd-viz
spec:
headers:
customRequestHeaders:
l5d-dst-override: "web.linkerd-viz.svc.cluster.local:8084"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: linkerd-web-ingress-route
namespace: linkerd-viz
spec:
entryPoints:
- websecure
tls:
secretName: hacker-linner-cert-tls
routes:
- match: Host(`linkerd-web.hacker-linner.com`)
kind: Rule
services:
- name: web
port: 8084
middlewares:
- name: l5d-header-middleware
- name: linkerd-basic-auth
部署:
kubectl apply -f ingressroute-viz.yaml
部署 emojivoto
執行如下命令:
curl -sL https://run.linkerd.io/emojivoto.yml \
| kubectl apply -f
審查部署:
kubectl get po -n emojivoto
# OR
# docker pull docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
# docker pull docker.l5d.io/buoyantio/emojivoto-web:v11
# docker pull docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
emoji-6b776684f5-nnflg 1/1 Running 0 6m4s
vote-bot-64695c4dc6-jn8ln 1/1 Running 0 6m4s
voting-7778876bdb-kdvsx 1/1 Running 0 6m4s
web-6f8d774656-9dsw7 1/1 Running 0 6m4s
設定 Ingressroute
這裡是:https://emojivoto.hacker-linner.com
emojivoto-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: emojivoto-web-ingress-route
namespace: emojivoto
spec:
entryPoints:
- websecure
tls:
secretName: hacker-linner-cert-tls
routes:
- match: Host(`emojivoto.hacker-linner.com`)
kind: Rule
services:
- name: web-svc
port: 80
Service Mesh(Linkerd) 注入
新增 Linkerd
到 emojivoto
:
kubectl get -n emojivoto deploy -o yaml \
| linkerd inject - \
| kubectl apply -f -
審查一下是否一切正常:
linkerd -n emojivoto check --proxy
回到皮膚檢視 emojivoto
:
完美搞定,一切正常。
最後看一下 Grafana
皮膚:
Refs
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)