Kubernetes 是一个开源容器编排平台,可以帮助用户管理容器的生命周期。而 Nginx Ingress 则是 Kubernetes 中常用的一种 Ingress Controller,允许将外部流量路由到 Kubernetes 集群内的不同服务。
在实际生产环境中,安全性和稳定性是必须考虑的问题。因此,在使用 Kubernetes 进行应用部署时,除了要考虑应用性能和可用性之外,还需要关注证书的配置和管理。
在本文中,我们将介绍如何使用 Kubernetes Nginx Ingress 进行 HTTPS 证书的配置和自动续期。
环境准备
- Kubernetes 集群
- Helm
- cert-manager
本文采用的 Kubernetes 版本为 v1.20.0。
安装 Helm
Helm 是 Kubernetes 的一个包管理工具,能够帮助用户方便地部署应用。
# 下载 Helm 安装包 $ wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz # 解压 Helm 安装包 $ tar -zxvf helm-v3.2.4-linux-amd64.tar.gz # 将 Helm 可执行文件移动到 $PATH 路径下 $ mv linux-amd64/helm /usr/local/bin/helm # 验证 Helm 是否安装成功 $ helm version
安装 cert-manager
cert-manager 是一个 Kubernetes 下的证书管理工具,可以帮助用户自动化配置、颁发、续期和管理 SSL/TLS 证书。
# 添加 cert-manager 的 Helm 仓库 $ helm repo add jetstack https://charts.jetstack.io # 创建 cert-manager 的命名空间 $ kubectl create namespace cert-manager # 安装 cert-manager 应用 $ helm install \ cert-manager \ jetstack/cert-manager \ --namespace cert-manager \ --version v0.15.1
安装完毕后,可以使用以下命令验证 cert-manager 是否正确安装:
$ kubectl get pods --namespace cert-manager
如果输出的结果为以下信息,则说明 cert-manager 安装成功:
NAME READY STATUS RESTARTS AGE cert-manager-7bddf9cf89-xcx7l 1/1 Running 0 10s cert-manager-cainjector-5f555f9cb5-b44bj 1/1 Running 0 10s cert-manager-webhook-79588f6f9f-r7vx5 1/1 Running 0 10s
证书颁发流程
在 Kubernetes 环境中,证书的颁发流程如下:
- 创建一个 Issuer 或者 ClusterIssuer 资源,用于告诉 cert-manager 如何颁发证书。
- 创建一个 Certificate 资源,告诉 cert-manager 需要颁发哪个域名的证书。
创建 Issuer
使用 Issuer 可以颁发针对单个命名空间内的证书。而 ClusterIssuer 则可以在整个集群范围内颁发证书。
以下是创建 Issuer 的示例 YAML 文件:
apiVersion: cert-manager.io/v1alpha2 kind: Issuer metadata: name: letsencrypt namespace: cert-manager spec: acme: email: admin@example.com # LetsEncrypt 账号邮箱 server: https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt ACME 服务器地址 privateKeySecretRef: name: letsencrypt solvers: - selector: dnsZones: - example.com # 域名 http01: ingress: class: nginx
其中,letsencrypt
为 Issuer 的名称,cert-manager
为命名空间。在 acme
字段中,需要填写 Let's Encrypt 账号邮箱和 ACME 服务器地址。
此外,在 solvers
字段中,我们使用了 http01
的方式进行域名验证。这种方式需要在 Ingress 中添加相应的注解,使得 cert-manager 能够通过访问网站获取 Token。
创建 Certificate
创建 Certificate 资源前,需要先将域名绑定到 Kubernetes Ingress 上。以下是一个示例 YAML 文件:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: default annotations: # 使用 Nginx Ingress 进行代理 kubernetes.io/ingress.class: nginx # 配置 http01 模式,用于域名验证 cert-manager.io/issuer: letsencrypt cert-manager.io/acme-challenge-type: http01 spec: tls: - hosts: - example.com # 域名 secretName: example-tls # 生成的证书密钥名称 rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-service port: number: 80
接下来,可以创建 Certificate 资源:
apiVersion: cert-manager.io/v1alpha2 kind: Certificate metadata: name: example-tls namespace: default spec: secretName: example-tls commonName: example.com dnsNames: - example.com acme: config: - http01: ingressClass: nginx domains: - example.com privateKeySecretRef: name: example-tls issuerRef: name: letsencrypt kind: Issuer
其中,example-tls
为密钥证书名称,example.com
为颁发证书的域名。
自动续期
使用 cert-manager 颁发的证书默认有效期为 90 天。为了确保证书长期可用,需要进行自动续期。
在 Kubernetes 中,证书续期的具体实现方式为设置 CronJob 定时任务,周期性更新证书。
以下是一个自动续期的 CronJob 配置示例:
apiVersion: batch/v1beta1 kind: CronJob metadata: name: example-tls-renew namespace: default spec: schedule: "0 0 * * *" # 定时任务执行时间,每天凌晨 0 点执行 jobTemplate: spec: template: spec: containers: - name: cert-renew image: certbot/certbot command: - /bin/sh - -c - > certbot renew --webroot --webroot-path /webroot --cert-name example-tls --deploy-hook "[[ -f /webroot/deploy-hook.sh ]] && sh /webroot/deploy-hook.sh" restartPolicy: OnFailure volumes: - name: webroot persistentVolumeClaim: claimName: webroot-pvc
该定时任务使用 certbot/certbot
镜像,在 /webroot
目录下存储了 Challange Tokens,进行证书续期时需要先验证 Token 合法性。
在 command
字段中,执行了 certbot renew
命令,表示续期证书。其中,--cert-name
指定需要续期的证书名称。
在 --deploy-hook
中,可以执行自定义脚本进行部署应用时的一些操作。
总结
本文介绍了在 Kubernetes 中使用 Nginx Ingress 进行 HTTPS 证书的配置和自动续期的方法,具有实际的指导意义和学习价值。
使用 cert-manager 颁发和管理证书,能够帮助用户在 Kubernetes 集群中快速部署应用,提高应用的可用性和安全性。同时,在处理证书续期问题时,使用定时任务可以大大降低了管理成本,并提高了工作流程的可持续性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b0b457add4f0e0ffa0df5a