Traefik Automatic Https
前言
traefik 是 Containous 团队推出的一款 ingress 工具,相比 nginx 而言它有着更友好的 dashboard UI 界面
并且支持二进制部署, docker kubernetes 等多种运维平台的原生支持方案,还能在 dashboard 面板中看到整体路由服务的健康情况
以及其他的,traefik 也可以接入 metrics 支持
原理介绍
traefik 自动化 https 的方式使用 Let’s Encrypt 实现,所以我们需要开启 acme
traefik 原生支持三种自动 https 的方式 httpChallenge
tlsChallenge
和 dnsChallenge
其中 http 和 tls 的方式需要 80 和 443 端口能被访问到,相当于 le 的服务会亲自验证你的网站是否能够被访问,而后会添加可信证书。
dnsChallenge 的方式则是使用云服务商的 dns 管理功能来实现验证该域名是否属于你,验证成功之后就会发布 https 证书
安装
创建 namespace
为了方便管理,创建一个独立的 namespace
kubectl create ns traefik-system
获取云厂商 AKSK
traefik 支持如下供应商 这里我用的是阿里云账户,为了最小化权限管理,使用了 RAM 账户,获取 RAM 账户的 AKSK 之后,记得给账户添加读写权限,这里给 AKSK 创建一个 secret
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
helm 安装
traefik helm chart github在这里
我们需要 helm 3.0 版本以上
首先添加 traefik 的 helm repo
helm repo add traefik https://helm.traefik.io/traefik
配置额外的 values
新建一个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匹配
- --[email protected]
#注意 这里的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: 8000
# hostPort: 8000
protocol: TCP
websecure:
expose: true
exposedPort: 443
port: 8443
# hostPort: 8443
protocol: TCP
tls:
certResolver: le # 配置默认的resolver名字,和上文一样
domains: # 配置的主域名和从泛域名, 这里只有匹配的域名才会自动加证书
- main: incubator4.com
sans: # 注意 多级泛域名需要单独填写,不支持*.test.com 匹配a.b.c.test.com
- "*.incubator4.com"
- "*.rancher.incubator4.com"
enabled: true
options: ""
providers:
kubernetesCRD:
enabled: true
namespaces: []
kubernetesIngress:
enabled: true
namespaces: []
publishedService:
enabled: false
deployment:
enabled: true
kind: Deployment # 可以选择Daemonset的形式
replicas: 1
service:
enabled: true
type: ClusterIP # 可以选用ClusterIP / LoadBalancer
根据集群具体情况使用 deployment 还是 daemonset
请各位同学根据自己情况斟酌使用哪种方式
使用 daemonset
daemonset 使用 node selector 使得 pod 落到特定的 node 上,启用 hostport 让容器绑定该机器的物理端口,可以直接用 node-ip:node-port 访问 pod。
PC -> node Port -> pod port
这种方式不经过 svc,适用于 裸金属 kubernetes,能直接通过 ip 连接到 node 节点的情况
使用 deployment
众所周知,云厂商提供了 LoadBalancer 的形式,使得创建的 service 具有一个公网 IP,可以在外网(或者内网,一般指集群外)直接访问 service 这种方式使用 loadbalance 形式的 service 为 traefik deployment 提供负载均衡 而后直接访问 loadbalance 的 ip 就相当于直接访问到 traefik 的 svc 了
部署
一句话
helm install traefik traefik/traefik -n traefik-system -f values.yaml
访问 dashboard
在 traefik-system 中创建如下资源
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.incubator4.com`)
kind: Rule
services:
- kind: TraefikService
name: api@internal
应用之后就可以通过 http 访问了
测试自动加密证书
在上文 yaml 资源中的 entryPoint 添加一个 websecure,如下所示
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`traefik.incubator4.com`)
kind: Rule
services:
- kind: TraefikService
name: api@internal
部署完成之后,把协议修改成 https 即可
注: 由于 LE 发证书需要一定的时间,受网络环境 集群性能影响,所以过快打开可能会出现证书错误的情况,traefik 会默认使用 traefik default 的证书,可以通过看 traefik pod 的 log 来 debug