Traefik Automatic Https

前言

traefik 是 Containous 团队推出的一款 ingress 工具,相比 nginx 而言它有着更友好的 dashboard UI 界面

traefik webui

并且支持二进制部署, docker kubernetes 等多种运维平台的原生支持方案,还能在 dashboard 面板中看到整体路由服务的健康情况

traefik webui path

以及其他的,traefik 也可以接入 metrics 支持

原理介绍

traefik 自动化 https 的方式使用 Let’s Encrypt 实现,所以我们需要开启 acme traefik 原生支持三种自动 https 的方式 httpChallenge tlsChallengednsChallenge

其中 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 访问了

dashboard

测试自动加密证书

在上文 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 即可

https-dashboard

注: 由于 LE 发证书需要一定的时间,受网络环境 集群性能影响,所以过快打开可能会出现证书错误的情况,traefik 会默认使用 traefik default 的证书,可以通过看 traefik pod 的 log 来 debug