背景
集体应用 traefik 有差不多 1 - 2 年工夫,kubernetes ingress controller 代理有很多种形式 例如 ingress-nginx kong istio 等等。集体比拟习惯 traefik。从 19 年就开始应用。最早应用 traefik 不间接应用腾讯云私有云的 slb 是因为过后 slb 不能挂载多个证书,而我 kubernetes 的自建集群切实不想挂载多个 slb. 就偷懒用了 slb udp 绑定运行 traefik 节点的 80 443 端口。证书 tls 的 secret 间接挂载在 traefik 代理层下面。hsts http 跳转 https 的个性都配置在了 traefik 代理层下面。利用比拟少。qps 也没有那么高,这样的简略利用就满足了我的需要了
对于 traefik 的结缘
最早接触 traefik 是 Google 下面看 ingress controller 找到的 而后再阳明大佬的博客看到了 traefik 的实际 https://www.qikqiak.com/post/traefik2-ga/,还有超级小豆丁的博客 http://www.mydlq.club/article/41。两位大佬的博客是 kubernetes 初学者的宝藏博客值得珍藏拜读。
顺便吐个糟,用的 traefik2.4 版本 … 抄的豆丁大佬的..http://www.mydlq.club/article/107/ 哈哈哈
ingress controller 比照:
参照 https://zhuanlan.zhihu.com/p/109458069。
1. Kubernetes Gateway API
v2.4 版本的扭转(在 Traefik v2.4 版本中减少了对 Kubernetes Gateway API 的反对)一下局部抄自豆丁大佬与官网文档 https://gateway-api.sigs.k8s.io/。
1、Gateway API 是什么
Gateway API 是由 SIG-NETWORK 社区治理的一个开源我的项目。它是在 Kubernetes 中对服务网络建模的资源的汇合。这些资源 -,GatewayClass
,Gateway
,HTTPRoute
,TCPRoute
,Service
等 - 旨在通过表现力,可扩大和面向角色由很多供应商实现的,并具备宽泛的行业反对接口演进 Kubernetes 服务网络。
留神:此我的项目以前被称为“服务 API”,直到 2021 年 2 月被重命名为“_Gateway API _”。
2、Gateway API 的指标
Gateway API 旨在通过提供可表白的,可扩大的,面向角色的接口来改善服务网络,这些接口已由许多供应商施行并取得了宽泛的行业反对。
网关 API 是 API 资源(服务、网关类、网关、HTTPRoute、TCPRoute 等)的汇合。这些资源独特为各种网络用例建模。
Gateway API 如何依据 Ingress 等以后规范进行改良?
- 以下设计指标驱动了 Gateway API 的概念。这些证实了 Gateway 如何旨在改良 Ingress 等以后规范。
- 面向角色- 网关由 API 资源组成,这些 API 资源对应用和配置 Kubernetes 服务网络的组织角色进行建模。
- 便携式- 这不是改良,而是应该放弃不变。就像 Ingress 是具备许多实现的通用标准一样,Gateway API 也被设计为受许多实现反对的可移植标准。
- 富裕表现力- 网关 API 资源反对外围性能,例如基于标头的匹配,流量加权以及其余只能通过自定义批注在 Ingress 中实现的性能。
- 可扩大- 网关 API 容许在 API 的各个层上链接自定义资源。这样就能够在 API 构造内的适当地位进行精密的自定义。
其余一些值得注意的性能包含:
- GatewayClasses -GatewayClasses 形式化负载平衡实现的类型。这些类使用户能够轻松,明确地理解通过 Kubernetes 资源模型能够应用的性能。
- 共享网关和跨命名空间反对- 通过容许独立的 Route 资源绑定到同一网关,它们能够共享负载平衡器和 VIP。这容许团队(甚至跨命名空间)在没有间接协调的状况下平安地共享根底构造。
- 类型化路由和类型化后端- 网关 API 反对类型化路由资源以及不同类型的后端。这使 API 能够灵便地反对各种协定(例如 HTTP 和 gRPC)和各种后端指标(例如 Kubernetes Services,存储桶或函数)。
如果想理解更多内容,能够拜访 Kubernetes Gateway API 文档。
2. traefik on kubernetes 实际
部署玩 Traefik 利用后,创立内部拜访 Kubernetes 外部利用的路由规定,能力从内部拜访 kubernetes 外部利用。Traefik 目前反对三种形式创立路由规定形式,一种是创立 Traefik 自定义 Kubernetes CRD
资源,另一种是创立 Kubernetes Ingress
资源,还有就是 v2.4 版本对 Kubernetes 扩大 API Kubernetes Gateway API
适配的一种形式,创立 GatewayClass
、Gateway
与 HTTPRoute
资源
留神:这里 Traefik 是部署在 kube-system namespace 下,如果不想部署到配置的 namespace,须要批改上面部署文件中的 namespace 参数。当然了也能够新建一个独自的 namespace 去部署 traefik
1. 创立 CRD
参照 https://doc.traefik.io/traefik/reference/dynamic-configuration/kubernetes-crd/
traefik-crd.yaml
cat <<EOF > traefik-crd.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: serverstransports.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: ServersTransport
plural: serverstransports
singular: serverstransport
scope: Namespaced
EOF
kubectl apply -f traefik-crd.yaml
2. 创立 RBAC 权限
cat <<EOF > traefik-rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: kube-system
EOF
kubectl apply -f traefik-rbac.yaml
3. 创立 Traefik 配置文件
# 号后为正文,跟 2.X 前几个版本一样。减少了 kubernetesIngress kubernetesGateway 两种路由形式,过来只部署了 CRD 的形式。
cat <<EOF > traefik-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
namespace: kube-system
data:
traefik.yaml: |-
ping: "" ## 启用 Ping
serversTransport:
insecureSkipVerify: true ## Traefik 疏忽验证代理服务的 TLS 证书
api:
insecure: true ## 容许 HTTP 形式拜访 API
dashboard: true ## 启用 Dashboard
debug: false ## 启用 Debug 调试模式
metrics:
prometheus: "" ## 配置 Prometheus 监控指标数据,并应用默认配置
entryPoints:
web:
address: ":80" ## 配置 80 端口,并设置入口名称为 web
websecure:
address: ":443" ## 配置 443 端口,并设置入口名称为 websecure
providers:
kubernetesCRD: "" ## 启用 Kubernetes CRD 形式来配置路由规定
kubernetesIngress: "" ## 启用 Kubernetes Ingress 形式来配置路由规定
kubernetesGateway: "" ## 启用 Kubernetes Gateway API
experimental:
kubernetesGateway: true ## 容许应用 Kubernetes Gateway API
log:
filePath: "" ## 设置调试日志文件存储门路,如果为空则输入到控制台
level: error ## 设置调试日志级别
format: json ## 设置调试日志格局
accessLog:
filePath: "" ## 设置拜访日志文件存储门路,如果为空则输入到控制台
format: json ## 设置拜访调试日志格局
bufferingSize: 0 ## 设置拜访日志缓存行数
filters:
#statusCodes: ["200"] ## 设置只保留指定状态码范畴内的拜访日志
retryAttempts: true ## 设置代理拜访重试失败时,保留拜访日志
minDuration: 20 ## 设置保留申请工夫超过指定持续时间的拜访日志
fields: ## 设置拜访日志中的字段是否保留(keep 保留、drop 不保留)defaultMode: keep ## 设置默认保留拜访日志字段
names: ## 针对拜访日志特地字段特地配置保留模式
ClientUsername: drop
headers: ## 设置 Header 中字段是否保留
defaultMode: keep ## 设置默认保留 Header 中字段
names: ## 针对 Header 中特地字段特地配置保留模式
User-Agent: redact
Authorization: drop
Content-Type: keep
#tracing: ## 链路追踪配置, 反对 zipkin、datadog、jaeger、instana、haystack 等
# serviceName: ## 设置服务名称(在链路追踪端收集后显示的服务名)# zipkin: ## zipkin 配置
# sameSpan: true ## 是否启用 Zipkin SameSpan RPC 类型追踪形式
# id128Bit: true ## 是否启用 Zipkin 128bit 的跟踪 ID
# sampleRate: 0.1 ## 设置链路日志采样率(能够配置 0.0 到 1.0 之间的值)# httpEndpoint: http://localhost:9411/api/v2/spans ## 配置 Zipkin Server 端点
EOF
kubectl apply -f traefik-config.yaml
4. 设置节点 label 标签
Traefix 采纳 DaemonSet 形式构建,在须要装置的节点下面打上标签,这里在三个 work 节点都装置上了默认:
kubectl label nodes {sh-work-01,sh-work-02,sh-work-02} IngressProxy=true
kubectl get nodes --show-labels
留神:如果想删除标签,能够应用 kubectl label nodes k8s-node-03 IngressProxy- 命令。哈哈哈偶然须要去掉标签,不调度。
5、装置 Kubernetes Gateway CRD 资源
因为目前 Kubernetes 集群上默认没有装置 Service APIs,咱们须要提前装置 Gateway API 的 CRD 资源,须要确保在 Traefik 装置之前启用 Service APIs 资源。
kubectl apply -k "github.com/kubernetes-sigs/service-apis/config/crd?ref=v0.2.0"
不过因为 github 网络问题,根本无奈装置的。我是间接把 github 上包下载到本地采纳本地装置的形式装置
进入
进入 base 目录间接全副装置:
kubectl apply -f .
6. Kubernetes 部署 Traefik
其实我就能够疏忽 443 了 …. 因为我想在 slb 哦 对也叫 clb. 间接做限度。对外只保留 80 端口。
cat <<EOF > traefik-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace:kube-system
spec:
ports:
- name: web
port: 80
- name: websecure
port: 443
- name: admin
port: 8080
selector:
app: traefik
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
namespace:kube-system
name: traefik-ingress-controller
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
name: traefik
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 1
containers:
- image: ccr.ccs.tencentyun.com/XXXX/traefik:v2.4.3
name: traefik-ingress-lb
ports:
- name: web
containerPort: 80
hostPort: 80
- name: websecure
containerPort: 443
hostPort: 443
- name: admin
containerPort: 8080
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 1000m
memory: 1024Mi
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --configfile=/config/traefik.yaml
volumeMounts:
- mountPath: "/config"
name: "config"
readinessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
livenessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
volumes:
- name: config
configMap:
name: traefik-config
tolerations: ## 设置容忍所有污点,避免节点被设置污点
- operator: "Exists"
nodeSelector: ## 设置 node 筛选器,在特定 label 的节点上启动
IngressProxy: "true
EOF
kubectl apply -f traefik-deploy.yaml
kubectl get pods -n kube-system 验证
3. 配置路由规定,与腾讯云 clb 整合
1. slb 绑定 traefik http 端口
对于腾讯云负载平衡 slb or clb 能够参照文档 https://cloud.tencent.com/document/product/214 理解。过来应用 slb 用的 tcp 代理形式有一下起因:
- 过来的腾讯云 slb 不反对一个负载平衡挂载多个证书,集体不想启用多个 slb 绑定。
- 在 slb 下面配置域名比拟麻烦 ….. 没有再 traefik 配置文件外面写对我集体来说不便。
那我当初怎么就用 slb http https 代理形式了呢?
- 当然了 首先是能够挂载多个证书了
- 我在 slb 下面间接绑定了泛域名,前面的具体域名解析还是在我的 traefik 配置。然而我不必绑定证书了 ….
- http https 的形式我能够把日志间接写入他的 cos 对象存储和腾讯云本人的日志服务(感觉也是一个 kibana)能够间接剖析日志啊 …..
综上所述,来实现一下我集体的过程与思路
- 创立 slb .slb 绑定 work 节点 80 端口(这里我用的是负载平衡型,没有用传统型),没有问题吧?老老实实 ipv4 了没有启用 ipv6 这个就看集体具体需要吧。
应用了极度不要脸的形式 泛域名 …. 因为我罕用的也就这两个域名,具体的解析都还是我本人在 traefik 配置了。
对于证书 我这里可是扔好了 两个主二级域名,泛域名证书间接扔上了 ……
四个前面配置我都绑定了 80 交给 traefik 解决吧。权重我都设置的一样的,有其余需要的能够依据本人须要设置呢。
2. 配置路由规定
Traefik 利用曾经部署实现,并且和 slb 负载平衡集成也大抵实现了。然而想让内部拜访 Kubernetes 外部服务,还须要配置路由规定,下面部署 Traefik 时开启了 traefik dashboard
,这是 Traefik 提供的视图看板,所以,首先配置基于 http
的 Traefik Dashboard
路由规定,使内部可能拜访 Traefik Dashboard
。这里别离应用 CRD
、Ingress
和 Kubernetes Gateway API
三种形式进行演示,过来版本罕用的是 CRD 的形式。https 的形式我就疏忽了交给 slb 负载平衡层了。
1. CRD 形式
过来我集体部署利用都是 crd 形式,本人老把这种形式叫做 ingressroute 形式。
cat <<EOF> traefik-dashboard-route-http.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespaces: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(\`traefik.saynaihe.com\`)
kind: Rule
services:
- name: traefik
port: 8080
EOF
kubectl apply -f traefik-dashboard-route-http.yaml
对于 match: Host(\`traefik.saynaihe.com\`) 加本义符应该都能看明确了,不加本义符会是这样的
我貌似又忘了加 namespace 截图中,理论我可是加上了 … 老容易往事。哎,我不是两个泛域名吗?特意做了两个 ingressoute 做下测试
而后绑定本地 hosts 绑定 host
C:\Windows\System32\drivers\etc
遮挡的有点多 …. 然而 这就是两个都路由过去了啊
对于 https 能够疏忽了间接挂载在 slb 层了啊。而后 http 强制跳转 https 也能够在 slb 层下面配置了
流氓玩法强跳 …. 测试也是胜利的 ….
2. Ingress 形式
ingress 的形式根本就是 https://kubernetes.io/zh/docs/concepts/services-networking/ingress/ kubernetes 常见的 ingress 形式吧?
持续拿 dashboard 做演示
cat <<EOF> traefik-dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: traefik1.saynaihe.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: traefik
port:
number: 8080
EOF
kubectl apply -f traefik-dashboard-ingress.yaml
因为端口强制跳转了设置,间接 https 了哈哈哈验证实现
3、形式三:应用 Kubernetes Gateway API
对于Kubernetes Gateway API
能够通过CRD
形式创立路由规定
CRD 自定义资源强调一下
详情能够参考:[https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/](https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/)
- GatewayClass: GatewayClass 是根底构造提供程序定义的群集范畴的资源。此资源示意能够实例化的网关类。个别该资源是用于反对多个基础设施提供商用处的,这里咱们只部署一个即可。
- Gateway: Gateway 与基础设施配置的生命周期是 1:1。当用户创立网关时,GatewayClass 控制器会提供或配置一些负载平衡基础设施。
- HTTPRoute: HTTPRoute 是一种网关 API 类型,用于指定 HTTP 申请从网关侦听器到 API 对象(即服务)的路由行为。
1. 创立 GatewayClass
*#创立 GatewayClass 资源 kubernetes-gatewayclass.yaml 文件 *
参照:https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/#kind-gatewayclass
cat <<EOF> kubernetes-gatewayclass.yaml
kind: GatewayClass
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: traefik
spec:
# Controller is a domain/path string that indicates
# the controller that is managing Gateways of this class.
controller: traefik.io/gateway-controller
EOF
kubectl apply -f kubernetes-gatewayclass.yaml
2 配置 HTTP 路由规定(Traefik Dashboard 为例)
创立 Gateway 资源 http-gateway.yaml 文件
cat <<EOF> http-gateway.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
name: http-gateway
namespace: kube-system
spec:
gatewayClassName: traefik
listeners:
- protocol: HTTP
port: 80
routes:
kind: HTTPRoute
namespaces:
from: All
selector:
matchLabels:
app: traefik
EOF
kubectl apply -f http-gateway.yaml
创立 HTTPRoute 资源 traefik-httproute.yaml 文件
cat <<EOF> traefik-httproute.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
name: traefik-dashboard-httproute
namespace: kube-system
labels:
app: traefik
spec:
hostnames:
- "traefi2.saynaihe.com"
rules:
- matches:
- path:
type: Prefix
value: /
forwardTo:
- serviceName: traefik
port: 8080
weight: 1
EOF
kubectl apply -f traefik-httproute.yaml
这里就出问题了 …..,无法访问,认真看了下文档 https://doc.traefik.io/traefik/providers/kubernetes-gateway/
全副删除一次重新部署吧将 2.5 中版本变成 v0.1.0 就好了 …. 图就不上了根本步骤是一样的。
注:都没有做域名解析,本地绑定了 host。saynaihe.com 域名只是做演示。没有理论搞 …. 因为我没有做备案。当初不备案的根本绑上就被扫描到封了。用正式域名做的试验。另外养成的习惯用 CRD 习惯了 … 部署利用根本集体都用了 CRD 的形式 —ingressroute。ingress 的形式是更适宜从 ingress-nginx 迁徙到 traefik 应用了。至于 Kubernetes Gateway API 集体还是图个陈腐,没有整明确。v0.2.0 不能用 … 就演示下了.