TLS 终止
学习目标
- 理解 TLS 终止的概念和作用
- 掌握在 Ingress 中配置 TLS 的方法
- 了解证书管理的最佳实践
核心概念
一句话解释
TLS 终止是指在 Ingress Controller 处理解密 HTTPS 流量,然后将明文 HTTP 流量转发到后端 Service,这样后端 Pod 不需要处理 TLS。
TLS 终止工作流程
HTTPS 请求流程:
用户浏览器 Ingress Controller Pod
│ │ │
│ HTTPS 请求 │ │
│ (加密) │ │
├─────────────────────────────→│ │
│ │ │
│ TLS 终止 │ │
│ 解密流量 │ │
│ │ │
│ │ HTTP 请求 │
│ │ (明文) │
│ ├─────────────────────────→│
│ │ │
│ │ HTTP 响应 │
│ │ (明文) │
│ │←─────────────────────────┤
│ │ │
│ HTTPS 响应 │ │
│ (加密) │ │
│←─────────────────────────────┤ │
│ │ │
优势:
- 后端 Pod 不需要处理 TLS
- 证书集中管理
- 性能更好(硬件加速)
TLS 配置方式
# 1. 创建 TLS Secret
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-certificate>
tls.key: <base64-encoded-private-key>
# 2. 在 Ingress 中引用 TLS Secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls: # TLS 配置
- hosts:
- app.example.com
- api.example.com
secretName: tls-secret # 引用 Secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
证书类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| 自签名证书 | 自己生成的证书 | 开发测试 |
| Let's Encrypt | 免费自动证书 | 生产环境 |
| 商业证书 | 购买的证书 | 企业环境 |
自动生成证书
# 生成自签名证书(开发测试用)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=app.example.com"
# 创建 Secret
kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key
Let's Encrypt 自动证书
# 使用 cert-manager 自动管理证书
# 安装 cert-manager
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml
# 创建 ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
# 在 Ingress 中使用自动证书
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-tls-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod" # 自动申请证书
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls-secret # cert-manager 自动创建
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
TLS 配置选项
# 通过 Annotation 配置 TLS 选项
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-options
annotations:
# 强制 HTTPS 重定向
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# HSTS 配置
nginx.ingress.kubernetes.io/hsts: "true"
nginx.ingress.kubernetes.io/hsts-max-age: "31536000"
nginx.ingress.kubernetes.io/hsts-include-subdomains: "true"
# TLS 版本
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
# 密码套件
nginx.ingress.kubernetes.io/ssl-ciphers: "HIGH:!aNULL:!MD5"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
多域名证书
# 多域名 TLS 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-tls
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
- api.example.com
- admin.example.com
secretName: wildcard-secret # 可以用一个通配符证书
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80
实践练习
练习 1:创建自签名证书并配置 TLS
# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=app.example.com"
# 创建 Secret
kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key
# 创建 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
# 应用配置
kubectl apply -f ingress.yaml
# 测试 HTTPS 访问
curl -k https://app.example.com
练习 2:查看 TLS 配置
# 查看 Secret
kubectl get secret tls-secret
kubectl describe secret tls-secret
# 查看 Ingress TLS 配置
kubectl get ingress tls-ingress
kubectl describe ingress tls-ingress
# 测试证书
openssl s_client -connect app.example.com:443 -servername app.example.com
练习 3:配置 cert-manager(可选)
# 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml
# 等待 cert-manager 就绪
kubectl wait --for=condition=Available deployment --all -n cert-manager
# 创建 ClusterIssuer
kubectl apply -f cluster-issuer.yaml
# 创建带注解的 Ingress
kubectl apply -f ingress-with-cert-manager.yaml
# 查看证书状态
kubectl get certificate
kubectl describe certificate app-tls-secret
常见误解
1. TLS 终止和 TLS 直通是一样的
错误理解:TLS 终止和 TLS 直通没有区别
正确理解:
TLS 终止:
Client → HTTPS → Ingress Controller → HTTP → Pod
(Ingress Controller 解密)
TLS 直通:
Client → HTTPS → Ingress Controller → HTTPS → Pod
(Pod 解密,Ingress Controller 只转发)
2. 自签名证书可以用于生产环境
错误理解:自签名证书和商业证书一样安全
正确理解:
自签名证书:
- 浏览器会显示安全警告
- 不受信任
- 仅适合开发测试
生产环境:
- 使用 Let's Encrypt 或商业证书
- 浏览器信任
- 自动续期
小结
| 要点 | 说明 |
|---|---|
| TLS 终止 | Ingress Controller 处理解密 |
| 优势 | 后端无需处理 TLS,证书集中管理 |
| 配置方式 | Secret + Ingress TLS 配置 |
| 证书类型 | 自签名、Let's Encrypt、商业证书 |
| 自动管理 | 使用 cert-manager 自动申请和续期 |
| 安全选项 | HTTPS 重定向、HSTS、TLS 版本控制 |
练习编辑器
bash
Loading...