Ingress 和服务暴露

Ingress 和服务暴露

本节配置 Ingress 将微服务应用暴露到集群外部,实现域名访问和 HTTPS 加密。

安装 Ingress Controller

Nginx Ingress Controller

# 使用 Helm 安装
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.service.type=LoadBalancer

# 查看安装状态
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

配置 Ingress 资源

基础 HTTP Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: shop.example.com
    http:
      paths:
      # 前端应用
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
      # API 网关
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-gateway
            port:
              number: 80

HTTPS Ingress 配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress-tls
  namespace: ecommerce
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - shop.example.com
    secretName: shop-tls-cert
  rules:
  - host: shop.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-gateway
            port:
              number: 80

配置 TLS 证书

安装 cert-manager

# 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# 验证安装
kubectl get pods -n cert-manager

创建 ClusterIssuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx

自签名证书(开发环境)

# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key -out tls.crt \
  -subj "/CN=shop.example.com/O=example"

# 创建 Secret
kubectl create secret tls shop-tls-cert \
  --key tls.key --cert tls.crt \
  -n ecommerce

高级 Ingress 配置

金丝雀发布

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress-canary
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"  # 10% 流量到新版本
spec:
  ingressClassName: nginx
  rules:
  - host: shop.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-v2
            port:
              number: 80

基于 Header 的路由

metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "true"

速率限制

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

白名单 IP

metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,192.168.0.0/16"

CORS 配置

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"

多环境配置

开发环境 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-dev
  namespace: ecommerce-dev
spec:
  ingressClassName: nginx
  rules:
  - host: dev.shop.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

生产环境 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-prod
  namespace: ecommerce-prod
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - shop.example.com
    secretName: prod-tls-cert
  rules:
  - host: shop.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

验证和测试

测试 HTTP 访问

# 获取 Ingress 地址
kubectl get ingress -n ecommerce

# 本地测试(修改 hosts 文件)
echo "192.168.1.100 shop.example.com" | sudo tee -a /etc/hosts

# 测试访问
curl http://shop.example.com
curl http://shop.example.com/api/products

测试 HTTPS

# 等待证书签发
kubectl get certificate -n ecommerce

# 查看证书详情
kubectl describe certificate shop-tls-cert -n ecommerce

# 测试 HTTPS 访问
curl https://shop.example.com
curl -k https://shop.example.com  # 跳过证书验证

查看 Ingress 日志

# 查看 Ingress Controller 日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# 实时查看访问日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f

监控和指标

Prometheus 集成

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-metrics
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
spec:
  ports:
  - name: metrics
    port: 10254
    targetPort: metrics
  selector:
    app.kubernetes.io/name: ingress-nginx
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
  endpoints:
  - port: metrics
    interval: 30s

Grafana Dashboard

导入官方 Dashboard ID: 9614 (NGINX Ingress controller)

故障排查

常见问题

问题 1:Ingress 无法访问

# 检查 Ingress 状态
kubectl describe ingress -n ecommerce

# 检查 Ingress Controller
kubectl get pods -n ingress-nginx

# 查看日志
kubectl logs -n ingress-nginx <pod-name>

问题 2:证书未签发

# 检查 Certificate 状态
kubectl get certificate -n ecommerce
kubectl describe certificate shop-tls-cert -n ecommerce

# 检查 CertificateRequest
kubectl get certificaterequest -n ecommerce

# 查看 cert-manager 日志
kubectl logs -n cert-manager -l app=cert-manager

问题 3:502/503 错误

# 检查后端服务
kubectl get svc -n ecommerce
kubectl get endpoints frontend -n ecommerce

# 检查 Pod 健康状态
kubectl get pods -n ecommerce

小结

本节配置了服务暴露:

Ingress Controller:Nginx Ingress 安装
HTTP/HTTPS:域名访问 + TLS 加密
证书管理:cert-manager + Let's Encrypt
高级功能:金丝雀发布、限流、CORS
多环境:开发、测试、生产环境隔离

下一节介绍运维和最佳实践。