跳转至

traefik 高级应用

在实际的生产环境,除了上线业务之外,还有更复杂的使用要求。 在 traefik 的高级用法之前,需要了解一个 TraefikService ,通过把 TraefikService 注册到 CRD 来实现更复杂的请求设置。

官网: https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#kind-traefikservice

TraefikService 目前能用于以下功能
    servers  load balancing.(负载均衡)
    services  Weighted Round Robin load balancing.(权重轮询)
    services  mirroring.(镜像)

1. 创建演示 deployment 资源

1. 创建 deployment 控制器类型应用

1. 创建 deployment 资源

1. 编写 001-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx-web1
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: v1
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: nginx-web-c
          image: nginx:latest
          lifecycle:
            postStart:
              exec:
                command:  ["/bin/sh", "-c", "echo svc1 > /usr/share/nginx/html/index.html"]
          ports:
            - containerPort: 80
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx-web2
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: v2
  template:
    metadata:
      labels:
        app: v2
    spec:
      containers:
        - name: nginx-web-c
          image: nginx:latest
          lifecycle:
            postStart:
              exec:
                command:  ["/bin/sh", "-c", "echo svc2 > /usr/share/nginx/html/index.html"]
          ports:
            - containerPort: 80
2. 创建 deployment 资源
kubectl apply -f 001-deployment.yaml
3. 查看 deployment 资源
kubectl get pods|grep nginx

2. 创建 service 资源

1. 编写 service 资源

1. 编写 002-deployment-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: v1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: v2
2. 创建 service 资源
kubectl apply -f 002-deployment-service.yaml
3. 查看 service 资源
> kubectl get svc | grep svc
svc1             ClusterIP   10.96.24.169    <none>        80/TCP     5m32s
svc2             ClusterIP   10.96.180.27    <none>        80/TCP     5m32s
...

> curl 10.96.24.169 && curl 10.96.180.27
svc1
svc2

一. 负载均衡

Traefik 的负载均衡功能通过负载均衡器来实现,支持多种负载均衡策略,包括轮询、随机、加权轮询和加权随机等。

当 Traefik 接收到请求时,根据路由规则将请求转发给相应的后端服务器。如果后端服务器有多个,Traefik 就需要使用负载均衡算法来选择一个服务器处理请求。具体流程如下:

Traefik 会先根据配置的路由规则,将请求匹配到对应的前端入口点 针对该入口点,Traefik 会获取所有与之关联的后端服务列表 根据负载均衡策略,在可用的后端服务器中选择一个服务 将请求转发给所选择的后端服务 如果后端服务出现故障或者不可用,Traefik 会将其从服务器列表中移除,并选择另外一个可用的服务器来处理请求。

目前来说,官方支持轮询和加权轮询策略。

image-20240420164610368

1. 创建 ingressroute

1. 创建资源 ingressroute 规则

1. 编写 003-loadbalancer-deploy-service-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressrouteweblb
  namespace: default

spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`tencent.k8s.huichengcheng.com`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: svc1
      port: 80
      namespace: default
    - name: svc2
      port: 80
      namespace: default
  tls:
    secretName: tencent-tls
2. 创建 ingressroute 资源
kubectl apply -f 003-loadbalancer-deploy-service-ingressroute.yaml
3. 查看 ingressroute 资源
kubectl describe ingressroute ingressrouteweblb

2. 访问验证

image-20240418170741447

二. 灰度发布

灰度发布也称为金丝雀发布,让一部分即将上线的服务发布到线上,观察是否达到上线要求,主要通过权重轮询的方式实现

image-20240418173514419

1. 创建 TraefikService

1. 创建 TraefikService

1. 编辑 a-wrr-01-traefik-service.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: wrr
  namespace: default

spec:
  weighted:
    services:
      - name: svc1    
        port: 80
        weight: 10          # 定义权重
        kind: Service      # 可选,默认就是 Service 
      - name: svc2
        port: 80     
        weight: 1
2. 创建 TraefikService 规则
kubectl apply -f a-wrr-01-traefik-service.yaml

2. 创建 ingressroute

需要注意的是现在我们配置的 Service 不再是直接的 Kubernetes 对象了,而是上面我们定义的 TraefikService 对象

1. 编写 ingressroute 规则

1. 编辑 a-wrr-02-traefik-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutewrr
  namespace: default

spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`tencent.k8s.huichengcheng.com`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: wrr
      namespace: default
      kind: TraefikService
  tls:
    secretName: tencent-tls
2. 创建 ingressroute 规则
kubectl apply -f a-wrr-02-traefik-ingressroute.yaml

3. 验证效果

image-20240418180509267

> for i in {1..11}; do curl https://tencent.k8s.huichengcheng.com:50000/; done
svc2
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1

三. 流量复制

流量复制,也称为镜像服务是指将请求的流量按规则复制一份发送给其它服务,并且会忽略这部分请求的响应,这个功能在做一些压测或者问题复现的时候很有用。

1. 指定流量来自己于 kubernetes service对象

1. 编写 TraefikService 规则

1. 编写 TraefikService 规则

1. 编写 b_mirror_from_001_service.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: mirror-from-service
  namespace: default

spec:
  mirroring:
    name: svc1       # 发送 100% 的请求到 Service "v1"
    port: 80
    mirrors:
      - name: svc2   # 然后复制 20% 的请求到 Servic "v2"
        port: 80
        percent: 20
2. 创建 TraefikService 规则
kubectl apply -f b_mirror_from_001_service.yaml

2. 编写 IngressRoute 规则

1. 编写 IngressRoute 规则

1. 编写 b_mirror_from_002_service_ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroute-mirror
  namespace: default

spec:
  entryPoints:
    - webwebsecure
  routes:
  - match: Host(`tencent.k8s.huichengcheng.com`) && PathPrefix(`/`) 
    kind: Rule
    services:
    - name: mirror-from-service         
      namespace: default
      kind: TraefikService
  tls:
    secretName: tencent-tls
2. 创建 IngressRoute 规则
 kubectl apply -f b_mirror_from_002_service_ingressroute.yaml 

3. 验证效果

image-20240418190240778

> for i in {1..10}; do curl https://tencent.k8s.huichengcheng.com:50000/; done
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1

2. 通过 traefikservice 导入流量

1. 编写 TraefikService 规则

1. 编写 TraefikService 规则

1. 编写 b_mirror_from_003_traefikservice.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: mirror-from-traefikservice
  namespace: default

spec:
  mirroring:
    name: mirror-from-service      #流量入口从 TraefikService 来
    kind: TraefikService
    mirrors:
    - name: svc2
      port: 80
      percent: 20
2. 创建 TraefikService 规则
kubectl apply -f b_mirror_from_003_traefikservice.yaml

2. 编写 IngressRoute 规则

1. 编写 IngressRoute 规则

1. 编辑 b_mirror_from_004_traefikservice-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroute-mirror-traefikservice
  namespace: default

spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`tencent.k8s.huichengcheng.com`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: mirror-from-traefikservice
      namespace: default
      kind: TraefikService
  tls:
    secretName: tencent-tls
2. 创建 IngressRoute 规则
kubectl apply -f b_mirror_from_004_traefikservice-ingressroute.yaml

5. 验证效果

image-20240418191553831

> for i in {1..11}; do curl https://tencent.k8s.huichengcheng.com:50000/; done
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1
svc1

3. 流量复制总结

发现所有的流量 100% 发送了 svc1 ,有 20% 的流量被复制到 svc2 ,且用户收到响应均来自 svc1 ,svc2 并没有响应,可通过查看 svc1 及 svc2 应用日志获取访问日志。

image-20240418194018682