minikube部署Traefik【2】

hukey發表於2024-03-23

目錄

minikube初體驗【1】
minikube部署Traefik【2】


接上篇, 安裝完成 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+ingressTraefik+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 ---

相關文章