Rancher 系列文章-K3s Traefik MiddleWare 報錯-Failed to create middleware keys

東風微鳴 發表於 2023-03-26
人工智慧

概述

書接上回:《Rancher 系列文章-K3S 叢集升級》, 我們提到:透過一鍵指令碼升級 K3S 叢集有報錯。

接下來開始進行 Traefik 報錯的分析和修復, 問題是:

  • 所有 Traefik 的 IngressRoute 訪問報錯 404

問題描述

報錯如下:

time="2022-05-05T09:51:21Z" level=error msg="Failed to create middleware keys: middleware kube-system/hsts-header is not in the IngressRoute namespace cert-manager" namespace=cert-manager providerName=kubernetescrd ingress=grafana

即無法跨 NameSpace 呼叫 Traefik MiddleWare.

解決過程

首先根據官方文件說明:Kubernetes IngressRoute & Traefik CRD - Traefik

可以配置 allowCrossNamespace 引數,該引數預設為 false, 如果該引數設定為true, IngressRoutes 可以引用其他 NameSpace 中的資源。

基本上斷定根因就是這個了。檢視 K3s v1.22.5+k3s2 的 Traefik 配置,確實沒有這個引數,如下:

...
containers:
  - name: traefik
    image: rancher/mirrored-library-traefik:2.5.0
    args:
      - '--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.kubernetesingress'
      - >-
        --providers.kubernetesingress.ingressendpoint.publishedservice=kube-system/traefik
      - '--entrypoints.websecure.http.tls=true'
...      

所以,剛開始就計劃透過編輯 Helm 的檔案把這個引數加上。

編輯 K3s 的 Manifests Helm 檔案

📚️ Reference:

  • 自動部署 manifests 和 Helm charts
    /var/lib/rancher/k3s/server/manifests中找到的任何 Kubernetes 清單將以類似kubectl apply的方式自動部署到 K3s。以這種方式部署的 manifests 是作為 AddOn 自定義資源來管理的,可以透過執行kubectl get addon -A來檢視。你會發現打包元件的 AddOns,如 CoreDNS、Local-Storage、Traefik 等。AddOns 是由部署控制器自動建立的,並根據它們在 manifests 目錄下的檔名命名。

該檔案位於:/var/lib/rancher/k3s/server/manifests/traefik.yaml, 內容如下:

---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik-crd
  namespace: kube-system
spec:
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-crd-10.3.001.tgz
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik
  namespace: kube-system
spec:
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-10.3.001.tgz
  set:
    global.systemDefaultRegistry: ""
  valuesContent: |-
    rbac:
      enabled: true
    ports:
      websecure:
        tls:
          enabled: true
    podAnnotations:
      prometheus.io/port: "8082"
      prometheus.io/scrape: "true"
    providers:
      kubernetesIngress:
        publishedService:
          enabled: true
    priorityClassName: "system-cluster-critical"
    image:
      name: "rancher/mirrored-library-traefik"
    tolerations:
    - key: "CriticalAddonsOnly"
      operator: "Exists"
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"
    - key: "node-role.kubernetes.io/master"
      operator: "Exists"
      effect: "NoSchedule"

在上面的 yaml 中加入如下配置:

...
    providers:
      kubernetesCRD:
        allowCrossNamespace: true

待其生效後, 確實可以恢復正常, 但是 K3s 會定期將 Manifests 重置為原有配置, 就會導致問題再次出現.

所以問題並沒有最終解決.

使用 HelmChartConfig 自定義打包的元件

不過根據官方文件後續的內容, 我們可以透過 使用 HelmChartConfig 自定義打包的元件 的方式覆蓋作為 HelmCharts(如 Traefik)部署的打包元件的值.

具體配置如下:

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    globalArguments:
    - "--providers.kubernetescrd.allowcrossnamespace=true"

生效後, 恢復正常, 並且沒有發生回滾.

問題解決.

🎉🎉🎉

📚️ 參考文件

三人行, 必有我師; 知識共享, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.