在 Istio 服務網格中使用 Traefik Ingress Controller
作者:Petr McAllister,Petr 是一名 IT 專業人士,擁有 20 多年的國際經驗和計算機科學碩士學位。他是 Tetrate 的技術專家。
Istio 服務網格自帶 ingress,但我們經常看到有要求使用非 Istio ingress 的客戶。此前,我們已經介紹過將 NGINX 與 Istio 集成的情況。最近,我們一直在與使用 Traefik ingress 的客戶合作。通過對我們之前建議的方法進行一些輕微調整,我將向你介紹如何實現 Traefik 作爲 Istio 服務網格的入口網關。
流量的流向如下圖所示。一旦請求從 Traefik Ingress 到達服務網格,Istio 就能夠對請求應用安全性、可觀察性和流量引導規則。
傳入的流量繞過 Istio sidecar,直接到達 Traefik,所以請求終止在 Traefik ingress。
Traefik 使用 IngressRoute
配置重寫 Host 頭以匹配目的地,並將請求轉發到目標服務,這是一個多步驟的過程。
• 從 Traefik Ingress 出來的請求被重定向到 Istio sidecar(由 iptables)。•Sidecar 接收請求,對其進行加密(因爲我們的 Istio PeerAuthentication
策略要求使用 STRICT mTLS),然後將請求轉發到目標服務的 pod。
下面是一個端到端的部署示例,使用 Istio 的 bookinfo 演示應用,但用 Traefik ingress 來支撐整個部署。簡而言之,要想在自己的環境中實現這個功能。
• 用 Istio sidecar 部署 Traefik 控制器,註釋部署,使入站流量繞過 Istio Sidecar:
# Exclude the ports that Traefik receives traffic on
traffic.sidecar.istio.io/excludeInboundPorts: “80”
# Make sure Traefik controller can talk to the Kubernetes API server
traffic.sidecar.istio.io/excludeOutboundIPRanges: X.X.X.X/32
• 在應用程序命名空間中啓用 Istio sidecar 注入,並部署任何你需要的 Istio 特定配置。• 用 Traefik Middleware
對象創建 IngressRoute
,將主機名改寫爲網格識別的主機名(即集羣中的服務;下文將通過一個例子詳細討論)。
使用 Traefik Ingress 的 Bookinfo
這篇文章的其餘部分涵蓋了部署 Istio 的 Bookinfo 示例應用程序,使用 Traefik 作爲部署的 Ingress 代理。
設置環境
參考以下步驟。
部署一個至少 1.17 版本的 Kuberentes 集羣(最小支持 Istio 1.8 版本)。我們使用 Google Kubernetes Engine 創建的集羣。
gcloud container clusters create istio-traefik \
--cluster-version=1.17 \
--region <GCP region> \
--machine-type=e2-standard-4 \
--project <GCP Project> \
--num-nodes 1 \
--node-locations <GCP Zone> # i.e us-west2-b (otherwise 1 node per zone)
下載 Istio 1.8
curl -sL https://git.io/getLatestIstio |\
ISTIO_VERSION=1.8.1 sh -
在啓用 HTTP 訪問日誌的情況下進行安裝。
./istio-1.8.1/bin/istioctl install \
--set meshConfig.accessLogFile=/dev/stdout \
--skip-confirmation
部署 Bookinfo 應用
安裝好 Istio 後,我們就可以開始部署我們的應用程序了。我們將使用 Istio 的 Bookinfo 應用程序進行演示。這個示例應用程序是 Istio 發行版的一部分(在./istio-1.8.1/samples/
文件夾中)。
創建 bookinfo namespace。
kubectl create ns bookinfo
設置 label,讓 sidecar 自動注入。
kubectl label namespace bookinfo istio-injection=enabled
在該 namespace 中部署 bookinfo 應用程序。
kubectl apply -f istio-1.8.1/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
確認所有的吊艙都已啓動,並部署了側車。
啓用 Istio mTLS 爲應用程序命名空間的服務到服務通信。
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: bookinfo
spec:
mtls:
mode: STRICT
EOF
部署 Traefik 入口
現在是時候按照 v2.3 文檔來部署 Traefik 了(本篇文章中 Traefik 的最新版本是 2.3,但如果你根據你的版本調整了 IngressRoute
和 Middleware
資源,它將適用於任何版本的 Traefik)。
部署 Traefik。請注意,Traefik 網站上的文檔部署有一些修改(代替 Traefik 文檔中的默認命名空間,將指定 bookinfo 命名空間)。該文件可以在這裏訪問並應用如下。
$ kubectl apply -f http://bit.ly/Traefik-CRDs-and-Roles
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressrouteudps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsstores.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/traefikservices.traefik.containo.us created
clusterrole.rbac.authorization.k8s.io/traefik-ingress-lb created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-lb created
爲傳入的請求創建一個服務。該服務將接收外部 IP 地址。(Traefik 網站上的例子有一些變化)。
• 需要指定 Namespace。• 只發布兩個端口:80 用於 Bookinfo 應用,8080 用於 Traefik 管理。• 服務需要使用的標籤(traefik-ingress-lb)指向 Traefik。•Type: Loadbalancer
是爲了告訴 GCP 給服務分配一個外部 IP。
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: bookinfo
spec:
ports:
- protocol: TCP
name: web
port: 80
- protocol: TCP
name: admin
port: 8080
selector:
app: traefik-ingress-lb
type: LoadBalancer
EOF
確認服務的創建符合預期。
$ kubectl get svc traefik -n bookinfo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.35.244.227 35.236.XXX.XXX 80:31718/TCP,8080:31334/TCP 2m6s
正如 Traefik 網站中介紹的,需要應用 ServiceAccount
的 Kubernetes 部署。除了名稱和命名空間,網站示例還引入了以下變化。
• 爲了簡單起見,刪除了安全端點。•Accesslog
:增加了 =true
,因爲沒有這個值就不行。•Log.level
設置爲 DEBUG 將幫助我們看到發生了什麼。• 增加了 traffic.sidecar.istio.io
註釋(更多細節請參考之前提到的 Tetrate NGINX 文章)。
KUBERNETES_SVC_IP=$( kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' )
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: bookinfo
name: traefik-ingress-lb
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: bookinfo
name: traefik-ingress-lb
labels:
app: traefik-ingress-lb
spec:
replicas: 1
selector:
matchLabels:
app: traefik-ingress-lb
template:
metadata:
labels:
app: traefik-ingress-lb
annotations:
traffic.sidecar.istio.io/excludeInboundPorts: "80"
traffic.sidecar.istio.io/excludeOutboundIPRanges: ${KUBERNETES_SVC_IP}/32
spec:
serviceAccountName: traefik-ingress-lb
containers:
- name: traefik-ingress-lb
image: traefik:v2.3
args:
- --api.insecure
- --accesslog=true
- --providers.kubernetescrd
- --entrypoints.web.address=:80
- --log.level=DEBUG
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
EOF
確認 Traefik 在 Bookinfo 命名空間的部署。
$ kubectl get pods -n bookinfo -l app=traefik-ingress-lb
NAME READY STATUS RESTARTS AGE
traefik-ingress-lb-669fc4b77d-74mpx 2/2 Running 0 2m35s
獲取服務 IP 並記錄 BOOKINFO_IP 變量值。
BOOKINFO_IP=$(kubectl -n bookinfo get service traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
測試來自 Ingress 80 端口的響應,看看它是否有通往應用的路由。
curl -I $BOOKINFO_IP
確保它返回 “404 Not Found”—— 由於尚未實施 Ingress 規則,所以預計會有 not-200 響應。
配置 Traefik Ingress 規則
Traefik 的 Middleware
頭重寫功能將使 Istio 服務網格正常運行。本例中,需要將主機定義爲 productpage.bookinfo.svc
。頭可以根據 Traefik 文檔來定義。
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: productpage-header
namespace: bookinfo
spec:
headers:
customRequestHeaders:
Host: productpage.bookinfo.svc
EOF
最後一步是指定 ingress 請求的路由邏輯,因爲本文的重點是服務網格集成。這個定義非常簡單,將所有到達 80 端口的入站請求轉發到名爲 ProductPage 的前沿 bookinfo 應用服務(服務於 9080 端口的流量)。它還使用了上一步創建的中間件對象。
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: productpage
namespace: bookinfo
spec:
entryPoints:
- web
routes:
- match: PathPrefix(`/`)
kind: Rule
middlewares:
- name: productpage-header
services:
- name: productpage
port: 9080
EOF
驗證部署功能
重新測試應用程序的響應。
curl -I $BOOKINFO_IP
我們會收到 “200 OK “的回覆。也可以通過瀏覽器測試,使用 http://<BOOKINFO_IP>/productpage
。
如果在 http://<BOOKINFO_IP>/productpage
,就會返回應用響應。
通過查詢 istio-proxy 容器的 bookinfo 命名空間中的 Traefik pod 日誌,可以在 istio-proxy 日誌中看到嚮應用程序發出的請求。沒有傳入請求,因爲它們直接到達 Traefik Ingress。
TRAEFIK_POD=$( kubectl -n bookinfo get pods -l app=traefik-ingress-lb -o jsonpath='{.items[0].metadata.name}' )
kubectl -n bookinfo logs ${TRAEFIK_POD} -c istio-proxy
請注意,請求處理後,日誌需要幾秒鐘才能顯示。只有在 Istio 安裝時使用 meshConfig.accessLogFile=/dev/stdout
標誌的情況下,纔會顯示日誌。
[2021-01-05T20:13:55.015Z] "GET /productpage HTTP/1.1" 200 - "-" 0 5179 1069 1069 "10.32.0.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "4bd443e9-1a2e-4d30-b1e3-398a5005f240" "productpage.bookinfo.svc" "10.32.0.18:9080" outbound|9080||productpage.bookinfo.svc.cluster.local 10.32.0.19:51810 10.32.0.18:9080 10.32.0.1:0 - default
[2021-01-05T20:13:56.301Z] "GET /static/bootstrap/fonts/glyphicons-halflings-regular.woff2 HTTP/1.1" 200 - "-" 0 18028 3 3 "10.32.0.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "8cb44552-c3c8-45dd-8674-4af207ce1648" "productpage.bookinfo.svc" "10.32.0.18:9080" outbound|9080||productpage.bookinfo.svc.cluster.local 10.32.0.19:51810 10.32.0.18:9080 10.32.0.1:0 - default
總結
本文演示瞭如何將 Traefik Ingress 作爲 Istio 服務網格的入口點。這裏應用的基本方法應該是適用的,即使你的環境與我們例子中使用的環境不同。當引入服務網格時,Traefik / 服務網格集成可以在不同的雲中成功實施,並使用全新或現有(也就是棕地)部署 Traefik。最終,您將獲得兩者最好的東西:Istio 服務網格與您所選擇的 Ingress 控制器相集成!
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/hNH-9JGK_Sa15a8xeClaPw