文章

kubernetes Ingress 自动签发SSL证书

现在的Web应用启用HTTPS服务是真的非常有必要的。一些正规机构颁发的CA证书费用又特别高,就算有免费的工具颁发证书,通过人工的方式手动注入到K8S比较麻烦,而且还需要到期后进行人工续期,若管理的证书过多,还无法颁发泛域名的话,那就更加麻烦了。

这里介绍一下免费的午餐 - Let's Encrypt,虽然只有90天的证书有效期,但是我们完全可以在证书失效之前,重新生成证书替换掉。在Kubernetes集群中就更方便了,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。

Cert-Manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt / HashiCorp / Vault 这些免费证书的签发。

cert-manager-structrue

SSL证书类型对比

image-20210824213412097

注意:使用Let’s Encrypt颁发的证书属于DV。

部署

我们这里用来管理 SSL/TLS 证书的组件是Cert manager,它对于每一个 ingress endpoint 将会自动创建一个新的证书,当 certificates 过期时还能自动更新,除此之外,Cert manager 也可以和其它的 providers 一起工作,例如 HashiCorp Vault。这里我们介绍两种部署方式:

Yaml文件部署

image-20210824222619294

Helm3 部署

image-20210824222608931

在使用的时候我们需要配置一个缺省的cluster issuer,当部署 Cert manager 的时候,用于支持kubernetes.io/tls-acme: "true"annotation 来自动化 TLS。

安装完成后,然后查看Pod运行状态:

image-20210824222456744

除此之外,安装完成后Cert manager还提供了一些Kubernetes custom resources

image-20210824222344367

证书签发服务

Cert manager安装后,接下来需要定义上面的 letsencrypt-prod 这个 cluster issuer,这里使用上面的clusterissuers.certmanager.k8s.io这个CRD来定义:(cluster-issuer-letsencrypt-prod.yaml)

image-20210824222329501

然后直接创建这个 ClusterIssuer 资源:

image-20210824222313432

注意:上面配置的是生产环境,你还可以配置staging环境来测试。Let’s Encrypt 测试环境与生产环境的区别

颁发速率限制

下面是 Let's Encrypt 测试环境和生产环境速率限制的对比:

测试环境

ACME V2 测试环境为:

 https://acme-staging-v02.api.letsencrypt.org/directory
  • 每个注册域名允许颁发的证书数量限制为每周 30000 张。

  • 重复证书限制为每周 30000 张。

  • 每小时允许 60 次验证失败

  • 每个 IP 地址注册账户数量限制为每个 IP 每 3 小时允许注册 50 个账户。

  • 对于 ACME v2,新订单限制为每个帐户每 3 小时 1500 个。

生产环境

  • 每个注册域名的证书数量(每周 50 张)

  • 续期证书遵守特殊规则:它们不计入您的每个注册域名的证书数量的限制,但它们受到每周最多 5 张重复证书的限制(一张证书包含的域名与以前某张证书的完全相同,它会被视为对之前证书的续期证书或重复证书)

  • 每个账户每小时每域名有最多验证失败 5 次的限制。

切记在使用我们的正式环境以前,强烈建议您使用测试环境进行测试性部署,这将允许您在颁发受信任的证书前确保一切正常,并且降低您受到速率限制的可能性。

验证

上面我们已经安装了 Cert manager,定义了 ClusterIssuer ,接下来我们来配置 HTTPS 去访问我们的 Nginx服务,Nginx 的部署我们这里就不多说了,直接添加一个 Ingress 资源对象即可:(nginx-ingress.yaml)

image-20210824222250842

这里需要注意的是上面我们添加的annotations非常重要,这个将告诉 Cert Manager 去生成证书,然后由于我们这里要使用 HTTPS,所以我们需要添加一个 tls 证书,而证书就是通过nginx-demo-tls这个 Secret 对象来提供的,要注意的是这个 Secret 对象并不是我们手动创建的,而是 Cert Manager 自动创建的证书对应的对应。然后直接创建这个资源对象即可:

image-20210824222222908

当然如果需要在公网中进行访问,我们还需要将我们这里的域名解析到 Ingress Controller 所在的任意一个节点,或者在本地的/etc/hosts中加上映射也是可以的。

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

image-20210824222159351

到这里我们就完成了使用 Let's Encrypt 实现 Kubernetes Ingress 自动化 HTTPS。

但是若大家在使用该工具实现自动化HTTPS的同时,一定要有 Plan B 可以快速通过人工的方式部署K8S Ingress所需的证书,之前我就出现过 Let's Encrypt 生产环境达到速率限制,不得不等待一周再去重新颁发的情况。

参考

Cert Manager 官网

Cert Manager Github

License:  CC BY 4.0