57·网络进阶

TLS 终止

kubernetesnetworkingingresstlssecurity

TLS 终止

学习目标

  1. 理解 TLS 终止的概念和作用
  2. 掌握在 Ingress 中配置 TLS 的方法
  3. 了解证书管理的最佳实践

核心概念

一句话解释

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...

继续学习

完成本课后,建议继续学习下一课「网络策略」 以巩固所学知识。