Kubernetes Nginx Ingress 搭建域名 https 证书及自动续期

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 安装成功:

证书颁发流程

在 Kubernetes 环境中,证书的颁发流程如下:

  1. 创建一个 Issuer 或者 ClusterIssuer 资源,用于告诉 cert-manager 如何颁发证书。
  2. 创建一个 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