之前我的集群一直使用的Ingress-Nginx作为应用路由,但是没有证书导致https一直都是不受信,然后被群友安利了Traefik的Ingress实现,感觉不错,抄了一套到我自己的集群上,过程中还踩了点坑,特此记录一下。
本文使用Helm安装Traefik,K8S管理工具使用的Lens,详情见这篇文章。
创建Namespace
为方便管理,创建一个独立的namespace:
kubectl create ns traefik-system
获取云厂商AKSK和DNS读写权限
本文使用的为阿里云的域名,所以此处以阿里云举例。
首先你需要到阿里云控制台,鼠标移动到头像处,点击访问控制,进入RAM访问控制页面,
之后在身份管理-用户页面,创建一个新的用户:

此处仅需提供OpenAPI调用权限即可,该用户是提供给traefik使用以提供Https证书用的,创建后记下AccessKeyID和AccessKeySecret。
之后在权限管理-授权页面中,点击新增授权,授权主体选择刚才新建的用户名,权限给予DNS相关的完全权限:

配置完成后,在同命名空间下创建一个sercret,填写刚才创建用户时获得的AK和SK:
apiVersion: v1
kind: Secret
metadata:
name: alicloud-secret
namespace: traefik-system
data:
ALICLOUD_ACCESS_KEY: ${base64 access_key}
ALICLOUD_SECRET_KEY: ${base64 secret_key}
type: Opaque
安装Helm3.7.0+
官方安装指南说的非常详细,参照这里:Helm安装
一般都是推荐使用脚本进行安装,但我阿里云服务器在使用脚本时,对一个安装包的下载速度奇慢无比,没有办法,我使用了Ubuntu的Apt安装方式,这里给出官方的两种安装方式,其他方式请自行查询官方文档。
# 脚本方式
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
# or
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# APT方式(Debian/Ubuntu)
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
安装成功后,需要添加Traefik官方Helm仓库:
helm repo add traefik https://helm.traefik.io/traefik
配置额外的Values
使用Helm安装k8s应用时,需要使用values提供额外参数,这里我们使用deployment方式来部署traefik,同时将副本数设置为1,因为acme不支持daemonSet模式,所以在values的端口号配置我们使用hostPort的方式,将traefik的Pod端口和宿主机的端口绑定,同时使用nodeSelector将该副本固定在指定的node上(注意该node必须是你域名解析到的服务器),新建values.yaml文件:
additionalArguments:
- --providers.kubernetesingress.ingressclass=traefik # k8s ingress的class 名字叫做 traefik
- --certificatesresolvers.le.acme.dnschallenge.provider=alidns # 本文使用了阿里云的域名解析,所以provider使用alidns
- --certificatesresolvers.le.acme.storage=/data/acme.json # 路径要和下面的pvc匹配,用于存储证书缓存
- --certificatesresolvers.le.acme.email=hulu@hafuhafu.cn # 你的邮箱
#注意 这里的certificatesresolvers.le, le只是一个certResolver的名字,也就是我们可以配置多个resolver,独立的ingress中可以配置独立的resolver
envFrom:
- secretRef:
name: alicloud-secret
# 这里填写刚才我们创建的secret名字,注意需要在一个namespace中
ingressClass:
enabled: true # 开启ingressclass
fallbackApiVersion: ""
isDefaultClass: true
# 由于我们用了acme storage 所以需要pvc存储实际申请的证书的信息,空间不用太大 128m即可
persistence:
accessMode: ReadWriteOnce
annotations: {}
enabled: true
name: data
path: /data
size: 128Mi
storageClass: nfs-client # storageclass 根据需要填写你集群的存储类
ports:
metrics:
expose: false
exposedPort: 9100
port: 9100
protocol: TCP
traefik:
expose: false
exposedPort: 9000
port: 9000
protocol: TCP
web:
expose: true
exposedPort: 80
port: 80
hostPort: 80 # traefik将占用80端口来监听宿主机请求
protocol: TCP
redirectTo: websecure # 80端口将直接跳转至443
websecure:
expose: true
exposedPort: 443
port: 443
hostPort: 443 # traefik将占用443端口监听宿主机请求
protocol: TCP
tls:
certResolver: le # 配置默认的resolver名字,和上文一样
domains: # 配置的主域名和从泛域名, 这里只有匹配的域名才会自动加证书
- main: hafuhafu.cn
sans: # 注意 多级泛域名需要单独填写,不支持*.test.com 匹配a.b.c.test.com
- '*.hafuhafu.cn'
- '*.rancher.hafuhafu.cn'
enabled: true
options: ""
providers:
kubernetesCRD:
enabled: true
namespaces: []
kubernetesIngress:
enabled: true
namespaces: []
publishedService:
enabled: false
deployment:
enabled: true
kind: Deployment
replicas: 1
service:
enabled: true
type: ClusterIP # 可以选用ClusterIP / LoadBalancer
nodeSelector:
ingressHost: "yes" # 配置nodeSelector 使该副本固定在对应宿主机上
记得要在你域名解析的目标服务器上配置label: ingressHost=yes,不然会一直等待分配。
然后进行部署:
helm install traefik traefik/traefik -n traefik-system -f values.yaml
访问dashboard
在traefik-system命名空间中创建如下资源:
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`traefik.hafuhafu.cn`)
kind: Rule
services:
- kind: TraefikService
name: api@internal
之后应该就可以访问了:

注: 由于LE发证书需要一定的时间,受网络环境 集群性能影响,所以过快打开可能会出现证书错误的情况,traefik会默认使用traefik default的证书,可以通过看traefik pod的log来debug
创建Ingress资源
traefik有自己的自定义资源,就是上述的 IngressRoute ,该资源如何编写可以去看官方文档,这里只简要概述如何用原生Ingress资源编写应用路由:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foundryvtt
namespace: default
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: 'web,websecure' # 配置80和443两种入口
spec:
ingressClassName: traefik # 指定ingressClass
rules:
- host: trpg.hafuhafu.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: foundryvtt
port:
number: 80
结语
据说这些只是traefik的一小部分能力,这玩意非常强大,具体的可以查阅其文档,我也只是了解的非常浅。

参考文章:Traefik Automatic Https By Incubator4
通告: K8S搭建自己的企业级CICD(一)Github镜像仓库 – HuLuBlog