使用cert-manager在Kubernetes上全站自动HTTPS

cert-manager 是一套运行在Kubernetes环境之中的 TLS 证书的自动管理方案,经过了几年的开发,最近终于发布了稳定的1.0版本,今天就快速的入门一下。

安装

假设已经有一套可用的Kubernetes环境,也安装了Helm 3。 通过Helm 安装 cert-manager

# 创建独立的命名空间
kubectl create namespace cert-manager

# helm中添加仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update

# 安装
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.0.2 --set installCRDs=true

使用

创建ClusterIsser

创建下面的文件production-issuer.yaml,并把其中的email替换成自己实际的。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
 name: letsencrypt-prod
spec:
 acme:
   server: https://acme-v02.api.letsencrypt.org/directory
   # Email address used for ACME registration
   email: yourname@example
   # Name of a secret used to store the ACME account private key
   privateKeySecretRef:
     name: letsencrypt-prod
   # Enable the HTTP-01 challenge provider
   solvers:
   - http01:
       ingress:
         class: nginx

使其生效:

# 安装
kubectl apply -f production-issuer.yaml

# 查看
kubectl describe clusterissuer letsencrypt-prod

在项目中使用

使用比较简单,原理就是两个步骤:

  1. 在指定的ingress中的annotations添加一条: cert-manager.io/cluster-issuer: "letsencrypt-prod",用于声明需要谁去生成证书
  2. 在指定的ingress中的tls下,配置好域名和证书的secret。

具体例子如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kuard
  annotations:
    kubernetes.io/ingress.class: "nginx"    
    cert-manager.io/cluster-issuer: "letsencrypt-prod"  # <---- 声明由谁去生成证书
spec:
  tls:                       #  <---- 声明TLS
  - hosts:
    - example.example.com    # <---- 域名替换成实际的域名
    secretName: example-tls  # <---- secret的名字,可自定义
  rules:
  - host: example.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kuard
          servicePort: 80

验证:

# 查看证书请求(CertificateRequest)列表
kubectl get certificaterequest
# 详情
kubectl describe pod certificaterequest example-tls-xxx

# 查看证书
kubectl describe certificate example-tls

# 查看secret
kubectl describe secret example-tls

注意事项

  1. 我们使用的是http01方式进行验证域名所有权,所以需要在生成证书前,确保DNS的A记录已经配置并生效,否则会因验证失败而签发失效
  2. Let’s Encrypt生产环境的证书颁发频率限制很严格,可以考虑先创建Staging环境的issuer用于测试
  3. 我们为了方便直接创建的ClusterIssuer,可以为所有namespace创建证书,如果想更精确管理,可以创建Issuer
  4. 也可以考虑使用traefik作为ingress controller,可以完全自动管理TLS

参考链接