随着 HTTPS 不断普及,大多数网站开始由 HTTP 升级到 HTTPS。使用 HTTPS 需要向权威机构申请CA证书,并且需要付出一定的成本,如果需求数量多,则开支也相对增加。证书过期,是个让人很头疼的问题。需要定期的去renew证书,就会比较麻烦,而且很容易遗忘。Cert-manager 是 Kubernetes 上的全能证书管理工具,支持利用 Cert-Manager 基于ACME(Automatic Certificate Management Environment)协议与Let's Encrypt签发免费证书并为证书自动续期,实现永久免费使用证书。
Cert-Manager用于在Kubernetes集群中自动管理和颁发来自各种颁发源的 TLS 证书,它可以从各种受支持的来源颁发证书,包括Let's Encrypt、HashiCorp Vault和Venafi以及私有PKI,它将确保证书定期有效和更新,并在到期前的适当时间尝试更新证书。
Cert-Manager官方给出的架构图,可以看到Cert-Manager在K8S中定义了两个自定义类型资源:Issuer和Certificate。
其中Issuer代表的是证书颁发者,可以定义各种提供者的证书颁发者,当前支持基于、Let's Encrypt/vault和自签名等证书颁发者,还可以定义不同环境下的证书颁发者。
Certificate代表的是生成证书的信息数据,一般其中存入生成证书的元信息,如域名等等。
一旦在K8S中定义了上述两类资源,部署的Cert-Manager则会根据Issuer和Certificate生成TLS证书,并将证书保存进K8S的Secret资源中,然后在Ingress资源中就可以引用到这些生成的Secret资源。对于已经生成的证书,还会定期检查证书的有效期,如即将超过有效期,还会自动续期。
Let's Encrypt和ACME协议的目标是使配置能够自动获取受信任浏览器的证书的HTTPS服务器成为可能。这是通过在Web服务器上运行证书管理软件(Agent)来达成的。该流程分为两步。首先,管理软件向证书颁发机构证明该服务器拥有域名的控制权。之后,该管理软件就可以申请、续期或吊销该域名的证书。
Let's Encrypt通过公钥识别服务器管理员。证书管理软件首次与Let's Encrypt交互时,会生成新的密钥对,并向Let's Encrypt CA证明服务器控制着一个或多个域名。这类似于创建帐户和向该帐户添加域名的传统证书颁发流程。
Let's Encrypt利用ACME协议校验域名的归属,校验成功后可以自动颁发免费证书。免费证书有效期只有90天,需在到期前再校验一次实现续期。使用 Cert-Manager可以自动续期,即实现永久使用免费证书。
本文将通过在OCI云上,在Kubernetes环境中,使用Cert-Manager和Let’s Encrypt自动管理应用证书的创建和更新的过程。
环境准备:
Kubernetes环境
使用OCI 部署好的OKE实例。
OCI DNS资源
使用申请好的testoci.xyz域名,托管在OCI DNS服务上。
运行命令:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml
使用helm工具,安装Cert-Manager-Webhook for OCI,webhook使Cert-Manager的Issuer对象可以使用DNS校验机制,验证OCI DNS 域名资源。
运行命令:
helm repo add cert-manager-webhook-oci https://dn13.gitlab.io/cert-manager-webhook-oci
helm install cert-manager-webhook-oci
cert-manager-webhook-oci/cert-manager-webhook-oci
生成Secret oci_profile,供Issuer使用.oci_profile Secret包含了Cert-Manager OCI webhook需要用到的参数信息。需要配置region tenancy user private key fingerprint compartment信息,具体配置流程参考OCI API权限配置相关内容。
https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm
运行命令,确保Secret创建完成。
kubectl apply -f oci-profile.yaml
创建名称为 letsencrypt-ocidns 的Issuer配置文件中,server的URL指向Let's Encrypt的ACME tls证书管理地址,如果是在测试环境中,可以指向staging测试的tls证书管理地址。Let's Encrypt将使用DNS的校验方式,通过oci的webhook完成DNS域名的校验,ociProfileSecretName变量指向创建的oci-profile Secret,Compartment OCID指向OCI DNS上托管的域名的Compartment。
运行命令:
kubectl apply -f let-encrypt-issuer-ocidns.yaml
查看Issuer letsencrypt的Ready 状态为True,Issuer创建成功。
配置文件中dnsNames指定域名,通过dns校验方式,可以使用通配符域名,secretName指向Kubernetes中存放tls证书的Secret名称,IssuerRef指向创建的Iusser。
运行命令:
kubectl apply -f certificate-let-encrypt-ocidns.yaml
查看Certificate的状态,Ready为True表示证书签发成功,可以使用。
在OKE集群中,使用Nginx Ingress Controler对外暴露Web应用,Ngnix Ingress Controler的部署过程参加官方文档。
在Ingress配置文件中,hosts指向OCI DNS配置的域名hello-ingress.testoci.xyz,secretName指向Certificate生成的secret app-lets-encrept-oci-dns-tls。
通过命令,查看Nginx Ingress Controller的Public IP地址为132.226.239.140。
在OCI DNS上,在testoci.xyz域名管理下,增加A记录指向Nginx Ingress Controller的Public IP地址。
在浏览器通过域名访问发布的Web应用,发现Let's Encrypt签发的证书已经应用,网站加上的“安全锁”的标记,表明网站的连接是安全的。
点击查看证书信息,查看证书颁发组织/过期时间/域名等信息。
查看签发的certificate信息,过期时间“notAfter”,重新签发时间“renewalTime”.Cert-Manager负责certifcate的管理, 会在证书的重新签发时间,自动通过证书的签发机构,重新请求签发新的CA证书,保证证书的自动更新,省去手动更新配置CA证书的操作。
通过以上操作,在OCI的OKE环境中,可以看到通过Cert-Manager和Let‘s Encrypt,可以自动管理管理Kubernetes环境中CA证书的自动分发和管理工作。
更多OCI OKE和 DNS信息请访问:
https://docs.oracle.com/en-us/iaas/Content/ContEng/home.htm
https://www.oracle.com/cloud/networking/dns/
作者简介
向志华,甲骨文云架构团队资深咨询顾问,专注 Application PaaS 产品及服务,同时关注Docker容器产品及Kubernetes容器调度产品方向。13年IT行业从业经验,擅长J2EE产品架构及开发,参与过Openstack相关产品研发工作。您可以通过george.xiang@oracle.com,与他联系。