【2】minikube部署Traefik


目录

【1】minikube初体验
【2】minikube部署Traefik
【3】minikube离线版安装

接上篇, 安装完成 minikube 后,原生单机版的 k8s集群已经搭建完毕,本次是为 minikube 安装 traefik 。 那问题来了, 什么是 traefik? 为什么要用 traefik?


traefik 简介


Traefik 是一款反向代理、负载均衡服务,使用 golang 实现,能够支持自动化更新反向代理和负载均衡配置。要理解 Traefik ,这里有三个概念

  • Ingress
  • IngressRoute
  • Ingress Controller

Ingress : 用于定义和管理HTTP和HTTPS流量的路由规则。通过Ingress资源,可以在Kubernetes集群内部部署一个负载均衡器,并将外部流量路由到集群内部的服务上。说白了就是申明配置规则的。

IngressRoute:用于定义更高级和灵活的HTTP和HTTPS流量路由规则,动态路由、多条件匹配等,可以增强对流量路由的控制。说白了就是申明配置的规则更加高级了,可以实现动态、多条件等。

Ingress Controller:负责监视 ingress 和 ingressRoute资源的变化,并将其应用到实际的负载均衡中去,实现流量的转发和管理。说白了就是nginx这款软件。

这三者的关系,我自身的理解,通过 nginx 来举例说明:

image-20240322151724434

Traefik 部署分了两种组合:

  • Traefik + Ingress

  • Traefik + IngressRoute

Traefik Ingress主要用于定义基本的路由规则,适用于简单的流量路由需求,类似于Kubernetes原生的Ingress资源。

Traefik IngressRoute则提供了更多高级的功能和选项,如中间件的应用、动态路由配置、服务权重调整等,用于处理更复杂的流量路由场景。

总的来说,Traefik Ingress和Traefik IngressRoute都是Traefik Ingress Controller提供的资源对象,用于定义和管理HTTP和HTTPS流量路由规则,主要区别在于Ingress适用于基本的路由配置,而IngressRoute提供了更高级的功能和强大的路由控制选项。根据具体的需求和场景选择使用Traefik Ingress或Traefik IngressRoute来管理流量路由。

接下来就通过实例配置来分别描述这两种组合的安装。

注意:Traefik+ingress 和 Traefik+ingresRoute 同一个集群只能选择其一,通常会选择功能更加强大的 Traefik+IngressRoute 组合。


Traefik+Ingress部署


通过上一篇:https://www.cnblogs.com/hukey/p/18061513 已经部署了一个 minikube 环境。Traefik的部署在 minikube 和 kubernetes 是一致的。

参考官方文档进行部署:https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress/

image-20240322153732162

在官方文档页面找到 Configuration Example 下的 RBAC 部分,并复制其中的yaml代码。

注意:直接复制官方文档,官方可能会更新。

root@minikube(192.168.199.200)~>mkdir traefik-ingress
root@minikube(192.168.199.200)~>cd traefik-ingress/
root@minikube(192.168.199.200)~/traefik-ingress>vim traefik-ingress.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
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: default

执行清单文件

root@minikube(192.168.199.200)~/traefik-ingress> kubectl apply -f  traefik-ingress.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created

image-20240322154155724

同样的位置,点击 Traefik 并复制其中的 yaml 代码

root@minikube(192.168.199.200)~/traefik-ingress>vim traefik-daemon.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller

---
apiVersion: apps/v1
kind: Deployment	#[修改]将Deployment 修改为 DaemonSet
metadata:
  name: traefik
  labels:
    app: traefik

spec:
  replicas: 1		#[删除]本项在 DaemonSet中没有配置此项
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v2.11
          args:
            - --log.level=INFO						 #[新增] Traefik日志级别
            - --api                                    #[新增] 允许访问API接口
            - --api.insecure				    	 #[新增] 允许以HTTP
            - --entrypoints.web.address=:80
            - --entrypoints.websecure.address=:443     #[新增] 定义 HTTPS 的接收端口
            - --providers.kubernetesingress
          ports:
            - name: web
              containerPort: 80
              hostPort: 80                             #[新增] 暴露Traefik容器的80端口至节点[HTTP转发]
            - name: websecure                          #[新增] 增加HTTPS转发的支持[选用]
              containerPort: 443                       #[新增] Traefik容器上使用的端口[对应上面的配置][选用]
              hostPort: 443                            #[新增] 暴露Traefik容器的443端口至节点[HTTPS转发]
            - name: admin                              #[新增] Traefik管理页面
              containerPort: 8080                      #[新增] Traefik dashboard访问端口
              hostPort: 8080                           #[新增] 暴露Tracfik容器的8080端口至节点[可不用配置,使用kubectl port-forward转发]

[删除] 删除 service 该部分是为公有云负载均衡使用
---
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: TCP
      port: 80
      name: web
      targetPort: 80
---

执行清单文件

root@minikube(192.168.199.200)~/traefik-ingress>kubectl apply -f  traefik-daemon.yaml
serviceaccount/traefik-ingress-controller created
deployment.apps/traefik created
service/traefik created

Deployment 修改为 DaemonSet 是为了让每个节点都创建一个 Traefik Pod,实现更好的冗余和负载均衡;

通过Pod直接暴露 hostPort 减少了service代理,社区通常的方案是通过 Traefik PodhostPort形式发布,然后外部在提供一个四层负载均衡器

image-20240322181130603

root@minikube(192.168.199.200)~/traefik-ingress>kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
traefik   1         1         1       1            1           <none>          42s

通过浏览器访问 traefik dashboard

image-20240322182129107

到此,已经可以通过 http://node_ip:8080 的方式去访问 Traefik 的后台了。如果是这样做的话,K8S集群中每台主机的 8080 端口都会被占用。目前已经有 Traefik作为边缘代理,而且也已经暴露了80端口,这时候就可以通过 ingress 来设置访问 Traefik dashboard

如果需要使用 ingress 则需要创建 service资源,如下:

注意:非官方代码

root@minikube(192.168.199.200)~/traefik-ingress>cat dashboard-ingress.yaml
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  ports:
    - protocol: TCP
      name: traefik
      port: 8080
  selector:
    app: traefik
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traefik
spec:
  rules:
  - host: traefik-dashboard.domain.local       #定义域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: traefik                      #Service资源定义的名称
            port:
              number: 8080                     #Service资源的端口

上面代码第一步创建了一个 traefik 服务,然后创建一个 ingress 资源进行转发。

上面的代码中使用了定义域名,所有如果客户端是 windows电脑则需要在 C:\Windows\System32\drivers\etc\hosts 中申明:

image-20240323154243594

现在就可通过浏览器访问:http://traefik-dashboard.domain.local/ 来访问 Traefik

image-20240323102136887

到此,K8S 的 Traefik+ingress 部署完毕。


Traefik+IngressRoute部署


如果安装了上面的 Traefik+ingress 组合,则需要删除其配置信息:

root@minikube(192.168.199.200)~/traefik-ingress>ls
dashboard-ingress.yaml  traefik-daemon.yaml  traefik-ingress.yaml
root@minikube(192.168.199.200)~/traefik-ingress>kubectl delete -f traefik-daemon.yaml -f traefik-ingress.yaml -f dashboard-ingress.yaml
serviceaccount "traefik-ingress-controller" deleted
daemonset.apps "traefik" deleted
clusterrole.rbac.authorization.k8s.io "traefik-ingress-controller" deleted
clusterrolebinding.rbac.authorization.k8s.io "traefik-ingress-controller" deleted
service "traefik" deleted
ingress.networking.k8s.io "traefik" deleted

通过上一篇:https://www.cnblogs.com/hukey/p/18061513 已经部署了一个 minikube 环境。Traefik的部署在 minikube 和 kubernetes 是一致的。

参考官方文档进行部署:https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/

在官方文档页面找到如下信息

image-20240323103405012

复制 Resource Definition 中的yaml内容到 traefik-definition.yaml

yaml文件内容太长就不在这里展示,请以官方文档中内容为准。

执行清单文件:

root@minikube(192.168.199.200)~/traefik-ingressroute>kubectl apply -f  traefik-definition.yaml
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressrouteudps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.io created
customresourcedefinition.apiextensions.k8s.io/middlewaretcps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/serverstransports.traefik.io created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.io created
customresourcedefinition.apiextensions.k8s.io/tlsstores.traefik.io created
customresourcedefinition.apiextensions.k8s.io/traefikservices.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressrouteudps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewaretcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/serverstransports.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsstores.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/traefikservices.traefik.containo.us created

完成后,同样的位置找到 RBAC

image-20240323103835145

复制 RBAC 中的yaml内容到 traefik-rbac.yaml

官方文档可能会更新,请以官方文档中内容为准。

root@minikube(192.168.199.200)~/traefik-ingressroute>vim traefik-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller

rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - traefik.io
      - traefik.containo.us
    resources:
      - middlewares
      - middlewaretcps
      - ingressroutes
      - traefikservices
      - ingressroutetcps
      - ingressrouteudps
      - tlsoptions
      - tlsstores
      - serverstransports
    verbs:
      - get
      - list
      - watch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
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: default

执行清单文件

root@minikube(192.168.199.200)~/traefik-ingressroute>kubectl apply -f  traefik-rbac.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller configured
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller unchanged

完成后,在该页面找到 Traefik

image-20240323104325713

复制 Traefik 中的yaml内容到 traefik-daemonset.yaml

root@minikube(192.168.199.200)~/traefik-ingressroute>cat traefik-daemonset.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller

---
kind: Deployment                      # [修改] 修改为 DaemonSet
apiVersion: apps/v1
metadata:
  name: traefik
  labels:
    app: traefik

spec:
  replicas: 1                         # [删除] DaemonSet中没有该项,删除
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v2.11
          args:
            - --log.level=DEBUG                       # [修改] 日志修改为 'info' 即可
            - --api
            - --api.insecure
            - --entrypoints.web.address=:80           # [说明] 定义HTTP的接收端口
            - --entrypoints.websecure.address=:443    # [新增] 定义HTTPS的接收端口
            - --entrypoints.tcpep.address=:8000       # [说明] 定义TCP 8080接收端口
            - --entrypoints.udpep.address=:9000/udp   # [说明] 定义UDP 9000接收端口
            - --providers.kubernetescrd
          ports:
            - name: web
              containerPort: 80
              hostPort: 80            # [新增] 暴露Traefik容器的80端口至节点
            - name: websecure         # [新增] 暴露Traefik容器的443端口至节点
              containerPort: 443      # [新增] Traefik容器上使用的端口
              hostPort: 443           # [新增] 暴露Traefik容器的443端口至节点
            - name: admin
              containerPort: 8080
              nodePort: 8080          # [新增] 暴露Tracfik容器的8080端口至节点[尽量别使用,可以后期通用转发实现访问]
            - name: tcpep
              containerPort: 8000
              nodePort: 8000          # [新增] 暴露Tracfik容器的8000端口至节点
            - name: udpep
              containerPort: 9000
              nodePort: 9000          # [新增] 暴露Tracfik容器的9000端口至节点


[删除] 以下部分在公有云使用SLB部署使用,这里直接删除。
---
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: TCP
      port: 80
      name: web
      targetPort: 80
    - protocol: TCP
      port: 8080
      name: admin
      targetPort: 8080
    - protocol: TCP
      port: 8000
      name: tcpep
      targetPort: 8000

---
apiVersion: v1
kind: Service
metadata:
  name: traefikudp
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: UDP
      port: 9000
      name: udpep
      targetPort: 9000
----------------------------

执行清单文件

kubectl apply -f  traefik-daemonset.yaml

通过 port-forward 来访问 traefik dashboard

安装使用 kubectl port-forward 之前需要安装 socat
yum install -y socat

启用端口转发
kubectl port-forward -n default  traefik-676967d669-kltct --address 0.0.0.0  8080:8080

浏览器访问:

image-20240323114439347

接下来使用 traefik ingressRoute 来代理 traefik dashboard

#dashboard-ingress.yaml
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  ports:
    - protocol: TCP
      name: traefik
      port: 8080
  selector:
    app: traefik
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`traefik.domain.local`)
    kind: Rule
    services:
    - name: traefik
      port: 8080

执行清单文件:

kubectl apply -f  dashboard-ingress.yaml

上面的代码中使用了定义域名,所有如果客户端是 windows电脑则需要在 C:\Windows\System32\drivers\etc\hosts 中申明:

image-20240323115439460

然后使用浏览器访问:

image-20240323115456536


IngressRoute常用实例


有这样一个需求:一个服务通过ip:host 访问直接返回文本"hello world",使用 Traefik 为其添加一个二级目录,返回的依然是 "hello world"

比如:
后端服务: 192.168.199.200:8080 -> "hello world."
通过Traefik加二级目录访问:192.168.199.200/hello -> "hello world."

(1)编写ngx-pod

#ngx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ngx
  name: ngx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ngx
  template:
    metadata:
      labels:
        app: ngx
    spec:
      containers:
      - image: nginx:alpine
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        hostPath:
          path: /opt/web    #挂载本地路径,路径下存放 echo "hello, world." > /opt/web/index.html
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ngx
  name: ngx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: ngx

(2)编写 Middleware

#ngx-middleware.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: ngx-middleware
spec:
  stripPrefix:
    prefixes:
      - /hello

(3)编写ingressRoute

#ngx-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ngx
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`www.super.com`) && PathPrefix(`/hello`)         #这里使用了域名/子目录的形式:www.super.com/hello
    kind: Rule
    services:
    - name: ngx
      port: 80
    middlewares:
    - name: ngx-middleware

执行清单文件:

kubectl apply -f ngx.yaml -f ngx-middleware.yaml -f ngx-route.yaml

在window中申明域名

image-20240323153501802

浏览器直接访问:

image-20240323153524349

Traefik+ingressRoute 使用方式还有很多,具体请自行试用。


参考链接


K8S部署Traefik与Ingress、IngressRoute教程: https://www.lemonsys.cn/tech_563/



--- EOF ---

posted @ 2024-03-23 15:47  hukey  阅读(167)  评论(0编辑  收藏  举报