如何用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

