通过Traefik暴露Kubernetes Dashboard遇500错误:TLS证书问题
问题分析与解决方案
从日志能直接定位核心问题:
- Traefik日志的
x509: cannot validate certificate for 10.42.0.3 because it doesn't contain any IP SANs:Traefik用Dashboard Service的集群内部IP访问后端时,你的Let's Encrypt证书仅包含k8s.mydomain.co.uk域名,没有这个内部IP的SAN字段,导致证书验证失败,返回500错误。 - Dashboard日志的
tls: bad certificate:Traefik用IP而非域名发起TLS握手,不符合Dashboard配置的域名证书要求,触发证书校验失败。
方案一:边缘TLS终止(推荐,最简单)
让Traefik负责与外部客户端的HTTPS握手,Traefik和Dashboard之间用HTTP通信,彻底绕开内部TLS验证问题:
- 修改Dashboard Deployment,关闭自身TLS
编辑kubernetes-dashboard命名空间下的Deployment,删除TLS相关启动参数,改用HTTP端口:
containers: - name: kubernetes-dashboard image: kubernetesui/dashboard:v2.7.0 args: - --port=8080 - --metrics-scraper-client-timeout=30s # 保留其他必要参数,删除所有--tls-cert-file、--tls-key-file类参数 ports: - containerPort: 8080 protocol: TCP
- 更新Dashboard Service
将Service端口改为80,指向Dashboard的HTTP端口:
apiVersion: v1 kind: Service metadata: name: kubernetes-dashboard namespace: kubernetes-dashboard spec: ports: - port: 80 targetPort: 8080 selector: k8s-app: kubernetes-dashboard
- 配置带TLS终止的Ingress
编写Ingress资源,指定cert-manager生成的域名证书:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: kubernetes-dashboard-ingress namespace: kubernetes-dashboard annotations: cert-manager.io/cluster-issuer: "your-cluster-issuer-name" # 替换为你的ClusterIssuer名称 spec: tls: - hosts: - k8s.mydomain.co.uk secretName: k8s-mydomain-co-uk-tls # 替换为cert-manager生成的证书Secret名称 rules: - host: k8s.mydomain.co.uk http: paths: - path: / pathType: Prefix backend: service: name: kubernetes-dashboard port: number: 80
方案二:内部TLS加密(适合严格安全要求场景)
如果必须让Traefik与Dashboard之间也用TLS,需要生成包含Dashboard内部地址的证书:
- 生成内部证书
用cert-manager创建包含Dashboard内部FQDN和ClusterIP的证书:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: dashboard-internal-cert namespace: kubernetes-dashboard spec: secretName: dashboard-internal-tls issuerRef: name: your-internal-issuer # 替换为内部Issuer(如自签ClusterIssuer) kind: ClusterIssuer commonName: kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local dnsNames: - kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local - kubernetes-dashboard.kubernetes-dashboard.svc ipAddresses: - 10.42.0.3 # 替换为Dashboard Service的ClusterIP
- 配置Dashboard使用内部证书
恢复Dashboard的TLS配置,指向内部证书Secret:
args: - --tls-cert-file=/tls/tls.crt - --tls-key-file=/tls/tls.key volumeMounts: - name: dashboard-certs mountPath: /tls readOnly: true volumes: - name: dashboard-certs secret: secretName: dashboard-internal-tls
- 配置Traefik信任内部证书
创建TLSOption让Traefik信任内部CA,再在IngressRoute中引用:
# 先创建TLSOption apiVersion: traefik.containo.us/v1alpha1 kind: TLSOption metadata: name: dashboard-internal-tls namespace: kubernetes-dashboard spec: rootCAs: - secretName: your-internal-ca-secret # 替换为内部CA的Secret名称
# 配置IngressRoute apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: kubernetes-dashboard-ingressroute namespace: kubernetes-dashboard spec: entryPoints: - websecure routes: - match: Host(`k8s.mydomain.co.uk`) kind: Rule services: - name: kubernetes-dashboard port: 443 tls: options: name: dashboard-internal-tls tls: certResolver: your-cert-resolver # 替换为Traefik配置的cert-manager resolver domains: - main: k8s.mydomain.co.uk
关于IngressRoute的404问题
之前的404大概率是配置错误,检查以下几点:
- 确认
match规则为Host(k8s.mydomain.co.uk),与访问域名完全一致 - 确认
entryPoints设置为websecure(Traefik默认HTTPS入口) - 确认服务端口指向Dashboard的正确端口(443用内部TLS,80用HTTP)
- 检查Traefik是否有读取IngressRoute资源的RBAC权限(k3s默认Traefik已配置)
内容的提问来源于stack exchange,提问作者lordnoob
相关产品推荐
相关产品推荐

