舍得

V1

2022/01/09阅读:111主题:绿意

实战:Traefik-2022.1.9

实战:Traefik-2022.1.9

image-20220107073526113
image-20220107073526113

目录

实验环境

实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
   k8s version:v1.22.2
   containerd://1.5.5

实验软件

链接:https://pan.baidu.com/s/1pGuxUQee8lSrH2lELisoWw 提取码:z6ns image-20220109103030680

1、Traefik

Traefik 是一个开源的可以使服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理。

traefik architecture
traefik architecture

除了众多的功能之外,Traefik 的与众不同之处还在于它会自动发现适合你服务的配置。当 Traefik 在检查你的服务时,会找到服务的相关信息并找到合适的服务来满足对应的请求。

Traefik 兼容所有主流的集群技术,比如 Kubernetes,Docker,Docker Swarm,AWS,Mesos,Marathon,等等;并且可以同时处理多种方式。(甚至可以用于在裸机上运行的比较旧的软件。

使用 Traefik,不需要维护或者同步一个独立的配置文件因为一切都会自动配置,实时操作的(无需重新启动,不会中断连接)。使用 Traefik,你可以花更多的时间在系统的开发和新功能上面,而不是在配置和维护工作状态上面花费大量时间。

2、核心概念

Traefik 是一个边缘路由器,是你整个平台的大门(就相当于一个网关)拦截并路由每个传入的请求:它知道所有的逻辑和规则,这些规则确定哪些服务处理哪些请求;传统的反向代理需要一个配置文件(比如说nginx.conf文件),其中包含路由到你服务的所有可能路由,而 Traefik 会实时检测服务并自动更新路由规则,可以自动服务发现

traefik architecture overview
traefik architecture overview

首先,当启动 Traefik 时,需要定义 entrypoints(入口点),然后,根据连接到这些 entrypoints 的路由来分析传入的请求,来查看他们是否与一组规则相匹配,如果匹配,则路由可能会将请求通过一系列中间件转换过后再转发到你的服务上去。在了解 Traefik 之前有几个核心概念我们必须要了解:

  • Providers 用来自动发现平台上的服务,可以是编排工具、容器引擎或者 key-value 存储等,比如 Docker、Kubernetes、File。

    这个providers就相当于我们所说的提供器。

    比如说我们在k8s当中,可以去定义一个让他去识别我们默认ingress资源对象的这样一个provider;然后呢,我们还可以定义一个让她去识别我们这个traefik当中自定义的ingress CRD这样得的一个资源对象。

    就是一个一个的提供器,就是我们需要去告诉traefik,我要开启哪些provider,比如说你不开启k8s的ingress,那么我们默认创建的资源对象它是识别不了的。

    所以,providers相当于一个提供器,你想去操作哪一个资源对象,你就需要把他开启。

  • Entrypoints 监听传入的流量(端口等…),是网络入口点,它们定义了接收请求的端口(HTTP 或者 TCP)。(一个入口点就相当于一个端口;)

  • Routers 分析请求(host, path, headers, SSL, …),负责将传入请求连接到可以处理这些请求的服务上去。(就相当于我们nginx config中的PATH路径之类的)

  • Services 将请求转发给你的应用(load balancing, …),负责配置如何获取最终将处理传入请求的实际服务。

    注意:这里的serice可能不完完全全等同于我们k8s里的service。

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

    在ingress-nginx里要想实现这个效果,是要通过注解来配置的,但在这里可以使用yaml文件格式来进行编写,更加地云原生。

3、安装

📍 演示1:traefik安装

由于 Traefik 2.X 版本和之前的 1.X 版本不兼容,我们这里选择功能更加强大的 2.X 版本来和大家进行讲解。

在 Traefik 中的配置可以使用两种不同的方式:

  • 动态配置:完全动态的路由配置
  • 静态配置:启动配置

静态配置中的元素(这些元素不会经常更改)连接到 providers 并定义 Treafik 将要监听的 entrypoints。

在 Traefik 中有三种方式定义静态配置:在配置文件中、在命令行参数中、通过环境变量传递

动态配置(你可以认为是需要创建那些CRD之类的)包含定义系统如何处理请求的所有配置内容,这些配置是可以改变的,而且是无缝热更新的,没有任何请求中断或连接损耗。

🍀 这里我们还是使用 Helm 来快速安装 traefik,首先获取 Helm Chart 包:

➜ git clone https://github.com/traefik/traefik-helm-chart #这里需要科学上网才可以,,
➜ cd traefik-helm-chart

🍀 创建一个定制的 values 配置文件:

[root@master1 ~]#cd traefik/
[root@master1 traefik]#ls
Chart.yaml  ci  crds  Guidelines.md  LICENSE  README.md  templates  tests  traefik.zip  values.yaml
[root@master1 traefik]#vim ci/deployment-prod.yaml
# ci/deployment-prod.yaml #我们用如下文件覆盖掉默认values.yaml文件内容。
deployment:
  enabled: true
  kind: Deployment

# 使用 IngressClass. Traefik 版本<2.3 或者 Kubernetes 版本 < 1.18.x 会被忽略
ingressClass:
  # 还没有进行完整的单元测试,pending https://github.com/rancher/helm-unittest/pull/12
  enabled: true
  isDefaultClass: false

ingressRoute:  # 不用自动创建,我们自己处理
  dashboard:
    enabled: false

#
# 配置 providers
#
providers:
  kubernetesCRD:  # 开启 crd provider
    enabled: true
    allowCrossNamespace: true  # 是否允许跨命名空间
    allowExternalNameServices: true  # 是否允许使用 ExternalName 的服务

  kubernetesIngress:  # 开启 ingress provider
    enabled: true
    allowExternalNameServices: true

logs:
  general:
    # format: json
    level: DEBUG
  access:
    enabled: true

ports:
  web:
    port: 8000
    hostPort: 80  # 使用 hostport 模式

  websecure:
    port: 8443
    hostPort: 443  # 使用 hostport 模式

  metrics:
    port: 9100
    hostPort: 9101

service:  # host 模式就不需要创建 Service 了,云端环境可以用 Service 模式
  enabled: false

resources:
  requests:
    cpu: "100m"
    memory: "100Mi"
  limits:
    cpu: "100m"
    memory: "100Mi"

# tolerations:   # kubeadm 安装的集群默认情况下master是有污点,如果需要安装在master节点需要添加容忍
# - key: "node-role.kubernetes.io/master"
#   operator: "Equal"
#   effect: "NoSchedule"

nodeSelector:   # 固定到node1这个边缘节点
  kubernetes.io/hostname: "node1"

一般情况,这里我们使用 hostport 模式将 Traefik 固定到 master1 节点上,因为只有这个节点有外网 IP,所以我们这里 master1 是作为流量的入口点。但这里我们之前部署把ingress-nginx部署在了master1上了吗,因此这里把traefik部署在node1上面

:warning: 注意:但是自己在部署过程中报错了

image-20220108173037350
image-20220108173037350

发现node都不具备条件:

image-20220108173159552
image-20220108173159552
image-20220108173249862
image-20220108173249862
image-20220108175018633
image-20220108175018633
image-20220108175050603
image-20220108175050603

呵呵:我把metric-server的reeplica改为0,现在traefik没问题了,metric-server起不来了哈哈。先不管了。。😂

好像metrics已经占用了443端口,因此这里创建traefik报错。

这里还是存在一定的问题的。

还有,我把ingres-nginx defaultbackend那个给删除了。。。。

image-20220108180237603
image-20220108180237603

🍀 直接使用上面的 values 文件安装 traefik:

➜ helm upgrade --install traefik ./traefik -f ./traefik/ci/deployment-prod.yaml --namespace kube-system
Release "traefik" does not exist. Installing it now.
NAME: traefik
LAST DEPLOYED: Thu Dec 23 17:03:29 2021
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@master1 ~]#kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik
NAME                       READY   STATUS    RESTARTS   AGE
traefik-84f9f8b5bb-zxc6l   1/1     Running   0          18m

🍀 安装完成后我们可以通过查看 Pod 的资源清单来了解 Traefik 的运行方式:

[root@master1 ~]#kubectl get deployments.apps  traefik -nkube-system -oyaml
apiVersion: apps/v1
kind: Deployment
......
    spec:
      containers:
      - args:
        - --global.checknewversion
        - --global.sendanonymoususage
        - --entryPoints.metrics.address=:9100/tcp
        - --entryPoints.traefik.address=:9000/tcp
        - --entryPoints.web.address=:8000/tcp
        - --entryPoints.websecure.address=:8443/tcp
        - --api.dashboard=true
        - --ping=true
        - --metrics.prometheus=true
        - --metrics.prometheus.entrypoint=metrics
        - --providers.kubernetescrd
        - --providers.kubernetescrd.allowExternalNameServices=true
        - --providers.kubernetesingress
        - --providers.kubernetesingress.allowExternalNameServices=true
        - --log.level=DEBUG
        - --accesslog=true
        - --accesslog.fields.defaultmode=keep
        - --accesslog.fields.headers.defaultmode=drop
        image: traefik:2.5.4
......
        ports:
        - containerPort: 9100
          hostPort: 9101
          name: metrics
          protocol: TCP
        - containerPort: 9000
          name: traefik
          protocol: TCP
        - containerPort: 8000
          hostPort: 80
          name: web
          protocol: TCP
        - containerPort: 8443
          hostPort: 443
          name: websecure
          protocol: TCP
        
......

其中 entryPoints 属性定义了 webwebsecure 这两个入口点的,并开启 kubernetesingresskubernetescrd 这两个 provider,也就是我们可以使用 Kubernetes 原本的 Ingress 资源对象,也可以使用 Traefik 自己扩展的 IngressRoute 这样的 CRD 资源对象。

  • 注意:查看下pod日志 [root@master1 ~]#kubectl logs -f traefik-84f9f8b5bb-zxc6l -nkube-system
image-20220108192932981
image-20220108192932981

我们可以看到,会有有一些ping,它自己会做一些类似于健康检查东西在里面。

  • 注意:安装好traefik之后,它会默认帮我们创建好一个traefik的ingressclass资源对象
[root@master1 ~]#kubectl get ingressclass
NAME      CONTROLLER                      PARAMETERS   AGE
nginx     k8s.io/ingress-nginx            <none>       6d3h
traefik   traefik.io/ingress-controller   <none>       132m
[root@master1 ~]#kubectl get ingressclasses traefik -oyaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  annotations:
    ingressclass.kubernetes.io/is-default-class: "false"
    meta.helm.sh/release-name: traefik
    meta.helm.sh/release-namespace: kube-system
  creationTimestamp: "2022-01-08T09:26:09Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: traefik
    helm.sh/chart: traefik-10.9.1
  name: traefik #ingressclass name
  resourceVersion: "1364007"
  uid: ad8b4335-d692-44a9-abe7-5df8ee1cb81a
spec:
  controller: traefik.io/ingress-controller

测试结束。😘

  • 我们可以看下traefike下有哪些可以使用的CRD
[root@master1 ingress-controller]#kubectl get crd
NAME                                    CREATED AT
ingressroutes.traefik.containo.us       2022-01-08T09:26:06Z
ingressroutetcps.traefik.containo.us    2022-01-08T09:26:06Z
ingressrouteudps.traefik.containo.us    2022-01-08T09:26:06Z
middlewares.traefik.containo.us         2022-01-08T09:26:06Z
middlewaretcps.traefik.containo.us      2022-01-08T09:26:06Z
serverstransports.traefik.containo.us   2022-01-08T09:26:06Z
tlsoptions.traefik.containo.us          2022-01-08T09:26:06Z
tlsstores.traefik.containo.us           2022-01-08T09:26:06Z
traefikservices.traefik.containo.us     2022-01-08T09:26:06Z

#如果想详细查看下这些CRD的信息,我们可以看下其yaml内容
[root@master1 traefik]#kubectl get crd ingressroutes.traefik.containo.us -oyaml
image-20220109074657002
image-20220109074657002

我们来看下IngressRoute的详细信息:

[root@master1 traefik]#kubectl get IngressRoute
No resources found in default namespace.
[root@master1 traefik]#kubectl explain IngressRoute.spec
KIND:     IngressRoute
VERSION:  traefik.containo.us/v1alpha1

RESOURCE: spec <Object>:

DESCRIPTION:
     IngressRouteSpec is a specification for a IngressRouteSpec resource.

FIELDS:
   entryPoints  <[]string>

   routes       <[]Object> -required->

   tls  <Object>
     TLS contains the TLS certificates configuration of the routes. To enable
     Let's Encrypt, use an empty TLS struct, e.g. in YAML:
     tls: {} # inline format tls: secretName: # block format
[root@master1 traefik]#kubectl explain IngressRoute.spec.routes
KIND:     IngressRoute
VERSION:  traefik.containo.us/v1alpha1

RESOURCE: routes <[]Object>:

DESCRIPTION:

     Route contains the set of routes.

FIELDS: #这里后面就没有具体的描述了
   kind <string> -required->

   match        <string> -required->

   middlewares  <[]Object>

   priority     <integer>

   services     <[]Object>

[root@master1 traefik]#

📍 演示2:创建一个用于Dashboard访问的 IngressRoute 资源清单

🍀 我们可以首先创建一个用于 Dashboard 访问的 IngressRoute 资源清单:

[root@master1 traefik]#vim traefik-dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: kube-system #注意:这里命名空间可以随意指定,因为前面是已经开启了跨命名空间访问的功能了,但一般是放在和traefik相同的命名空间下面的。
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`traefik.qikqiak.com`)  # 指定域名
    kind: Rule
    services:
    - name: api@internal #trefik内置的一个用于处理traefik内部服务的service(和k8s的service不一样)
      kind: TraefikService  # 引用另外的 Traefik Service
[root@master1 traefik]#kubectl apply -f traefik-dashboard.yaml 
ingressroute.traefik.containo.us/traefik-dashboard created
[root@master1 traefik]#kubectl get ingressroute -nkube-system
NAME                AGE
traefik-dashboard   54s

#在自己pc笔记本上做下域名解析:C:\WINDOWS\System32\drivers\etc\hosts
172.29.9.52 traefik.qikqiak.com

其中的 TraefikServiceTraefik Service 的一个 CRD 实现,这里我们使用的 api@internal 这个 TraefikService,表示我们访问的是 Traefik 内置的应用服务。

🍀 部署完成后我们可以通过在本地 /etc/hosts 中添加上域名 traefik.qikqiak.com 的映射即可访问 Traefik 的 Dashboard 页面了:

这个traefik-dashboard 只能进行查看,不能创建资源;

image-20220109082543435
image-20220109082543435

注意

另外需要注意的是默认情况下 Traefik 的 IngressRoute 已经允许跨 namespace 进行通信了,可以通过设置参数 --providers.kubernetescrd.allowCrossNamespace=true 开启(默认已经开启),开启后 IngressRoute 就可以引用 IngressRoute 命名空间以外的其他命名空间中的任何资源了。

image-20220109101343079
image-20220109101343079

📍 演示3:让Traefik去处理默认的Ingress资源对象

如果要让 Traefik 去处理默认的 Ingress 资源对象,则我们就需要使用名为 traefik的 IngressClass 了,因为没有指定默认的:

➜ kubectl get ingressclass
NAME      CONTROLLER                      PARAMETERS   AGE
nginx     k8s.io/ingress-nginx            <none>       46h
traefik   traefik.io/ingress-controller   <none>       122m

把原来my-nginxingress资源对象的ingressClassName值从nginx改为本次要使用的traefik。测试过程如下

[root@master1 ~]#kubectl get ingressclass
NAME      CONTROLLER                      PARAMETERS   AGE
nginx     k8s.io/ingress-nginx            <none>       6d3h
traefik   traefik.io/ingress-controller   <none>       147m
[root@master1 ~]#kubectl get ingress
NAME            CLASS   HOSTS                ADDRESS       PORTS     AGE
ingress-https   nginx   foo.bar.com          172.29.9.51   80, 443   2d
my-nginx        nginx   ngdemo.qikqiak.com   172.29.9.51   80        2d6h
[root@master1 ingress-controller]#vim first-ingress.yaml 
……
apiVersion: networking.k8s.io/v1
kind: Ingress                                                                                                        4.0.11    master1   <none>      
metadata:
  name: my-nginx
  namespace: default
spec:
  ingressClassName: traefik  # 修改1:使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)
  rules:
  - host: ngdemo-by-traefik.qikqiak.com  # 修改2:将域名映射到 my-nginx 服务
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:  # 将所有请求发送到 my-nginx 服务的 80 端口
            name: my-nginx
            port:
              number: 80
[root@master1 ingress-controller]#kubectl apply -f first-ingress.yaml
deployment.apps/my-nginx unchanged
service/my-nginx unchanged
ingress.networking.k8s.io/my-nginx configured

#在自己pc笔记本上做下域名解析:C:\WINDOWS\System32\drivers\etc\hosts
172.29.9.52 ngdemo-by-traefik.qikqiak.com

[root@master1 ingress-controller]#kubectl get ingress
NAME            CLASS     HOSTS                           ADDRESS       PORTS     AGE
ingress-https   nginx     foo.bar.com                     172.29.9.51   80, 443   2d
my-nginx        traefik   ngdemo-by-traefik.qikqiak.com         80        2d7h 

此时在浏览器访问测试:

image-20220108200539185
image-20220108200539185

查看下traefik pod日志:

[root@master1 ingress-controller]#kubectl logs -f traefik-84f9f8b5bb-zxc6l -nkube-system
image-20220108201031830
image-20220108201031830
image-20220108201100620
image-20220108201100620

测试结束。😘

注意事项

📍 traefik

:warning: 注意:

其实你把它看成一个网关就可以; 宿主机上,你完全把它当成一个nginx来使用就可以了;

traefik是golang开发的,这个Traefik整体使用起来要比我们的nginx灵活很多;

但是,从官方数据得知,这个traefik的性能要比ingress-nginx差一点。这个当然要根据你实际的场景来选择,如果说你的集群不是一个超大规模的话,那么使用traefik要舒服很多的

其实:这个Traefik整体和nginx里比较类似,它可能把其他一些请求点,整个请求的一个路径上面给它做了一些其他的定义而已;

traefik里它最经典的一点就是中间件,我们可以自己去创建一个中间件,而且这个中间件它也是一种CRD对象;

other 注意事项:

🍀 如果要开启ACME的话,daemonset方式是不支持的,只能使用deployment。

image-20220108115850296
image-20220108115850296

🍀 deployment方式可以使用acme,但只允许只要一个副本才行。

image-20220108120109881
image-20220108120109881

🍀 真正的模板是在这个里面定义的:_podtemplate.tpl

image-20220108142059179
image-20220108142059179
image-20220108142142131
image-20220108142142131

🍀 这里可以指定ingressclass。

image-20220108142651664
image-20220108142651664

🍀 默认traefik安装完成后,它会帮我们安装一个ingressroute的dashboard。我们不用开启,给它手动创建一个。

image-20220108143005402
image-20220108143005402

🍀 kubernetesCRD和kuberbetesIngress:2者默认都是开启的

image-20220108143323559
image-20220108143323559

🍀 这里就相当于我们的Entrypoints。

image-20220108143824271
image-20220108143824271

🍀 本地用hostport模式,就不用开启service了。

image-20220108144056421
image-20220108144056421

📍 traefik官方文档

https://doc.traefik.io/traefik/

image-20220108201352951
image-20220108201352951

就是我现在想做一个https的跳转该怎么做呢?

原来的ingres-nginx里是可以通过注解来做的,而traefike这里也是兼容的,但是采用中间件来做的,直接搜索anotations查看。

image-20220108202156918
image-20220108202156918
image-20220108201634294
image-20220108201634294

但traefik更让人喜欢的而是可以使用kubernetesCRD这种方式。😥

image-20220108202323945
image-20220108202323945

📍 traefik pilot

现在这个traefik提供的这个扩展的traefik中间件的sas系统,它把这个做成可一个sas系统,对我们的企业用户不是那么地友好。因为很多情况,我们是把traefik部署在我们的内网环境里的。如果我们的网关都依赖于你的sas服务的话,那如果你的sas服务挂掉了的话,对我们的依赖性还是挺高的。 这个pilot用起来其实还是挺好用的,这个pilot上面提供了很多中间件服务。就是我们也可以自己去开发,但你想要把它用起来的话,你还是要把它上传到这个pilot上面去。

image-20220109102128973
image-20220109102128973

关于我

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。

    image-20211002091450217
    image-20211002091450217
  2. 个人博客地址:www.onlyonexl.cn

    image-20211002092057988
    image-20211002092057988
  3. 个人微信公众号:云原生架构师实战

    image-20211002141739664
    image-20211002141739664
  4. 个人github

    https://github.com/OnlyOnexl

    image-20220105203338290
    image-20220105203338290
  5. 个人csdn

    https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

    image-20211002092344616
    image-20211002092344616

最后

​ 好了,关于Traefik实验就到这里了,感谢大家阅读,最后贴上我女神的photo,祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20220109091922928
image-20220109091922928

分类:

后端

标签:

后端

作者介绍

舍得
V1