前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Traefik 企业实战:TraefikService篇

Traefik 企业实战:TraefikService篇

作者头像
用户1107783
发布2023-09-11 11:22:56
3220
发布2023-09-11 11:22:56
举报
简介

traefik 的路由规则就可以实现 4 层和 7 层的基本负载均衡操作,使用 IngressRoute IngressRouteTCP IngressRouteUDP 资源即可。但是如果想要实现 加权轮询、流量复制 等高级操作,traefik抽象出了一个 TraefikService 资源。此时整体流量走向为:外部流量先通过 entryPoints 端口进入 traefik,然后由 IngressRoute/IngressRouteTCP/IngressRouteUDP 匹配后进入 TraefikService,在 TraefikService 这一层实现加权轮循和流量复制,最后将请求转发至kubernetes的service。

创建Demo应用

app-v1.yaml:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-v1
  template:
    metadata:
      labels:
        app: app-v1
    spec:
      containers:
        - name: app-v1
          image: nginx:latest
          lifecycle:
            postStart:
              exec:
                command:  ["/bin/sh", "-c", "echo Hello app-v1 > /usr/share/nginx/html/index.html"]
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 200m
              memory: 256Mi
    
---
apiVersion: v1
kind: Service
metadata:
  name: app-v1
spec:
  selector:
    app: app-v1
  ports:
    - name: http
      port: 80
      targetPort: 80
  type: ClusterIP

app-v2.yaml:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-v2
  template:
    metadata:
      labels:
        app: app-v2
    spec:
      containers:
        - name: app-v2
          image: nginx:latest
          lifecycle:
            postStart:
              exec:
                command:  ["/bin/sh", "-c", "echo Hello app-v2 > /usr/share/nginx/html/index.html"]
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 200m
              memory: 256Mi
    
---
apiVersion: v1
kind: Service
metadata:
  name: app-v2
spec:
  selector:
    app: app-v2
  ports:
    - name: http
      port: 80
      targetPort: 80
  type: ClusterIP

部署

代码语言:javascript
复制
[root@localhost traefik]# kubectl apply -f app-v1.yaml
deployment.apps/app-v1 created
service/app-v1 created
[root@localhost traefik]# kubectl apply -f app-v2.yaml 
deployment.apps/app-v2 created
service/app-v2 created
 
 
 
 
[root@localhost traefik]# kubectl get pod,svc                      
NAME                          READY   STATUS    RESTARTS   AGE
pod/app-v1-579dbbb754-nwtzw   1/1     Running   0          2m23s
pod/app-v2-7f7844f7b9-grsdk   1/1     Running   0          2m19s
 
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/app-v1       ClusterIP   10.100.10.94     <none>        80/TCP    2m23s
service/app-v2       ClusterIP   10.104.145.150   <none>        80/TCP    2m18s

灰度发布(加权轮询)

灰度发布也称为金丝雀发布,让一部分即将上线的服务发布到线上,观察是否达到上线要求,主要通过加权轮询的方式实现。创建 traefikService 和 inressRoute 资源,实现 wrr 加权轮询 app-traefikService-ingressroute-wrr.yaml:

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-ingressroute-wrr
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`traefikservice-wrr.kubesre.lc`)
    kind: Rule
    services:
    - name: wrr
      namespace: default
      kind: TraefikService
---
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: wrr
  namespace: default
spec:
  weighted:
    services:
      - name: app-v1 
        port: 80
        weight: 1          # 定义权重
        kind: Service      # 可选,默认就是 Service
      - name: app-v2
        port: 80    
        weight: 2

部署

代码语言:javascript
复制
[root@localhost traefik]# kubectl apply -f app-traefikService-ingressroute-wrr.yaml
ingressroute.traefik.containo.us/app-ingressroute-wrr created
traefikservice.traefik.containo.us/wrr created  
 
[root@localhost traefik]# kubectl get ingressroute
NAME                   AGE
app-ingressroute-wrr   6s
 [root@localhost traefik]# kubectl get TraefikService
NAME   AGE
wrr    3m42s

添加本地hosts解析

代码语言:javascript
复制
192.168.36.139 traefikservice-wrr.kubesre.lcc

测试结果如下:

代码语言:javascript
复制
[root@localhost traefik]# for i in {1..9}; do curl http://traefikservice-wrr.kubesre.lc && sleep 1; done             
Hello app-v1
Hello app-v2
Hello app-v2
Hello app-v1
Hello app-v2
Hello app-v2
Hello app-v1
Hello app-v2
Hello app-v2

会话保持(粘性会话)

当我们使用 traefik 的负载均衡时,默认情况下轮循多个 k8s 的 service 服务,如果用户对同一内容的多次请求,可能被转发到了不同的后端服务器。假设用户发出请求被分配至服务器 A,保存了一些信息在 session 中,该用户再次发送请求被分配到服务器 B,要用之前保存的信息,若服务器 A 和 B 之间没有 session 粘滞,那么服务器 B 就拿不到之前的信息,这样会导致一些问题。traefik 同样也支持粘性会话,可以让用户在一次会话周期内的所有请求始终转发到一台特定的后端服务器上。创建 traefikervie 和 ingressRoute,实现基于 cookie 的会话保持 app-traefikService-ingressroute-cokie.yaml:

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-ingressroute-cokie
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`traefikservice-cokie.kubesre.lc`)
    kind: Rule
    services:
    - name: cokie
      namespace: default
      kind: TraefikService
---
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: cokie
  namespace: default
spec:
  weighted:
    services:
      - name: app-v1
        port: 80
        weight: 1          # 定义权重
      - name: app-v2
        port: 80
        weight: 2
    sticky:                 # 开启粘性会话
      cookie:               # 基于cookie区分客户端     
        name: cookie   # 指定客户端请求时,包含的cookie名称

部署

代码语言:javascript
复制
[root@localhost traefik]# kubectl apply -f  app-traefikService-ingressroute-cokie.yaml   
ingressroute.traefik.containo.us/app-ingressroute-cokie created
traefikservice.traefik.containo.us/cokie created
 
[root@localhost traefik]# kubectl get ingressroute
NAME                     AGE
app-ingressroute-cokie   5s
[root@localhost traefik]# kubectl get TraefikService
NAME    AGE
cokie   8s

添加本地hosts解析

代码语言:javascript
复制
192.168.36.139 traefikservice-cokie.kubesre.lcc

客户端访问测试,携带 cookie

代码语言:javascript
复制
[root@localhost traefik]# for i in {1..5}; do curl -b "cookie=default-app-v1-80" http://traefikservice-cokie.kubesre.lc/; done
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
[root@localhost traefik]# for i in {1..5}; do curl -b "cookie=default-app-v2-80" http://traefikservice-cokie.kubesre.lc/; done
Hello app-v2
Hello app-v2
Hello app-v2
Hello app-v2
Hello app-v2

流量复制

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

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-ingressroute-copy
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`traefikservice-copy.kubesre.lc`)
    kind: Rule
    services:
    - name: copy
      namespace: default
      kind: TraefikService
---
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: copy
  namespace: default
spec:
  mirroring:
    name: app-v1       # 发送 100% 的请求到 app-v1
    port: 80
    mirrors:
      - name: app-v2   # 然后复制 10% 的请求到 app-v2
        port: 80
        percent: 10

部署

代码语言:javascript
复制
[root@localhost traefik]# kubectl apply -f app-traefikService-ingressroute-copy.yaml
ingressroute.traefik.containo.us/app-ingressroute-copy created
traefikservice.traefik.containo.us/copy created
 
[root@localhost traefik]# kubectl get ingressroute
NAME                     AGE
app-ingressroute-copy    7s
[root@localhost traefik]# kubectl get TraefikService
NAME    AGE
copy    13s

添加本地hosts解析

代码语言:javascript
复制
192.168.36.139 traefikservice-copy.kubesre.lc

测试结果如下:只能看到 app-v1的返回信息,

代码语言:javascript
复制
[root@localhost traefik]#  for i in {1..9}; do curl http://traefikservice-copy.kubesre.lc && sleep 1; done   
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1
Hello app-v1

查看app-v2的pod日志,发现会有10%的流量请求进来

代码语言:javascript
复制
[root@localhost traefik]# kubectl logs -f app-v2-7f7844f7b9-grsdk
...
10.244.0.5 - - [23/Aug/2023:02:54:36 +0000] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "10.244.0.1"
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生运维圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建Demo应用
  • 灰度发布(加权轮询)
  • 会话保持(粘性会话)
  • 流量复制
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档