K3S 中 Traefik v2 安装及采坑纪实

1,972 阅读2分钟

本文主要记录了在 k3s 1.20 中安装 traefik v2 版本的主要步骤及问题,若你是升级 v1 到 v2,可直接参考官方文档Migration Guide: From v1 to v2

k3s 集群中默认使用 Traefik 作为 Ingress Controller,k3s 1.20 及更早版本默认安装 Traefik v1,而 k3s 1.21 及更高版本默认安装 Traefik v2,v2 版本在性能和功能性上都有比较大的提升。

我们集群为 k3s 1.20,默认安装的是 Traefik v1 版本,基于性能和功能丰富度的考虑,我们打算升级为 Traefik v2,因为我们集群为新集群,不涉及到已有 ingress 的兼容修改,我们采用卸载重新安装的方式。若为升级操作,可参考官方文档Migration Guide: From v1 to v2,逐一修改不兼容的地方。

下面是安装重点配置和问题记录。

安装

我们使用 helm 来进行安装,可以从 rancher 的应用商店中查看下支持的最新版本。

traefik

若默认配置满足需求,完全可以通过上边的页面进行安装。若想自定义,可以通过页面右则下方的「Download」链接,下载 helm chart 来自定义配置安装。安装时和页面名称一致即可。

官方还有一种自定义修改默认安装组件的方法,使用 helmchartconfig,在配置清单目录中添加自定义配置,个人感觉不如直接自定义 helm chart 来的直接明了,大家可以尝试官方方案。

我们使用下载的 helm chart 进行自定义安装:

1、编写自己的 values 来自定义部分配置。

下面是我安装时自定义的values文件 k3s-values.yaml ,可参考:

# 默认的 ingressRouter 是开启的,使用内部 CRD service,自定义dashboard ingressroute时,可设置为 false,自己创建。
# ingressRoute:
#   dashboard:
#     enabled: false


deployment:
  enabled: true
  # Can be either Deployment or DaemonSet
  kind: Deployment
  # Number of pods of the deployment (only applies when kind == Deployment)
  replicas: 2

ports:
  traefik:
    port: 9000
    # You SHOULD NOT expose the traefik port on production deployments.
    # If you want to access it from outside of your cluster,
    # use `kubectl port-forward` or create a secure ingress
    # kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -n cattle-system) 9000:9000 -n cattle-system
    expose: false
    exposedPort: 9000
  web:
    port: 8000
    expose: true
    exposedPort: 80
  websecure:
    port: 8443
    expose: true
    exposedPort: 443
    tls:
      enabled: true  # 需要开启,否则配置的ingress不支持配置tls证书
  metrics:
    port: 9100
    expose: true
    exposedPort: 9100

affinity: 
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
                - traefik
        topologyKey: kubernetes.io/hostname

2、使用helm 安装

# 安装
helm install traefik ./ -n cattle-system -f k3s-values.yaml
# 更新自定义配置时使用
helm upgrade --install traefik ./ -n cattle-system -f k3s-values.yaml

这样便按照好了,不过在给出上边配置,之前我遇到了好几个问题,可参考,避免采坑。

问题记录

1、dashboard 如何配置?

官方提供了两种方式,第一种为port-forward 直接端口映射到本地访问,步骤如下:

  • 1、通过ingressRoute创建路由,helm chart中默认是创建的,如想自定义可设置为 false, 自己创建ingressingressRoute
  • 2、通过 port-forward 绑定端口
kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -n cattle-system) 9000:9000 -n cattle-system

访问本地的 localhost:9000/dashboard/ 即可,dashboard 后边的 /一定要有,否则会报 404。

第二种为直接暴露端口,步骤如下:

1、修改 values 配置如下:

ports:
  traefik:
    port: 9000
    expose: true ## <<< 改为 true,默认为 false
    exposedPort: 9000

2、执行更新配置命令:

helm upgrade --install traefik ./ -n cattle-system -f k3s-values.yaml

3、此时会看到 traefik 这个service 暴露了 9000 端口,我们可以通过 rancher 创建一个普通的ingress。

image

主机域名绑定集群节点ip,即可通过http://traefik-prod.example.com/dashboard/#/ 访问。

基于安全方面的考虑,官方更推荐第一种方案。

2、tls 如何支持?

该 charts 中有个比较坑的地方,如下:

  websecure:
    port: 8443
    expose: true
    exposedPort: 443
    tls:
      enabled: true  #<< 默认关闭,需要开启,否则配置的ingress不支持配置tls证书

ports.websecure.tls.enabled 默认是 false,这就导致在 ingress 中配置自定义证书不生效。当需要 https 的ingress时,该参数一定要打开。

image

3、k3s 中 traefik 部署方式问题?

在 k8s 中,ingress 有3种部署方式:

  • 1、IngressController作为DaemonSet部署,暴露hostPort;
  • 2、作为 Deployment 部署,给IngressController开一个NodePort服务;
  • 3、作为 Deployment 部署,给IngressController暴露一个LoadBalancer服务(需要借助云厂商提供的cloud provider能力分配ip);

在 k3s 中,使用了一个叫Klipper Load Balancer负载均衡器,它会以daemonset 的方式默认在所有节点上跑一个pod(当节点配置污点时,会启动报错,这里需要自己配置),作为代理服务。所以在 k3s 中,traefik 以 Deployment 和 DaemonSet 方式部署效果是一样的。

对比k8s第二种方式部署的 traefik 情况如下:

k3s

k8s

4、traefik 部署副本问题?

在k8s中 traefik 部署在那个node 节点,那个就可以接流量。但是在k3s中由于使用了 Klipper Load Balancer,默认所有节点都可以接流量,但是svclb这个 daemonset 是依赖 traefik这个服务的,当 traefik 服务重启时,svclb 不可用。建议最少配置 2 个traefik pod,且开启非亲和性,让pod不要部署在一个node节点,提高可用性。

deployment:
  enabled: true
  # Can be either Deployment or DaemonSet
  kind: Deployment
  # Number of pods of the deployment (only applies when kind == Deployment)
  replicas: 2  ## <<<< 至少两个副本,且开启pod 非亲和性。

affinity: 
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
                - traefik
        topologyKey: kubernetes.io/hostname        

5、traefik 监控配置?

在 charts 中metrics的监控接口并没有启动,我们可以修改ports.metrics.expose参数启动,如下:

  metrics:
    port: 9100
    expose: true  # <<< 改为true,默认为false
    exposedPort: 9100

之后增加一个 serviceMonitor,就能在 Prometheus 中看到该 target 了。

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: traefik
  namespace: cattle-monitoring-system
  labels:
    app.kubernetes.io/name: traefik
spec:
  jobLabel: app.kubernetes.io/name
  selector:
    matchLabels:
      app.kubernetes.io/name: traefik  # 服务发现label
  namespaceSelector:
    matchNames:
    - cattle-system  # traefik安装的命名空间
  endpoints:
  - port: metrics
    interval: 30s
    path: /metrics

总结

Rancher 中大部分组件都可以通过自定 helm chart 来安装,只要保持资源名字一致即可。可以先用 Rancher 的应用商店中的 chart 包安装一遍,创建些应用需要的CRD,再使用 helm chart安装。

我是 DeanWu,一个努力成为真正 SRE 的人。

关注公众号「码农吴先生」, 可第一时间获取最新文章。