在k8s中将内部service暴露到集群外一般采用ingress,而比较常用的ingress controller是NGINX Ingress Controller。 而一般证书会存于nginx, nginx作为endpoint用于tls的认证。采用Let’s Encrypt证书生成浏览器信任的免费证书,并在k8s环境中生效的常用方法有以下:
方法1 原始办法,直接使用certbot
即支持ACME协议(协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)的Let's Encrypt提供的客户端, 来生成浏览器信任的数字证书。
certbot-auto certonly
--manual
--email liuzhicong@xxx
--server https://acme-v02.api.letsencrypt.org/directory
--agree-tos -d *.yourdomain.com
此命令可以生成域名*.yourdomain.com的通配符证书(命令运行过程中会要求在域名DNS设置中生成指定TXT记录用于认证域名拥有者,按指示操作即可)。然后将此证书以k8s 的secret的形式配置到相应deployment的对应的service所对应的ingress上。配置方式可见方法2。
注意:
- 使用
certbot-auto需要指定认证方式, 认证方式有HTTP 01和DNS 01,HTTP 01不支持生成通配符证书,DNS 01需要在DNS上添加指定的TXT记录 cerbot客户端使用DNS 01时可运行在任何主机上- 直接使用
cerbot生成证书无法实现证书即将过期自动更新(Let's Encrypt证书三月有效期, 过期前有邮件通知)。 - 使用Let’s Encrypt生成证书对证书生成数有限制。
方法2, 云原生风格,参考此教程
其可实现证书在3个月后的自动更新。是主要步骤包括:
- 使用
helm安装certmanager, 用于证书Certificate和证书签发者ClusterIssuer的管理, 并实现证书到期前的自动更新。 kubectl创建issuer(Let's Encryt)kubectl创建certificate- 将
certificate配置到ingress上。
注意:
- 关于创建认证方式是
DNS 01的issuer, 若DNS提供商是阿里云, 暂未尝试到配置办法。 - 使用文中的
HTTP 01认证方式可以通用各类DNS提供商, 虽然证书不具有域名通配符, 但可以通过一个证书, 对应多个域名的办法去配置。 Certificate和CertificateIssuer均为kubernetes CRD, 生成证书的实现原理与方法1相同, 但通过kubernetes CRD会使得配置过程更灵活和自动化。- 对于特殊配置项, 如
api转发代理, 数据代理等在kubernetes环境下配置https,需要在ingress上增加若干annotation, 具体内容与ingress controller版本与业务需求有关, 参见。 kubectl get certificate发现证书签发失败或状态异常, 可查看cert-manager的日志信息。- 若发现证书没有自动更新, 普遍的情况是证书对应的
ClusterIssuer运行不正常, 可通过kubectl describe certificates certName查看证书对应的ClusterIssuer, 然后kubectl get ClusterIssuer去进一步查看ClusterIssuer的状态。 cert-manager的三个pod必须均处于运行状态才能保证证书颁发流程正常,已经能在证书过期前自动更新证书。
kubectl get pods -n cert-manager
- 更详细的部署和排错方法见此
总结
ingress controller的nginx版本跟平常用的nginx没啥区别, 通过nginx的ingress controller可以了解在kubernetes环境下将服务暴露出去的工作原理,实际上跟普通的nginx区别不大。只是ingress和ingress controller实现方式更具有解耦性。Kubernetes CRD有无限的想象空间, 通过对常见的运维任务和部署任务的抽象, 使其以kubernetes object的形式存在和管理调度,可以大大简化和优化日常运维。- 由于证书是配置在
ingress上的, 所以ingress后(k8s内部)的流量实际上可能是是明文传输的。例如访问一个外部请求访问https://www.mydomain.cc域名对应的服务, 流量到达k8s节点A上后, 节点A上的nginx ingress controller将请求交给域名对应的ingress,ingress将数据报文解密, 再将请求交给对应service,service再作loadbalancing(实际上是在节点上查找iptable上的记录), 将请求转发到服务对应的endpoint, 最后服务对应的pod处理请求。 若pod不在节点A上, 则会将请求转发到服务对应的pod所在的节点B。因此节点A和B之间的流量转发有可能是明文传输(pod-to-pod or service-to-service communication)。
解决办法:- 采用有数据报文加密功能的CNI
- 采用服务网格,例如istio, isitio 环境下原生支持cert-manager
- 应用本身作为加密和解密端, 即将
web service直接上https
最后
以上就是勤恳豌豆最近收集整理的关于Kubernetes环境使用Let's Encrypt证书的部署方法的全部内容,更多相关Kubernetes环境使用Let's内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复