前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >还不会Traefik?看这篇文章就够了!(文末送书)

还不会Traefik?看这篇文章就够了!(文末送书)

作者头像
没有故事的陈师傅
发布于 2021-11-12 07:19:07
发布于 2021-11-12 07:19:07
4.4K01
代码可运行
举报
文章被收录于专栏:运维开发故事运维开发故事
运行总次数:1
代码可运行

大家好,我是乔克。

提到Traefik,有些人可能并不熟悉,但是提到Nginx,应该都耳熟能详。

暂且我们把Traefik当成和Nginx差不多的一类软件,待读完整篇文章,你就会对Traefik有不一样的认识。

本文主要带大家对Traefik有一个全面的认识,我将从下面几个方面作介绍。

本文基于Traefik 2.5.3进行介绍。

什么是Traefik

Traefik是一个开源的边缘路由网关,它简单易用并且功能全面。官方【1】的介绍是:Traefik is an [open-source](https://github.com/traefik/traefik) _Edge Router_ that makes publishing your services a fun and easy experience.

Traefik原生支持多种集群,如Kubernetes、Docker、Docker Swarm、AWS、Mesos、Marathon等;并且可以同时处理许多集群。

image.png

Traefik的核心概念及能力

Traefik是一个边缘路由器,它会拦截外部的请求并根据逻辑规则选择不同的操作方式,这些规则决定着这些请求到底该如何处理。Traefik提供自动发现能力,会实时检测服务,并自动更新路由规则。

从上图可知,请求首先会连接到entrypoints,然后分析这些请求是否与定义的rules匹配,如果匹配,则会通过一系列middlewares,再到对应的services上。

这就涉及到以下几个重要的核心组件。

  • Providers
  • Entrypoints
  • Routers
  • Services
  • Middlewares

Providers

Providers是基础组件,Traefik的配置发现是通过它来实现的,它可以是协调器,容器引擎,云提供商或者键值存储。

Traefik通过查询ProvidersAPI来查询路由的相关信息,一旦检测到变化,就会动态的更新路由。

Entrypoints

EntrypointsTraefik的网络入口,它定义接收请求的接口,以及是否监听TCP或者UDP

Routers

Routers主要用于分析请求,并负责将这些请求连接到对应的服务上去,在这个过程中,Routers还可以使用Middlewares来更新请求,比如在把请求发到服务之前添加一些Headers。

Services

Services负责配置如何到达最终将处理传入请求的实际服务。

Middlewares

Middlewares用来修改请求或者根据请求来做出一些判断(authentication, rate limiting, headers, ...),中间件被附件到路由上,是一种在请求发送到你的服务之前(或者在服务的响应发送到客户端之前)调整请求的一种方法。

部署Traefik

Traefik的部署方式有多种,这里主要采用Helm方式进行部署管理。

Helm部署

环境:kubernetes: 1.22.3 helm: 3.7.1

1、添加traefik helm仓库
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ helm repo add traefik https://helm.traefik.io/traefik
$ helm repo update
2、将traefik包下载到本地进行管理
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ helm  search repo traefik
NAME            CHART VERSION APP VERSION DESCRIPTION                                  
traefik/traefik 10.6.0        2.5.3       A Traefik based Kubernetes ingress controller
$ helm pull traefik/traefik
3、部署Traefik

默认的value.yaml[2]配置文件配置比较多,可能需要花一定的时间去梳理,不过根据相关的注释还是可以很快的理解。

这里自定义一个配置文件my-value.yaml,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
service:
  type: NodePort 

ingressRoute:
  dashboard:
    enabled: false
ports:
  traefik:
    port: 9000
    expose: true
  web:
    port: 8000
    expose: true
  websecure:
    port: 8443
    expose: true
persistence:
  enabled: true
  name: data
  accessMode: ReadWriteOnce
  size: 5G
  storageClass: "openebs-hostpath"
  path: /data
additionalArguments:
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"

进行部署,命令如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ kubectl create ns traefik-ingress
$ helm install traefik -n traefik-ingress -f my-value.yaml .

这里不是使用的是默认的value.yaml[2]配置文件。

然后可以看到部署结果,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# kubectl get all -n traefik-ingress 
NAME                           READY   STATUS    RESTARTS   AGE
pod/traefik-77ff894bb5-qqszd   1/1     Running   0          6m26s

NAME              TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                     AGE
service/traefik   NodePort   10.108.170.22   <none>        9000:32271/TCP,80:31728/TCP,443:30358/TCP   6m26s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/traefik   1/1     1            1           6m26s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/traefik-77ff894bb5   1         1         1       6m26s

然后可以通过NodePort访问Dashboard页面,如下:

使用Traefik

创建第一个路由规则

我们上面访问Dashboard是采用的NodePort的方式,既然已经把Traefik部署好了,为什么不使用路由网关的方式呢?

下面我们就来创建第一个路由网关来访问Dashboard

Traefik创建路由规则有多种方式,比如:

  • 原生Ingress写法
  • 使用CRD IngressRoute方式
  • 使用GatewayAPI的方式

这里暂时介绍前面两种方式,关于GatewayAPI的方式在后续进行介绍。

原生Ingress路由规则

原生Ingress的路由规则,写法就比较简单,如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cat traefik-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traefik-dashboard-ingress
  annotations:
    kubernetes.io/ingress.class: traefik  
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
  - host: traefik-web.coolops.cn 
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: traefik
            port:
              number: 9000

创建路由规则,命令如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# kubectl apply -f traefik-ingress.yaml -n traefik-ingress 
ingress.networking.k8s.io/traefik-dashboard-ingress created

现在就可以通过域名http://traefik-web.coolops.cn:31728/dashboard/#/ 进行访问了(31728是80端口的映射端口),如下:

使用CRD方式配置路由规则

在早期版本,Traefik仅提供kubernetes ingress方式配置路由规则,社区认为采用开发一个自定义CRD的类型能够更好的提供Kubernetes的访问配置【3】。

IngressRoute的配置方式也比较简单,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cat traefik-ingressRoute.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`traefik-web2.coolops.cn`)
    kind: Rule
    services:
      - name: traefik
        port: 9000 

部署命令如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# kubectl apply -f traefik-ingressRoute.yaml -n traefik-ingress 
ingressroute.traefik.containo.us/traefik-dashboard-route created

然后就可以通过http://traefik-web2.coolops.cn:31728/dashboard/#/ 进行访问了。

暴露HTTP服务

首先,部署一个简单的whoami[4]应用,YAML文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
apiVersion: v1
kind: Pod
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  containers:
    - name: whoami
      image: traefik/whoami:latest
      ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: whoami
  type: ClusterIP

部署成功后,创建一个路由规则,使外部可以访问。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cat ingressroute.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`whoami.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80 

创建过后,就可以进行访问了,如下:

暴露HTTPS服务

上面的whoami应用,是通过HTTP进行访问的,如果要通过HTTPS进行访问,应该如何配置呢?

Traefik支持HTTPS和TLS,对于证书可以选择自有证书,也可以使用Let's Encrypt【5】自动生成证书。这里会分别介绍这两种方式。

自有证书配置HTTPS

现在公司基本都会自己购买更安全的证书,那对于自有证书配置HTTPS就会使用更加频繁,这里主要介绍这种配置方式。

1、申请或者购买证书

我这里是在腾讯云申请的免费证书。

然后下载对应的证书,并上传到服务器上。

2、将证书文件保存为Secret
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# kubectl create secret tls whoami-tls --cert=1_whoami.coolops.cn_bundle.crt --key=2_whoami.coolops.cn.key
3、创建IngressRoute对象,使其可以通过TLS访问
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cat ingressroutetls.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route-tls
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`whoami.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80 
  tls:
    secretName: whoami-tls

创建完成后,就可以通过https://whoami.coolops.cn:30358/ 进行访问了(30358是443映射出来的端口)。

自动生成HTTPS证书

Traefik除了使用自有证书外,还支持Let's Encrypt自动生成证书【6】。

要使用Let's Encrypt自动生成证书,需要使用ACME。需要在静态配置中定义 "证书解析器",Traefik负责从ACME服务器中检索证书。

然后,每个 "路由器 "被配置为启用TLS,并通过tls.certresolver配置选项与一个证书解析器关联。

TraefikACME验证方式主要有以下三种:

  • tlsChallenge
  • httpChallenge
  • dnsChallenge

如果使用tlsChallenge,则要求Let's Encrypt到 Traefik 443 端口必须是可达的。如果使用httpChallenge,则要求Let's Encrypt到 Traefik 80端口必须是可达的。如果使用dnsChallenge,则需要对应的providers[7]。

但是我们上面部署Traefik的时候并没有把80和443端口暴露出来,要测试tlsChallengehttpChallenge的话就必须暴露,下面我们更改一下my-value.yaml,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
service:
  type: NodePort 

ingressRoute:
  dashboard:
    enabled: false
ports:
  traefik:
    port: 9000
    expose: true
  web:
    port: 8000
    hostPort: 80
    expose: true
  websecure:
    port: 8443
    hostPort: 443
    expose: true
persistence:
  enabled: true
  name: data
  accessMode: ReadWriteOnce
  size: 5G
  storageClass: "openebs-hostpath"
  path: /data
additionalArguments:
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"

然后重新更新一下Traefik,命令如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
helm upgrade traefik -n traefik-ingress -f my-value.yaml .

现在我们就可以直接通过80或443端口进行访问了。

1、tlsChallenge

上面已经介绍过,要使用tlsChallenge,必须能访问入口的443端口,现在我们入口已经放开,接下来就修改Traefikmy-value.yaml配置,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
......
deployment:
  initContainers:
    - name: volume-permissions
      image: busybox:1.31.1
      command: ["sh", "-c", "chmod -Rv 600 /data/*"]
      volumeMounts:
        - name: data
          mountPath: /data
additionalArguments:
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--certificatesresolvers.coolops.acme.email=coolops@163.com"
  - "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
  - "--certificatesresolvers.coolops.acme.tlschallenge=true"

PS:这里需要将/data目录权限给更改一下,默认是0660,权限太大是不允许的。

然后我们创建一个ingressRoute,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cat ingressrouteautotls.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route-auto-tls
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`whoami3.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80 
  tls:
    certResolver: coolops

这时候我们访问https://whoami3.coolops.cn是可以正常使用证书的,如下:

2、httpChallenge

下面再使用httpChallenge进行测试,修改my-value.yaml配置文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
......
deployment:
  initContainers:
    - name: volume-permissions
      image: busybox:1.31.1
      command: ["sh", "-c", "chmod -Rv 600 /data/*"]
      volumeMounts:
        - name: data
          mountPath: /data
additionalArguments:
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--certificatesresolvers.coolops.acme.email=coolops@163.com"
  - "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
  - "--certificatesresolvers.coolops.acme.httpchallenge=true"
  - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web"

更新Traefik过后,然后再创建一个ingressRoute进行测试,YAML文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route-auto-tls-http
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`whoami4.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80
  tls:
    certResolver: coolops

然后使用https://whoami4.coolops.cn,效果如下:

3、dnsChallenge

dnsChallenge在使用上相对比较麻烦,因为需要配置对应的provider,不过它可以生成通配符证书,这里以阿里云DNS【8】为例。

使用阿里DNS的前提是您的域名是在阿里云上面,不然在签署证书的时候会报错,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Unable to obtain ACME certificate for domains \"*.coolops.cn\" : unable to generate a certificate for the domains [*.coolops.cn]: error: one or more domains had a problem:\n[*.coolops.cn] [*.coolops.cn] acme: error presenting token: alicloud: zone coolops.cn. not found in AliDNS for domain coolops.cn\n" providerName=coolops.acme

使用阿里云的 DNS 校验需要配置3个环境变量:ALICLOUD_ACCESS_KEYALICLOUD_SECRET_KEYALICLOUD_REGION_ID,分别对应我们平时开发阿里云应用的时候的密钥,可以登录阿里云后台获取,由于这是比较私密的信息,所以我们用 Secret 对象来创建:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ kubectl create secret generic traefik-alidns --from-literal=ALICLOUD_ACCESS_KEY=<aliyun ak> --from-literal=ALICLOUD_SECRET_KEY=<aliyun sk>--from-literal=ALICLOUD_REGION_ID=cn-beijing -n traefik-ingress

修改Traefik的my-value.yaml,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
......
additionalArguments:
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--certificatesresolvers.coolops.acme.email=coolops@163.com"
  - "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
  - "--certificatesresolvers.coolops.acme.dnschallenge=true"
  - "--certificatesResolvers.coolops.acme.dnsChallenge.provider=alidns"
envFrom:
  - secretRef: 
      name: traefik-alidns

更新Traefik过后,然后再创建一个ingressRoute进行测试,YAML文件如下(由于coolops.cn不在阿里云上,所以换了一个域名):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route-auto-tls-dns
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`whoami6.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80 
  tls:
    certResolver: coolops 
    domains:
    - main: "*.coolops.cn"

然后访问域名后,就可以看到证书签署 成功,如下:

中间件的使用

在介绍Traefik的核心概念的时候有提到一个请求匹配Rules后,会经过一系列的Middleware,再到具体的Services上。这个Middleware是什么呢?

image.png

MiddlewareTraefik 2.0之后新增的功能,用户可以根据不通的需求来选择不同的Middleware来满足服务,提高了定制化的能力。

Traefik内置了很多不同功能的Middleware,主要是针对HTTP和TCP,HTTP占大部分[9],这里挑选几个比较常用的进行演示。

强制跳转HTTPS

强制跳转HTTPS是经常会配置的功能,这里还是以上没的whoami应用为例。

1、创建一个HTTPS的ingressRoute
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-route-auto-tls
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`whoami3.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80 
  tls:
    certResolver: coolops
2、定义一个跳转HTTPS的中间件

这里会用到RedirectScheme的内置中间件,配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-https-middleware
spec:
  redirectScheme:
    scheme: https
3、定义一个HTTP的ingressRoute,并使用Middleware
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami3-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`whoami3.coolops.cn`)
    kind: Rule
    services:
      - name: whoami
        port: 80
    middlewares:
    - name: redirect-https-middleware

然后访问http://whoami3.coolops.cn就会被强制跳转到https://whoami3.coolops.cn

去除请求路径前缀

有时候会遇到这么一个需求:

  • 只有一个域名
  • 相通过这个域名访问不同的应用

这种需求是非常常见的,在NGINX中,我们可以配置多个Location来定制规则,使用Traefik也可以这么做。

但是定制不同的前缀后,由于应用本身并没有这些前缀,导致请求返回404,这时候我们就需要对请求的path进行处理,还是以whoami应用为例。

1、创建一个带前缀的ingressRoute
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami7-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`whoami7.coolops.cn`) && PathPrefix('/coolops')
    kind: Rule
    services:
      - name: whoami
        port: 80 

我们现在访问是会返回404状态的。

2、定义去除前缀的中间件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: prefix-coolops-url-middleware
spec:
  stripPrefix:
    prefixes:
      - /coolops
3、修改上面的ingressRoute,应用中间件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami7-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`whoami7.coolops.cn`) && PathPrefix('/coolops')
    kind: Rule
    services:
      - name: whoami
        port: 80
    middlewares:
    - name: prefix-coolops-url-middleware

然后就可以正常访问了。

添加IP白名单

在工作中,有一些URL并不希望对外暴露,比如prometheus、grafana等的url,这时候我们希望通过白名单IP来达到需求,就可以使用Traefik中的ipWhiteList中间件来完成。

1、定义白名单IP的中间件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: ip-white-list-middleware
spec:
  ipWhiteList:
    sourceRange:
      - 127.0.0.1/32
      - 192.168.100.180

然后将中间件应用到对应的Rules上,就可以完成白名单功能。

除了上面的功能,Traefik内置Middleware还支持很多其他功能,比如限流、认证鉴权等,可以通过引用【9】进行查看。

暴露TCP服务

Traefik 2.0支持暴露TCP,这里以Redis为例。

1、部署一个Redis服务
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:5.0.14
        ports:
        - containerPort: 6379
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
2、暴露Redis端口

暴露TCP端口使用的是SNI【10】,而SNI又是依赖TLS的,所以我们需要配置证书才行,但是如果没有证书的话,我们可以使用通配符*进行配置。

(1)、添加一个redis的entrypoints

修改Traefik的部署文件my-value.yaml,添加如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ports:
  traefik:
    port: 9000
    expose: true
  web:
    port: 8000
    hostPort: 80
    expose: true
  websecure:
    port: 8443
    hostPort: 443
    expose: true
  redis:
    port: 6379
    containerPort: 6379
    hostPort: 6379
additionalArguments:
  - "--entryPoints.redis.address=:6379"
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--certificatesresolvers.coolops.acme.email=coolops@163.com"
  - "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
  - "--certificatesresolvers.coolops.acme.httpchallenge=true"
  - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web"

在启动参数中添加--entryPoints.redis.address=:6379用来指定entrypoint。

(2)、创建ingressRoute进行对外暴露
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis-traefik-tcp
spec:
  entryPoints:
    - redis
  routes:
  - match: HostSNI(`*`)
    services:
    - name: redis
      port: 6379

然后可以使用客户端工具进行Redis的操作了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# redis-cli -h redis.coolops.cn 
redis.coolops.cn:6379> set  a b
OK
redis.coolops.cn:6379> get a
"b"
redis.coolops.cn:6379> 

灰度发布

Traefik2.0 以后的一个更强大的功能就是灰度发布,灰度发布我们有时候也会称为金丝雀发布(Canary),主要就是让一部分测试的服务也参与到线上去,经过测试观察看是否符号上线要求。

假设一个应用现在运行着V1版本,新的V2版本需要上线,这时候我们需要在集群中部署好V2版本,然后通过Traefik提供的带权重的轮询(WRR)来实现该功能。

1、部署appv1、appv2应用

appv1.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: appv1
spec:
  selector:
    matchLabels:
      app: appv1
  template:
    metadata:
      labels:
        use: test
        app: appv1
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        lifecycle:
          postStart:
            exec:
              command:  ["/bin/sh", "-c", "echo Hello v1 > /usr/share/nginx/html/index.html"]
        ports:
        - containerPort: 80
          name: portv1

---

apiVersion: v1
kind: Service
metadata:
  name: appv1
spec:
  selector:
    app: appv1
  ports:
  - name: http
    port: 80
    targetPort: portv1

appv2.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: appv2
spec:
  selector:
    matchLabels:
      app: appv2
  template:
    metadata:
      labels:
        use: test
        app: appv2
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        lifecycle:
          postStart:
            exec:
              command:  ["/bin/sh", "-c", "echo Hello v2 > /usr/share/nginx/html/index.html"]
        ports:
        - containerPort: 80
          name: portv2

---

apiVersion: v1
kind: Service
metadata:
  name: appv2
spec:
  selector:
    app: appv2
  ports:
  - name: http
    port: 80
    targetPort: portv2
2、创建TraefikService

在 Traefik2.1以后新增了一个 TraefikService的 CRD 资源,我们可以直接利用这个对象来配置 WRR

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: app-wrr
spec:
  weighted:
    services:
      - name: appv1
        weight: 3
        port: 80
        kind: Service
      - name: appv2
        weight: 1
        port: 80
        kind: Service
3、创建ingressRoute
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-ingressroute-canary 
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`app.coolops.cn`)
    kind: Rule
    services:
    - name: app-wrr
      kind: TraefikService

注意:这里配置的不是Service类型,而是TraefikService

然后就可以通过访问http://app.coolops.cn来校验结果。

V2测试没问题后,就可以将流量全切到V2了。

流量复制

Traefik 2.0之后还引入了镜像服务[11],它可以将请求的流量按规则复制一份发送给其他服务,并且会忽略这部分请求的响应。

这个功能在做一些压测或者问题复现的时候还是很有用。

这里依然以上没的appv1和appv2为例进行简单的演示。

1、创建TraefikService,定义复制规则
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: app-mirror
spec:
  mirroring:
    name: appv1
    port: 80
    mirrors:
    - name: appv2
      percent: 50
      port: 80

上面定义的意思是将请求到appv1的50%请求复制到appv2。

2、创建ingressRoute,进行效果演示
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-ingressroute-mirror
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`mirror.coolops.cn`)
    kind: Rule
    services:
    - name: app-mirror
      kind: TraefikService

然后进行测试,效果如下:

发了4次请求,appv1可以正常接收4次请求,appv2可以收到2次请求,收到的响应是appv1的,并没有appv2的响应。

Kubernetes Gateway API

我们在上面创建路由规则要么使用ingress,要么使用ingressRoute,其实在Traefik 2.4以后支持Kubernetes Gateway API[12]提供的CRD方式创建路由规则。

什么是Gateway API?

Gateway API【13】是一个由SIG-NETWORK社区管理的开源项目。它是Kubernetes中服务网络模型的资源集合。这些资源(GatewayClass、Gateway、HTTPRoute、TCPRoute、Service)旨在通过表达式的、可扩展的和面向角色的接口来发展Kubernetes服务网络,这些接口由许多供应商实现,并得到了广泛的行业支持。

image.png

  • GatewayClass:GatewayClass 是基础结构提供程序定义的群集范围的资源。此资源表示可以实例化的网关类。一般该资源是用于支持多个基础设施提供商用途的,这里我们只部署一个即可。
  • Gateway:Gateway 与基础设施配置的生命周期是 1:1。当用户创建网关时,GatewayClass 控制器会提供或配置一些负载平衡基础设施。
  • HTTPRoute:HTTPRoute 是一种网关 API 类型,用于指定 HTTP 请求从网关侦听器到 API 对象(即服务)的路由行为。
使用Gateway API
1、安装Gateway API 的CRD

Traefik Gateway provider 仅支持 v0.3.0 (v1alpha1).

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.3.0" \
| kubectl apply -f -
2、创建rbac,给traefik授权
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gateway-role
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.x-k8s.io
    resources:
      - gatewayclasses
      - gateways
      - httproutes
      - tcproutes
      - tlsroutes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.x-k8s.io
    resources:
      - gatewayclasses/status
      - gateways/status
      - httproutes/status
      - tcproutes/status
      - tlsroutes/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gateway-controller

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: gateway-role
subjects:
  - kind: ServiceAccount
    name: traefik
    namespace: traefik-ingress 
2、Traefik开启gateway api支持

修改my-value.yaml 文件,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
......
additionalArguments:
  - "--entryPoints.redis.address=:6379"
  - "--serversTransport.insecureSkipVerify=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--certificatesresolvers.coolops.acme.email=coolops@163.com"
  - "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
  - "--certificatesresolvers.coolops.acme.httpchallenge=true"
  - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web"
  - "--experimental.kubernetesgateway"
  - "--providers.kubernetesgateway"

更新Traefik,命令如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
helm upgrade traefik -n traefik-ingress -f my-value.yaml .
4、通过Gateway api的方式暴露traefik dashboard应用
(1)、创建GatewayClass
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: networking.x-k8s.io/v1alpha1
kind: GatewayClass
metadata:
  name: traefik
spec:
  controller: traefik.io/gateway-controller
(2)、创建gateway
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata: 
  name: http-gateway
  namespace: traefik-ingress 
spec: 
  gatewayClassName: traefik
  listeners: 
    - protocol: HTTP
      port: 8000 
      routes: 
        kind: HTTPRoute
        namespaces:
          from: All
        selector:
          matchLabels:
            app: traefik
(3)、创建HTTPRoute
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: whoami-gateway-api-route 
  namespace: traefik-ingress
  labels:
    app: traefik
spec:
  hostnames:
    - "traefik1.coolops.cn"
  rules:
    - matches:
        - path:
            type: Prefix
            value: /
      forwardTo:
        - serviceName: traefik 
          port: 9000
          weight: 1
(4)、现在就可以直接在浏览器访问了

image.png

GatewayClass在集群中可以只创建一个,然后GatewayHTTPRoute是需要对应的。

比如我这里要暴露default命名空间下的whoami应用,YAML就应该如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata: 
  name: http-gateway
spec: 
  gatewayClassName: traefik
  listeners: 
    - protocol: HTTP
      port: 8000 
      routes: 
        kind: HTTPRoute
        namespaces:
          from: All
        selector:
          matchLabels:
            app: whoami
---
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: whoami-gateway-api-route 
  labels:
    app: whoami 
spec:
  hostnames:
    - "whoami8.coolops.cn"
  rules:
    - matches:
        - path:
            type: Prefix
            value: /
      forwardTo:
        - serviceName: whoami 
          port: 80
          weight: 1

最后

Traefik是一个功能比较强大的边缘网关,基本能满足绝大部分的场景需求,而且还有Mesh等工具,比较好用,有兴趣的朋友可以到官网[14]进行学习,也欢迎交流。

最后,求关注。如果你还想看更多优质原创文章,欢迎关注我们的公众号「运维开发故事」。

如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

你还可以把我的公众号设为「星标」,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。


我是 乔克,《运维开发故事》公众号团队中的一员,一线运维农民工,云原生实践者,这里不仅有硬核的技术干货,还有我们对技术的思考和感悟,欢迎关注我们的公众号,期待和你一起成长!

引用

[1] https://doc.traefik.io/traefik/ [2] https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml [3] https://doc.traefik.io/traefik/providers/kubernetes-crd/ [4] https://github.com/traefik/whoami [5] https://letsencrypt.org/zh-cn/ [6] https://doc.traefik.io/traefik/https/acme/ [7] https://doc.traefik.io/traefik/https/acme/#tlschallenge [8] https://go-acme.github.io/lego/dns/alidns/ [9] https://doc.traefik.io/traefik/middlewares/http/overview/ [10] https://doc.traefik.io/traefik/routing/routers/#configuring-tcp-routers [11] https://doc.traefik.io/traefik/routing/services/#mirroring-service [12] https://doc.traefik.io/traefik/providers/kubernetes-gateway/ [13] https://gateway-api.sigs.k8s.io/ [14] https://traefik.io/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维开发故事 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
TKE之Traefik最佳实践
k8s的接入层有很多种,常见的7层负载均衡有nginx-ingress、traefik、kong等,还有每个云厂商为了对接自己的负载均衡产品所开发的控制器,tke集群现在默认是clb类型ingress,也支持组件安装nginx-ingress到集群内使用,其他类型的网关,需要自己在集群内部署才行,今天我们讲讲traefik在tke上的部署安装和一些使用实践。
聂伟星
2022/03/18
2.5K0
# 一篇文章让你搞懂如何在K8s 里使用 Traefik 2.0作为Ingress Controller(上)
了解K8s的同学应该都知道,如果想要把应用暴露到公网上供外部访问,那么不可避免的会接触到Ingress资源。本文以Traefik为例,让大家对Ingress和Traefik的使用有一定的了解。
100000798482
2020/02/13
1.2K0
# 一篇文章让你搞懂如何在K8s 里使用 Traefik 2.0作为Ingress Controller(上)
Traefik 企业实战:路由规则篇
首先,当部署完后启动 Traefik 时,定义了入口点(端口号和对应的端口名称),然后 Kubernetes 集群外部就可以通过访问 Traefik 服务器地址和配置的入口点对 Traefik 服务进行访问,在访问时一般会带上 “域名” + “入口点端口”,然后 Traefik 会根据域名和入口点端口在 Traefik 路由规则表中进行匹配,如果匹配成功,则将流量发送到 Kubernetes 内部应用中与外界进行交互。这里面的域名与入口点与对应后台服务关联的规则,即是 Traefik 路由规则。Traefik 创建路由规则有多种方式:
用户1107783
2023/09/11
5560
Traefik 企业实战:路由规则篇
Traefik 企业实战:TraefikService篇
traefik 的路由规则就可以实现 4 层和 7 层的基本负载均衡操作,使用 IngressRoute IngressRouteTCP IngressRouteUDP 资源即可。但是如果想要实现 加权轮询、流量复制 等高级操作,traefik抽象出了一个 TraefikService 资源。此时整体流量走向为:外部流量先通过 entryPoints 端口进入 traefik,然后由 IngressRoute/IngressRouteTCP/IngressRouteUDP 匹配后进入 TraefikService,在 TraefikService 这一层实现加权轮循和流量复制,最后将请求转发至kubernetes的service。
用户1107783
2023/09/11
4970
Traefik 企业实战:TraefikService篇
Traefik2.3.x 使用大全(更新版)
Traefik 是一个开源的可以使服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理。
我是阳明
2021/01/04
5.4K0
Traefik2.3.x 使用大全(更新版)
使用 Traefik 中间件处理 Log4J 漏洞
Traefik 的中间件是最让人喜欢的一个功能,为了能够扩展中间件,Traefik 官方还推出了 Pilot(https://pilot.traefik.io/) 这样的中间件 SaaS 服务,和 Traefik 深度集成,我们可以非常方便的使用平台上提供的各种中间件,在 Dashboard 上就可以无缝进行对接:
我是阳明
2021/12/27
7360
使用 Traefik 中间件处理 Log4J 漏洞
Traefik2.2从坑出发
Traefik 2.2新增的功能如下: 1. 支持了udp 2. traefik2.2 支持使用K/V存储做为动态配置的源,分别是 consul, etcd, Redis, zookeeper 3. 能够使用kubernetes CRD自定义资源定义UDP负载平衡 IngressRouteUDP。 4. 能够使用 rancher, consul catalog, docker和 marathon中的标签定义UDP的负载平衡 5. 增加了对ingress注解的主持 6. 将TLS存储功能 TLSStores添加到Kubernetes CRD中,使kubernetes用户无需使用配置文件和安装证书即可提供默认证书。 7. 在日志中增加了http的请求方式,是http还是https 8. 因为TLS的配置可能会影响CPU的使用率,因此增加了 TLS version和 TLS cipher使用的指标信息 9. 当前的WRR算法对于权重不平衡端点存在严重的偏差问题,将EDF调度算法用于WeightedRoundRobin, Envoy也是使用了 EOF调度算法 10. 支持请求主体用于流量镜像 11. 增加了 ElasticAPM作为traefik的tracing系统。 12. Traefik的Dashboard增加了UDP的页面 13. Traefik也增加了黑暗主题
极客运维圈
2020/06/01
2.9K0
Traefik2.2从坑出发
自定义 Traefik(本地)插件
Traefik 已经默认实现了很多中间件,可以满足大部分我们日常的需求,但是在实际工作中,用户仍然还是有自定义中间件的需求,为解决这个问题,官方推出了一个 Traefik Pilot[1] 的功能了,此外在 Traefik v2.5 版本还推出了支持本地私有插件的功能。
我是阳明
2021/12/30
1.2K0
自定义 Traefik(本地)插件
Kubernetes (K8S)中Traefik的服务发布
traefik 的路由规则就可以实现 4 层和 7 层的基本负载均衡操作,使用 IngressRoute IngressRouteTCP IngressRouteUDP 资源即可。但是如果想要实现 加权轮询、流量复制 等高级操作,traefik抽象出了一个 TraefikService 资源。此时整体流量走向为:外部流量先通过 entryPoints 端口进入 traefik,然后由 IngressRoute/IngressRouteTCP/IngressRouteUDP 匹配后进入 TraefikService,在 TraefikService 这一层实现加权轮循和流量复制,最后将请求转发至kubernetes的service。
王先森sec
2023/10/17
3490
Kubernetes (K8S)中Traefik的服务发布
附021.Traefik-ingress部署及使用
[root@master01 ingress]# helm repo add traefik https://containous.github.io/traefik-helm-chart
木二
2020/06/04
1.3K0
Kubernetes 集群部署 Ingress Traefik
Traefik 是一个开源的可以使服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理。
高楼Zee
2021/12/15
2K0
Kubernetes 集群部署 Ingress Traefik
Kubernetes (K8S)中Traefik中间件(Middleware)
Traefik Middlewares 是一个处于路由和后端服务之前的中间件,在外部流量进入 Traefik,且路由规则匹配成功后,将流量发送到对应的后端服务前,先将其发给中间件进行一系列处理(类似于过滤器链 Filter,进行一系列处理),例如,添加 Header 头信息、鉴权、流量转发、处理访问路径前缀、IP 白名单等等,经过一个或者多个中间件处理完成后,再发送给后端服务,这个就是中间件的作用。 Traefik内置了很多不同功能的Middleware,主要是针对HTTP和TCP,这里挑选几个比较常用的进行演示。
王先森sec
2023/10/17
1.1K0
Kubernetes (K8S)中Traefik中间件(Middleware)
Kubernetes生态Ingress组件Traefik v2.0浅析
上一篇文章简单介绍了下Kubernetes生态的几个组件,这篇文章重点讲解下其中的Traefik组件,Traefik组件类似与Nginx,可以为整个集群做服务暴露、域名控制等等的作用,目前Traefik主要分为两个版本,v1.x与v2.x,这两个版本之间差距较大,让人感觉在使用不同的软件。本篇文章是以v2.x版本为基础来演示的,相关脚本代码都在Github仓库https://github.com/lateautumn4lin/KubernetesResearch里面,大家使用的时候可以切换目录到ClusterEcology/initTraefik下面。
云爬虫技术研究笔记
2020/02/19
8460
Kubernetes的Ingress控制器比较(Traefik)
Traefik支持动态配置和静态配置,因此在实践的过程中,我们将Traefik运行的端口配置在静态配置文件中,Traefik因为功能的丰富性得到很多的人的青睐,尤其是它的弹性功能,从大量的技术博客上观察来看,现在很多人在使用并且很稳定,对于ingress-nginx来说,能动态配置的Traefik显然略胜一筹,这是一个非常大且好的升级。更多的功能点可以在官方文档(https://docs.traefik.io/)详细查阅:
公众号: 云原生生态圈
2021/11/15
2K0
Kubernetes的Ingress控制器比较(Traefik)
使用traefik暴露常用kubernetes服务的方法
其中 k8s dashboard 的服务比较特殊,因为原来就是https,需要配置 insecureSkipVerify。
tanmx
2023/10/18
4250
使用traefik暴露常用kubernetes服务的方法
Traefik 企业实战:中间件(Middleware)篇
Traefik Middlewares 是一个处于路由和后端服务之前的中间件,在外部流量进入 Traefik,且路由规则匹配成功后,将流量发送到对应的后端服务前,先将其发给中间件进行一系列处理(类似于过滤器链 Filter,进行一系列处理),例如,添加 Header 头信息、鉴权、流量转发、处理访问路径前缀、IP 白名单等等,经过一个或者多个中间件处理完成后,再发送给后端服务,这个就是中间件的作用。Traefik内置了很多不同功能的Middleware,主要是针对HTTP和TCP,这里挑选几个比较常用的进行演示。
用户1107783
2023/09/11
9470
Traefik 企业实战:中间件(Middleware)篇
TraefikIngressRoute配置
端口说明: 8080是dashboard 80是http入口 443是https入口
mikelLam
2022/10/31
6100
TraefikIngressRoute配置
Kubernetes (K8S)中Traefik路由(ingressRoute)
kubernetes 中使用 Traefik ingress 的 ingressRoute 代理 http、https、tcp、udp。
王先森sec
2023/10/17
3K0
Kubernetes (K8S)中Traefik路由(ingressRoute)
在 Kubernetes 集群上部署 VSCode
近来由于武汉冠状病毒疫情的扩散,很多公司不得不开始了远程办公的模式,远程办公最大的成本自然是沟通成本了,对于我们开发人员来说最重要的自然也是有一个顺手的 IDE 工具,现在在云端作业的工具也在逐渐增长,比如最近比较流行的设计应用 Figma,就完全是云端操作的方式,大有要取代 Sketch 的趋势,对于开发工具来说云端 IDE 也逐渐受到大家重视,特别是对于远程办公的团队,Cloud IDE 允许开发团队在一个统一的开发环境中实时协作的工具,这可以大大提高生产效率。而且只需要通过 web 浏览器就可以访问,还有一个优点就是可以利用集群的能力,这可以大大超过我们之前的个人 PC 的处理能力,我们也不用为本地 IDE 占用了电脑大量资源而苦恼了。
我是阳明
2020/06/15
1.8K0
在 Kubernetes 集群上部署 VSCode
一篇文章让你搞懂K8s Ingress,Traefik 2.0为例(上)
了解K8s的同学应该都知道,如果想要把应用暴露到公网上供外部访问,那么不可避免的会接触到Ingress资源。本文以Traefik为例,让大家对Ingress和Traefik的使用有一定的了解。
100000798482
2020/01/16
5.7K2
一篇文章让你搞懂K8s Ingress,Traefik 2.0为例(上)
相关推荐
TKE之Traefik最佳实践
更多 >
目录
  • 什么是Traefik
  • Traefik的核心概念及能力
    • Providers
    • Entrypoints
    • Routers
    • Services
    • Middlewares
  • 部署Traefik
    • Helm部署
  • 使用Traefik
    • 创建第一个路由规则
      • 原生Ingress路由规则
      • 使用CRD方式配置路由规则
    • 暴露HTTP服务
    • 暴露HTTPS服务
      • 自有证书配置HTTPS
      • 自动生成HTTPS证书
    • 中间件的使用
      • 强制跳转HTTPS
      • 去除请求路径前缀
      • 添加IP白名单
    • 暴露TCP服务
    • 灰度发布
    • 流量复制
    • Kubernetes Gateway API
      • 什么是Gateway API?
      • 使用Gateway API
  • 最后
  • 引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档