![](/style/images/good.png)
![](/style/images/bad.png)
在 Istio 服务网格中使用 Traefik Ingress Controller
source link: https://cloudnative.to/blog/using-traefik-ingress-controller-with-istio-service-mesh/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在 Istio 服务网格中使用 Traefik Ingress Controller
本文演示了如何将 Traefik Ingress 作为 Istio 服务网格的入口点。
本文译自 Using Traefik Ingress Controller with Istio Service Mesh。
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 控制器相集成!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK