WEBKT

Kubernetes服务自动化HTTPS:Ingress与Cert-Manager实战

87 0 0 0

最近有个新服务要上线,作为后端开发,我知道HTTPS是现在标配,但一想到要在Kubernetes里搞TLS证书、配置Ingress,还不能老是手动更新证书,就感觉一团乱麻。相信不少后端同学也有类似困惑。别担心,今天就手把手教你如何利用 IngressCert-Manager,搭配 Let's Encrypt,实现Kubernetes服务自动化HTTPS,从此告别证书焦虑!

1. 理清思路:我们需要什么?

我们最终目标是:

  1. 服务上线:一个运行在Kubernetes里的后端服务。
  2. HTTPS访问:外部用户通过https://your-domain.com访问到我们的服务。
  3. 证书自动化:TLS证书能够自动申请、自动续期,不用我们操心。

为了实现这些,Kubernetes生态中有几个关键角色:

  • Deployment & Service:部署你的后端应用并对外暴露(通常是ClusterIP类型)。
  • Ingress Controller:集群内部的流量入口,通常是Nginx Ingress Controller或Traefik等,负责将外部请求路由到正确的Service。
  • Ingress:Kubernetes资源对象,定义了外部流量如何路由到集群内部的服务,以及TLS配置。
  • Cert-Manager:一个Kubernetes附加组件,用于自动化地管理和签发TLS证书,支持Let's Encrypt等多种CA。
  • Let's Encrypt:一个免费、开放、自动化的证书颁发机构。

2. 前置准备

在开始之前,请确保你的Kubernetes集群已经满足以下条件:

  • Ingress Controller已安装:例如Nginx Ingress Controller。如果没装,可以参考官方文档安装。
  • 有一个可用的域名:并解析到你的Ingress Controller的外部IP或负载均衡器上。

3. 安装 Cert-Manager

Cert-Manager是自动化证书管理的核心。我们通过Helm来安装它,这是最推荐的方式:

# 1. 添加Cert-Manager Helm仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update

# 2. 安装Cert-Manager
# 建议安装最新稳定版本,这里以v1.13.0为例,请根据实际情况调整
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.crds.yaml
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.13.0 \
  --set installCRDs=true # 如果已经手动安装CRDs,这里可以省略或设置为false

安装完成后,检查cert-manager命名空间下的所有Pod是否都已Running

4. 配置 Issuer 或 ClusterIssuer

IssuerClusterIssuer 是Cert-Manager用来与证书颁发机构(如Let's Encrypt)交互的资源。

  • Issuer:只能在其所在的命名空间中颁发证书。
  • ClusterIssuer:可以为集群中任何命名空间颁发证书,更常用,因为它提供更广的适用性。

这里我们配置一个ClusterIssuer,使用Let's Encrypt的staging环境(用于测试,避免达到生产环境的速率限制)和production环境。

4.1 Let's Encrypt Staging ClusterIssuer (测试环境)

创建一个letencrypt-staging-clusterissuer.yaml文件:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    email: your-email@example.com # 替换为你的邮箱,用于接收证书通知
    server: https://acme-staging-v02.api.letsencrypt.org/directory # Let's Encrypt测试环境
    privateKeySecretRef:
      name: letsencrypt-staging-private-key # 用于存储ACME账户私钥
    solvers:
    - http01: # 使用HTTP-01挑战,需要Ingress Controller支持
        ingress:
          class: nginx # 如果你使用其他Ingress Controller,请替换为对应的class

应用配置:

kubectl apply -f letencrypt-staging-clusterissuer.yaml

4.2 Let's Encrypt Production ClusterIssuer (生产环境)

测试成功后,我们将使用生产环境。创建一个letencrypt-production-clusterissuer.yaml文件:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: your-email@example.com # 替换为你的邮箱
    server: https://acme-v02.api.letsencrypt.org/directory # Let's Encrypt生产环境
    privateKeySecretRef:
      name: letsencrypt-prod-private-key
    solvers:
    - http01:
        ingress:
          class: nginx

应用配置:

kubectl apply -f letencrypt-production-clusterissuer.yaml

注意your-email@example.com非常重要,Let's Encrypt会通过此邮箱发送证书到期通知。

5. 部署你的服务和Ingress

假设你已经有了一个后端服务,例如一个名为my-backend-serviceService,暴露在端口80。现在我们来创建DeploymentService(如果还没有),然后配置Ingress

5.1 示例应用 Deployment & Service (如果已有可跳过)

创建一个my-app.yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-backend
  labels:
    app: my-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-backend
  template:
    metadata:
      labels:
        app: my-backend
    spec:
      containers:
      - name: my-backend
        image: nginx:latest # 替换为你的后端服务镜像
        ports:
        - containerPort: 80 # 你的服务监听端口
---
apiVersion: v1
kind: Service
metadata:
  name: my-backend-service
spec:
  selector:
    app: my-backend
  ports:
    - protocol: TCP
      port: 80 # Service暴露的端口
      targetPort: 80 # Pod监听的端口
  type: ClusterIP

应用配置:

kubectl apply -f my-app.yaml

5.2 配置 Ingress 启用 HTTPS

现在是最关键的一步!我们将创建一个Ingress资源,它会告诉Ingress Controller如何路由流量,同时通过cert-manager.io/cluster-issuer注解,让Cert-Manager自动为我们申请和管理TLS证书。

创建一个my-ingress.yaml文件:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-backend-ingress
  annotations:
    kubernetes.io/ingress.class: nginx # 指定你的Ingress Controller类型
    cert-manager.io/cluster-issuer: letsencrypt-staging # 或者 letsencrypt-prod
    nginx.ingress.kubernetes.io/rewrite-target: /$1 # 如果你的后端路径需要重写
spec:
  tls:
    - hosts:
        - your-domain.com # 替换为你的域名
      secretName: my-backend-tls-secret # Cert-Manager会将证书存储到这个Secret中
  rules:
    - host: your-domain.com # 替换为你的域名
      http:
        paths:
          - path: / # 匹配所有路径,可以根据需要调整
            pathType: Prefix
            backend:
              service:
                name: my-backend-service # 你的Service名称
                port:
                  number: 80 # 你的Service端口

注意

  • 一开始建议使用 letsencrypt-staging 进行测试,避免生产环境速率限制。
  • 确认your-domain.com已经指向你的Ingress Controller的外部IP。
  • secretName是Cert-Manager存放证书的Kubernetes Secret的名字,无需提前创建。

应用配置:

kubectl apply -f my-ingress.yaml

6. 验证证书状态

部署Ingress后,Cert-Manager会开始工作:

  1. 它会看到Ingress上的cert-manager.io/cluster-issuer注解。
  2. 创建一个Certificate资源(你也可以手动创建)。
  3. 创建一个OrderChallenge来完成Let's Encrypt的验证。
  4. 当挑战成功后,Let's Encrypt签发证书。
  5. Cert-Manager获取证书并将其存储到一个名为 my-backend-tls-secretSecret中。
  6. Ingress Controller会自动加载这个Secret中的证书。

你可以通过以下命令查看Certificate的状态:

kubectl get certificate
kubectl describe certificate my-backend-tls-secret # 替换为你的secretName

Status中的Ready显示为True时,说明证书已经成功签发并可用。

7. 测试你的服务

现在,打开浏览器,访问 https://your-domain.com (替换为你的域名)。你应该能看到你的服务通过HTTPS安全地运行了!浏览器会显示安全连接,证书信息也会显示由Let's Encrypt签发。

8. 切换到生产环境

如果你在测试环境(staging)成功获取了证书,并且访问正常,现在可以将Ingress中的cert-manager.io/cluster-issuer注解改为letsencrypt-prod,然后重新kubectl apply -f my-ingress.yaml。Cert-Manager会为你自动申请生产环境的证书。

9. 自动化续期

Cert-Manager会自动监控证书的有效期。在证书临近过期时(通常是30天内),它会自动触发续期流程,确保你的HTTPS连接始终有效,无需任何手动干预。

总结

通过 IngressCert-ManagerLet's Encrypt 的组合,我们实现了Kubernetes服务对外提供HTTPS访问,并且证书的申请、续期全部自动化,极大减轻了开发和运维的负担。现在,你可以专注于业务逻辑,而不用再为证书问题而烦恼了!

DevOps小马 KubernetesHTTPS

评论点评