使用 Cert Manager 为 Kubernetes 应用自动签发 HTTPS 证书

Cert-Manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt / HashiCorp / Vault 这些免费证书的签发。在 Kubernetes 中,可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS

此文章按照 Cert Manager 官网 的推荐步骤, 使用 helm3 安装并配置 Cert-Manager

安装 Helm3

若你还未安装 Helm3, 可参考我的 这篇文章 安装 Helm

安装 Cert-Manager

创建 CustomResourceDefinition 用户自定义资源

# 针对 Kubernetes 1.15+ 以上版本使用以下命令
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.14.0/cert-manager.crds.yaml

customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created

创建命名空间

我使用的命名空间为 cluster-service,替换为你自己的命名空间:

$ kubectl create namespace cluster-service

namespace/cluster-service created

添加 Jetstack Helm 仓库

$ helm repo add jetstack https://charts.jetstack.io

更新 Helm 仓库

$ helm repo update

安装 Cert Manager

# Helm v3+
$ helm install \
  cert-manager jetstack/cert-manager \
  --namespace cluster-service \
  --version v0.14.0


NAME: cert-manager
LAST DEPLOYED: Fri Mar 27 06:26:00 2020
NAMESPACE: cluster-service
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://docs.cert-manager.io/en/latest/reference/issuers.html

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://docs.cert-manager.io/en/latest/reference/ingress-shim.html

安装成功, 查看安装结果

我使用的 Kubernetes 管理界面是 Kuboard

1585290595100

配置 Issuer 或 Clusterissuer

官方介绍这中 Issuer 与 ClusterIssuer 的概念:

Issuers, and ClusterIssuers, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request.

Issuer 与 ClusterIssuer 的区别是 ClusterIssuer 可跨命名空间使用,而 Issuer 需在每个命名空间下配置后才可使用。我在此使用ClusterIssuer,其类型选择 Let‘s Encrypt

配置 staging 环境使用的 Let‘s Encrypt ClusterIssuer,并创建:

# cluster-issuer-letsencrypt-staging.yaml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # 务必将此处替换为你自己的邮箱, 否则会配置失败。当证书快过期时 Let's Encrypt 会与你联系
    email: user@example.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # 将用来存储 Private Key 的 Secret 资源
      name: letsencrypt-staging
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx
$ kubectl create -f cluster-issuer-letsencrypt-staging.yaml

clusterissuer.cert-manager.io/letsencrypt-staging created

配置 production 环境使用的 Let‘s Encrypt ClusterIssuer,并创建:

# cluster-issuer-letsencrypt-prod.yaml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: varroreve@gmail.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx
$ kubectl create -f cluster-issuer-letsencrypt-prod.yaml

clusterissuer.cert-manager.io/letsencrypt-prod created

查看:

$ kubectl get clusterissuer

NAME                  READY   AGE
letsencrypt-prod      True    37s
letsencrypt-staging   True    119m

这里分别配置了测试环境与生产环境两个 ClusterIssuer, 原因是 Let’s Encrypt 的生产环境有着非常严格的接口调用限制,最好是在测试环境测试通过后,再切换为生产环境。

Let’s Encrypt 测试环境与生产环境的区别

测试

这里我假设你已安装好 Nginx Ingress Controller 并已存在一个 Ingress 对象,现在为它开启 TLS 选项

# quickstart-example.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kuard
  annotations:
    # 务必添加以下两个注解, 指定 ingress 类型及使用哪个 cluster-issuer
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer:"letsencrypt-staging"

    # 如果你使用 issuer, 使用以下注解 
    # cert-manager.io/issuer: "letsencrypt-staging"

spec:
  tls:
  - hosts:
    - example.example.com                # TLS 域名
    secretName: quickstart-example-tls   # 用于存储证书的 Secret 对象名字 
  rules:
  - host: example.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kuard
          servicePort: 80

应用此更新

$ kubectl create -f quickstart-example.yaml

之后 Cert-manager 会读取注解并创建证书,使用以下命令查看:

$ kubectl get certificate -A

NAME                     READY   SECRET                   AGE
quickstart-example-tls   True    quickstart-example-tls   16m

当 Ready 为 True 时代表证书安装成功若出现问题可使用 descirbe 命令查看具体出错原因:

$ kubectl describe certificate -A 

切换到生产环境

当一切就绪后,将 Ingress 对象中的 cluster-issuer 注解改为 Let’s Encrypt 生产环境

# quickstart-example.yaml

cert-manager.io/cluster-issuer: "letsencrypt-prod"

更新 Ingress 后访问你的网站,应该可以看到 HTTPS 证书配置

1585373007182

1585373024926

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!