☰
Kubernetes - Ingress 配置 HTTPS,实现安全的 HTTPS 访问
2026/9/28 3:07:15 网站建设 项目流程

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕Kubernetes这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!


文章目录

  • Kubernetes - Ingress 配置 HTTPS,实现安全的 HTTPS 访问 🛡️🌐
    • 一、HTTPS 与 TLS:为什么我们必须使用它? 🔐
      • 1.1 数据泄露的代价
      • 1.2 浏览器与搜索引擎的“惩罚机制”
      • 1.3 法规合规的硬性要求
      • 1.4 TLS 的工作原理简述
      • 1.5 证书类型与信任链
    • 二、Kubernetes Ingress 基础回顾 🚦
      • 2.1 Ingress 的核心结构
      • 2.2 Ingress Controller 是什么?
      • 2.3 Ingress 与 Service 的关系
    • 三、证书管理方案选型:手动 vs 自动化 🤖
      • 3.1 推荐方案:cert-manager + Let’s Encrypt
    • 四、实战部署:从零搭建 HTTPS Ingress 系统 🛠️
      • 4.1 环境准备
      • 4.2 部署 cert-manager
      • 4.3 创建 Let’s Encrypt Issuer
      • 4.4 部署 Java Web 应用
        • Java 代码示例:`HelloController.java`
        • `pom.xml`(Maven 依赖)
        • 构建 Docker 镜像
      • 4.5 部署 Java 应用到 Kubernetes
      • 4.6 创建 Ingress 并启用 HTTPS
      • 4.7 等待证书签发
    • 五、验证 HTTPS 访问:从浏览器到命令行 🧪
      • 5.1 使用 curl 测试
      • 5.2 浏览器验证
      • 5.3 强制 HTTP 跳转测试
    • 六、进阶配置:增强安全性与性能 🚀
      • 6.1 启用 HSTS(HTTP Strict Transport Security)
      • 6.2 启用 TLS 1.3 与强加密套件
      • 6.3 启用 Gzip 压缩
      • 6.4 防止点击劫持与 XSS
      • 6.5 限制请求速率(防暴力破解)
    • 七、监控与告警:让证书永不过期 🔔

Kubernetes - Ingress 配置 HTTPS,实现安全的 HTTPS 访问 🛡️🌐

在当今互联网环境中,安全已成为不可妥协的底线。无论是用户登录、支付交易,还是 API 调用,数据的加密传输都已成为行业标配。HTTP 协议早已无法满足现代应用对隐私与完整性的要求,HTTPS 凭借 TLS/SSL 加密机制,成为构建可信网络服务的基石。在 Kubernetes 集群中,Ingress 作为流量入口的核心组件,承担着将外部请求路由至内部服务的重任。如何在 Ingress 上正确配置 HTTPS,实现端到端的安全访问,是每一位云原生工程师必须掌握的技能。

本文将带你从零开始,系统性地构建一个基于 Kubernetes Ingress 的 HTTPS 安全访问体系。我们将深入理解 TLS 证书的原理、ACME 协议的自动化流程、Ingress Controller 的工作模式,并结合真实 Java 应用示例,演示如何部署一个完整的、支持 HTTPS 的微服务系统。你将学会如何使用 Let’s Encrypt 自动签发证书、如何配置 Nginx Ingress 实现双向认证、如何处理证书轮换、如何调试常见错误,以及如何通过监控与日志保障服务的长期稳定运行。

无论你是刚接触 Kubernetes 的新手,还是希望深化安全架构的资深工程师,本文都将为你提供可落地、可复用的实践指南。让我们一起,把安全从口号变成代码,从理论变成生产环境中的坚实盾牌。🔐


一、HTTPS 与 TLS:为什么我们必须使用它? 🔐

在讨论如何配置之前,我们先明确一个核心问题:为什么 HTTPS 不是“可选项”,而是“必选项”?

1.1 数据泄露的代价

想象一下,你的用户在未加密的 HTTP 网站上输入了邮箱和密码。攻击者只需在同一个 Wi-Fi 网络中监听流量,就能轻松截获明文凭证。根据 IBM 2023 年《数据泄露成本报告》,单次数据泄露的平均成本已高达445 万美元。而其中,38% 的泄露事件起源于未加密的通信通道。

🔗 https://www.ibm.com/reports/data-breach —— IBM 数据泄露成本报告(权威数据来源)

1.2 浏览器与搜索引擎的“惩罚机制”

现代浏览器(Chrome、Firefox、Safari)对非 HTTPS 网站会显示“不安全”红色警告,直接劝退用户。Google 更是在其搜索算法中将 HTTPS 作为排名因子,非加密网站将被降权。你可能不在乎排名,但你的用户会在意是否被浏览器“拉黑”。

1.3 法规合规的硬性要求

GDPR(欧盟通用数据保护条例)、CCPA(加州消费者隐私法案)、等保 2.0、《个人信息保护法》等国内外法规,均明确要求对用户敏感信息传输进行加密。不使用 HTTPS,意味着你可能面临巨额罚款甚至业务关停。

1.4 TLS 的工作原理简述

HTTPS 并非独立协议,而是 HTTP over TLS(Transport Layer Security)。TLS 的核心流程如下:

  1. 客户端发起连接(Client Hello):携带支持的加密套件、随机数。
  2. 服务端响应(Server Hello):选择加密套件,发送证书(含公钥)。
  3. 证书验证:客户端使用信任的 CA(证书颁发机构)验证证书签名。
  4. 密钥交换:客户端生成预主密钥,用服务端公钥加密后发送。
  5. 会话密钥生成:双方使用预主密钥 + 随机数生成对称密钥。
  6. 加密通信:后续所有数据使用对称密钥加密传输。

✅ 重点:对称加密用于数据传输(高效),非对称加密用于密钥交换(安全)。

1.5 证书类型与信任链

类型说明适用场景
DV(域名验证)仅验证域名所有权个人博客、测试环境
OV(组织验证)验证企业身份企业官网、B2B 服务
EV(扩展验证)最严格审核,地址栏显示公司名银行、电商
自签名证书无第三方 CA 签名仅限内网测试

在 Kubernetes 中,我们主要使用DV 证书,并通过Let’s Encrypt(免费、自动化)自动签发。

🔗 https://letsencrypt.org/ —— Let’s Encrypt 官网(全球最大的免费证书颁发机构)


二、Kubernetes Ingress 基础回顾 🚦

Ingress 是 Kubernetes 中用于管理外部访问集群服务的 API 对象。它通常与 Ingress Controller 配合使用,后者是一个实际处理 HTTP/HTTPS 请求的反向代理(如 Nginx、Traefik、HAProxy)。

2.1 Ingress 的核心结构

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:my-app-ingressnamespace:defaultannotations:kubernetes.io/ingress.class:"nginx"cert-manager.io/cluster-issuer:"letsencrypt-prod"spec:tls:-hosts:-example.comsecretName:tls-secretrules:-host:example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:my-java-appport:number:8080
  • tls:定义 HTTPS 证书绑定的域名和 Secret 名称。
  • rules:定义域名与后端服务的映射。
  • annotations:配置 Ingress Controller 的行为,如使用哪个 issuer、是否启用压缩等。

2.2 Ingress Controller 是什么?

Ingress Controller 并非 Kubernetes 内置组件,而是由社区或厂商提供的独立部署应用。最流行的是:

  • NGINX Ingress Controller:高性能、配置灵活,适合生产环境。
  • Traefik:自动发现服务,适合动态微服务架构。
  • HAProxy:高可用、负载均衡能力强。
  • Contour:基于 Envoy,支持 gRPC、WebSocket。

我们以NGINX Ingress Controller为例,因其生态成熟、文档丰富、社区支持广泛。

🔗 https://kubernetes.github.io/ingress-nginx/ —— Nginx Ingress 官方文档

2.3 Ingress 与 Service 的关系

外部用户 → Ingress Controller(监听 443) → Ingress 规则 → Service(ClusterIP) → Pod(Java 应用)

Java 应用本身无需关心 HTTPS,它只需监听 HTTP(如 8080),由 Ingress Controller 负责 TLS 终止(TLS Termination),然后以 HTTP 明文转发给后端服务。这种方式称为SSL Offloading,是主流架构。

⚠️ 注意:若需端到端加密(客户端 → Ingress → Pod 全程 HTTPS),需在 Pod 内启用 HTTPS,但会增加证书管理复杂度,一般不推荐。


三、证书管理方案选型:手动 vs 自动化 🤖

在 Kubernetes 中,证书管理有三种主流方式:

方式描述优点缺点
手动上传 Secret本地生成证书,kubectl create secret tls简单可控证书过期需人工轮换,易遗忘
cert-manager + Let’s Encrypt自动申请、续期、更新证书完全自动化,免费,安全需配置 Issuer、DNS 验证
自建 CA + 签发使用私有 PKI 系统签发适用于内网、合规要求高成本高,运维复杂

3.1 推荐方案:cert-manager + Let’s Encrypt

cert-manager是 Kubernetes 原生的证书管理控制器,它能自动监听 Ingress 资源中的注解,向 Let’s Encrypt 申请证书,并自动更新到 Secret 中。

✅ 优势:

  • 证书有效期 90 天,自动续期
  • 支持 DNS-01 和 HTTP-01 验证
  • 与 Ingress 深度集成
  • 支持多 Issuer(Prod / Staging)

我们将在下一节完整部署这套体系。


四、实战部署:从零搭建 HTTPS Ingress 系统 🛠️

现在,我们进入实战环节。我们将完成以下步骤:

  1. 部署 cert-manager
  2. 创建 Let’s Encrypt 生产环境 Issuer
  3. 部署一个 Java Web 应用
  4. 创建 Ingress 并启用 HTTPS
  5. 验证并测试访问

4.1 环境准备

假设你已拥有一个可用的 Kubernetes 集群(Minikube、EKS、GKE、Rancher 等均可),并已配置kubectl连接。

💡 建议:使用公网可访问的域名(如your-app.example.com),并已将 A 记录解析到集群的 Ingress Controller 公网 IP。

4.2 部署 cert-manager

# 添加 Jetstack Helm 仓库helm repoaddjetstack https://charts.jetstack.io helm repo update# 安装 cert-managerhelminstallcert-manager jetstack/cert-manager\--namespacecert-manager\--create-namespace\--setinstallCRDs=true

等待所有 Pod 运行:

kubectl get pods-ncert-manager

输出应类似:

NAME READY STATUS RESTARTS AGE cert-manager-5b7b8c8d8f-7x9q2 1/1 Running 0 2m cert-manager-cainjector-7d6b9d5c5d-9z2kx 1/1 Running 0 2m cert-manager-webhook-6d9b8c8b8f-4w9lq 1/1 Running 0 2m

4.3 创建 Let’s Encrypt Issuer

创建prod-issuer.yaml:

apiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-prodspec:acme:# Let's Encrypt 生产环境 URL(非测试)server:https://acme-v02.api.letsencrypt.org/directoryemail:admin@example.comprivateKeySecretRef:name:letsencrypt-prod-private-keysolvers:-http01:ingress:class:nginx

应用配置:

kubectl apply-fprod-issuer.yaml

验证 Issuer 状态:

kubectl describe clusterissuer letsencrypt-prod

若看到Status: Ready,说明配置成功。

📌 注意:http01验证要求 Ingress Controller 能被公网访问。若你处于内网或防火墙后,需改用dns01(需配置 DNS 提供商 API)。

4.4 部署 Java Web 应用

我们创建一个简单的 Spring Boot 应用作为后端服务。

Java 代码示例:HelloController.java
packagecom.example.demo;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;@RestControllerpublicclassHelloController{@GetMapping("/api/hello")publicStringhello(){Stringtimestamp=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));returnString.format("{\"message\": \"Hello from Kubernetes!\", \"timestamp\": \"%s\", \"env\": \"production\"}",timestamp);}@GetMapping("/health")publicStringhealth(){return"OK";}}
pom.xml(Maven 依赖)
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/XML/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>k8s-https-demo</artifactId><version>1.0.0</version><packaging>jar</packaging><name>k8s-https-demo</name><description>Demo Spring Boot app for Kubernetes HTTPS</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version><relativePath/></parent><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
构建 Docker 镜像
# Dockerfile FROM eclipse-temurin:17-jre-slim WORKDIR /app COPY target/k8s-https-demo-1.0.0.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]

构建并推送:

dockerbuild-tyour-registry.com/k8s-https-demo:latest.dockerpush your-registry.com/k8s-https-demo:latest

💡 若你使用的是公共镜像仓库(如 Docker Hub),请替换your-registry.com为实际地址。

4.5 部署 Java 应用到 Kubernetes

创建java-app-deployment.yaml:

apiVersion:apps/v1kind:Deploymentmetadata:name:java-applabels:app:java-appspec:replicas:2selector:matchLabels:app:java-apptemplate:metadata:labels:app:java-appspec:containers:-name:java-appimage:your-registry.com/k8s-https-demo:latestports:-containerPort:8080resources:requests:memory:"128Mi"cpu:"250m"limits:memory:"256Mi"cpu:"500m"livenessProbe:httpGet:path:/healthport:8080initialDelaySeconds:30periodSeconds:10readinessProbe:httpGet:path:/healthport:8080initialDelaySeconds:5periodSeconds:5---apiVersion:v1kind:Servicemetadata:name:java-app-servicespec:selector:app:java-appports:-protocol:TCPport:80targetPort:8080type:ClusterIP

部署:

kubectl apply-fjava-app-deployment.yaml

验证 Pod 状态:

kubectl get pods-lapp=java-app

4.6 创建 Ingress 并启用 HTTPS

创建ingress-https.yaml:

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:java-app-ingressannotations:kubernetes.io/ingress.class:"nginx"cert-manager.io/cluster-issuer:"letsencrypt-prod"nginx.ingress.kubernetes.io/ssl-redirect:"true"nginx.ingress.kubernetes.io/backend-protocol:"HTTP"spec:tls:-hosts:-your-domain.com# 替换为你的域名secretName:tls-secretrules:-host:your-domain.comhttp:paths:-path:/pathType:Prefixbackend:service:name:java-app-serviceport:number:80

✅ 关键注解说明:

  • cert-manager.io/cluster-issuer:告诉 cert-manager 使用哪个 Issuer 签发证书
  • nginx.ingress.kubernetes.io/ssl-redirect: "true":强制 HTTP 重定向到 HTTPS
  • nginx.ingress.kubernetes.io/backend-protocol: "HTTP":告知 Nginx 后端是 HTTP(非 HTTPS)

应用配置:

kubectl apply-fingress-https.yaml

4.7 等待证书签发

证书申请是异步过程。查看证书状态:

kubectl get certificate-A

输出示例:

NAMESPACE NAME READY SECRET AGE default tls-secret True tls-secret 8m

若READY为False,查看详细信息:

kubectl describe certificate tls-secret

常见错误:

  • DNS record not found:域名未正确解析到 Ingress IP
  • Failed to authorize:防火墙阻止了 HTTP-01 验证请求
  • Too many certificates already issued:Let’s Encrypt 有频率限制(每域名 50 次/周)

✅ 解决方案:使用letsencrypt-staging先测试,成功后再切换到生产环境。

创建staging-issuer.yaml用于测试:

apiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-stagingspec:acme:server:https://acme-staging-v02.api.letsencrypt.org/directoryemail:admin@example.comprivateKeySecretRef:name:letsencrypt-staging-private-keysolvers:-http01:ingress:class:nginx

修改 Ingress 注解为:

cert-manager.io/cluster-issuer:"letsencrypt-staging"

测试通过后,再切回生产环境。


五、验证 HTTPS 访问:从浏览器到命令行 🧪

当tls-secret状态变为True,证书已成功创建。我们来验证整个链路是否畅通。

5.1 使用 curl 测试

curl-vhttps://your-domain.com/api/hello

预期输出:

* TLS 1.3 connected * Server certificate: * subject: CN=your-domain.com * start date: Apr 10 12:00:00 2024 GMT * expire date: Jul 9 12:00:00 2024 GMT * issuer: C=US, O=Let's Encrypt, CN=R3 * SSL certificate verify ok. > GET /api/hello HTTP/2 > Host: your-domain.com > ... < HTTP/2 200 < content-type: application/json < {"message": "Hello from Kubernetes!", "timestamp": "2024-04-10 15:30:22", "env": "production"}

✅ 成功!说明:

  • HTTPS 连接建立
  • 证书有效
  • Ingress 路由正确
  • Java 应用返回数据

5.2 浏览器验证

在浏览器中访问https://your-domain.com/api/hello

你会看到:

  • 地址栏显示 🔒 小锁图标
  • 点击锁 → 证书信息 → 由 Let’s Encrypt R3 签发
  • 无任何“不安全”警告

5.3 强制 HTTP 跳转测试

访问http://your-domain.com/api/hello

预期:自动跳转到https://...,状态码 308。

curl-Ihttp://your-domain.com/api/hello

输出:

HTTP/1.1 308 Permanent Redirect Location: https://your-domain.com/api/hello

说明ssl-redirect: "true"生效。


六、进阶配置:增强安全性与性能 🚀

6.1 启用 HSTS(HTTP Strict Transport Security)

HSTS 强制浏览器在未来一段时间内只使用 HTTPS 访问,防止 SSL Stripping 攻击。

添加注解:

annotations:nginx.ingress.kubernetes.io/hsts:"true"nginx.ingress.kubernetes.io/hsts-max-age:"31536000"# 1年nginx.ingress.kubernetes.io/hsts-include-subdomains:"true"nginx.ingress.kubernetes.io/hsts-preload:"true"

✅ 作用:浏览器访问一次 HTTPS 后,未来 1 年内即使输入http://也会自动转为 HTTPS。

6.2 启用 TLS 1.3 与强加密套件

Nginx Ingress 默认使用较旧的加密套件。我们通过configmap强化安全:

创建nginx-config.yaml:

apiVersion:v1kind:ConfigMapmetadata:name:nginx-configurationnamespace:ingress-nginxdata:ssl-protocols:"TLSv1.2 TLSv1.3"ssl-ciphers:"ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"ssl-prefer-server-ciphers:"true"hsts:"true"hsts-max-age:"31536000"

应用:

kubectl apply-fnginx-config.yaml

🔗 https://ssl-config.mozilla.org/ —— Mozilla SSL 配置生成器(推荐使用 Intermediate 配置)

6.3 启用 Gzip 压缩

减少带宽,提升响应速度:

annotations:nginx.ingress.kubernetes.io/use-gzip:"true"

6.4 防止点击劫持与 XSS

annotations:nginx.ingress.kubernetes.io/security-headers:|X-Frame-Options: DENY X-Content-Type-Options: nosniff X-XSS-Protection: "1; mode=block" Referrer-Policy: strict-origin-when-cross-origin

6.5 限制请求速率(防暴力破解)

annotations:nginx.ingress.kubernetes.io/limit-rps:"10"nginx.ingress.kubernetes.io/limit-connections:"5"

七、监控与告警:让证书永不过期 🔔

证书过期是导致服务中断的“隐形杀手”。据统计,超过 15% 的网站因证书过期而宕机。


🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍点赞、📌收藏、📤分享给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询