You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Kubernetes Ingress实现指定Nginx反向代理配置?求推荐控制器

问题描述

我使用Nginx作为反向代理,配置负责基于主机名路由至两个后端HTTPS服务,同时执行TLS终止并对转发流量进行重加密(后端强制使用HTTPS),此外还设置了若干请求头。对应的Nginx配置如下,请问如何通过Kubernetes Ingress实现该需求?适合的Ingress控制器有哪些?非标准端口与不同证书的使用是否会导致在Nginx Ingress Controller中难以实现?或者我的理解有误?

server {
  listen 8143 ssl;
  listen [::]:8143 ssl;
  server_name server1.external;

  ssl_certificate   /etc/nginx/certs/server1.external.crt;
  ssl_certificate_key /etc/nginx/certs/server1.external.key;

  proxy_set_header Host $host:$proxy_port;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $host;

  location / {
    proxy_pass https://server1.external:8143/;
  }

  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/html;
  }
}

server {
  listen 8085 ssl;
  listen [::]:8085 ssl;
  server_name server2.external;

  ssl_certificate   /etc/nginx/certs/server2.external.crt;
  ssl_certificate_key /etc/nginx/certs/server2.external.key;

  proxy_set_header Host $host:$proxy_port;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $host;

  location / {
    proxy_pass https://server2.external:8085/;
  }

  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/html;
  }
}

已实现方案

将所有待暴露服务的端口修改为同一个大于1024的端口,手动调整Nginx Ingress清单(修改Deployment和Service对象中的HTTPS端口,以及Nginx容器的HTTPS端口命令行参数)


解答

一、基于Kubernetes Ingress的实现步骤

1. 创建TLS证书Secret

为两个域名分别生成K8s TLS Secret,用于Ingress的TLS终止:

kubectl create secret tls server1-tls --cert=server1.external.crt --key=server1.external.key
kubectl create secret tls server2-tls --cert=server2.external.crt --key=server2.external.key

2. 定义后端Service

如果后端是外部服务,使用ExternalName类型的Service;如果是集群内服务,用ClusterIP类型。以下是外部服务的配置示例:

# server1 后端Service
apiVersion: v1
kind: Service
metadata:
  name: server1-service
spec:
  type: ExternalName
  externalName: server1.external
  ports:
  - name: https
    port: 8143
    protocol: TCP
    targetPort: 8143

# server2 后端Service
apiVersion: v1
kind: Service
metadata:
  name: server2-service
spec:
  type: ExternalName
  externalName: server2.external
  ports:
  - name: https
    port: 8085
    protocol: TCP
    targetPort: 8085

3. 编写Ingress资源配置

通过Ingress实现主机名路由、TLS终止、流量重加密及自定义请求头:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
  annotations:
    # 启用后端HTTPS重加密
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    # 配置自定义请求头
    nginx.ingress.kubernetes.io/proxy-set-header: |
      Host $host:$proxy_port
      X-Real-IP $remote_addr
      X-Forwarded-Proto $scheme
      X-Forwarded-For $proxy_add_x_forwarded_for
      X-Forwarded-Host $host
    # 配置自定义错误页(对应原Nginx的50x规则)
    nginx.ingress.kubernetes.io/custom-http-errors: "500,502,503,504"
spec:
  tls:
  - hosts:
    - server1.external
    secretName: server1-tls
  - hosts:
    - server2.external
    secretName: server2-tls
  rules:
  - host: server1.external
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: server1-service
            port:
              number: 8143
  - host: server2.external
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: server2-service
            port:
              number: 8085

4. 自定义错误页配置(可选)

若需和原Nginx一致的50x页面,可通过ConfigMap将自定义HTML页面挂载到Ingress Controller容器,或通过annotation指定错误页路径(具体操作取决于Ingress Controller的部署方式)。

二、适合的Ingress控制器

  • Nginx Ingress Controller:最主流的选择,完全覆盖你的所有需求(多域名TLS、自定义请求头、后端HTTPS重加密、非标准端口支持),配置灵活,社区文档完善。
  • HAProxy Ingress Controller:性能优异,支持多域名TLS和后端HTTPS转发,适合高流量场景。
  • Traefik:云原生轻量控制器,自带Let's Encrypt自动TLS功能,配置简洁,支持动态更新,适合快速部署。

三、非标准端口与多证书的常见疑问

1. 多证书处理

Nginx Ingress Controller原生支持为不同Host配置独立TLS证书,只需在Ingress的tls字段中为每个Host关联对应的Secret即可,属于标准特性,无实现难度。

2. 非标准端口处理

后端服务的非标准端口

只需在Service中正确配置port和targetPort,Ingress即可正常转发到后端的非标准端口,无需修改Ingress Controller本身的配置。

Ingress Controller监听的非标准端口

若需让Ingress Controller监听8143、8085这类端口,无需手动修改Deployment清单,更推荐通过ConfigMap配置:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
data:
  ssl-ports: "8143,8085"
  http-ports: "" # 不需要HTTP监听则留空

同时更新Ingress Controller的Service,添加端口映射:

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  ports:
  - name: https-8143
    port: 8143
    protocol: TCP
    targetPort: 8143
  - name: https-8085
    port: 8085
    protocol: TCP
    targetPort: 8085
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx

这种方式比手动修改Deployment命令行参数更符合K8s最佳实践,维护性更强。

内容的提问来源于stack exchange,提问作者AndyM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:05:20