Nginx Ingress同一主机配置多后端服务是否可行?
问题解答
你的Ingress配置不可行——Kubernetes Ingress的paths[].backend字段仅支持定义一个后端服务,同时声明两个service属于无效语法,Nginx Ingress Controller会直接忽略第二个服务,甚至可能抛出配置解析错误。
要实现你需要的「主备模式(活跃/被动)」,即仅让就绪探针正常的服务接收流量,备用服务仅在主服务故障时接管,推荐以下两种方案:
方案一:利用Nginx Ingress的Canary特性实现主备切换
通过两个独立的Ingress资源(主Ingress + Canary备Ingress),结合服务就绪状态控制流量转发:
主服务Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: appcj-primary-ingress spec: ingressClassName: nginx rules: - host: "{{ .Values.ingress.appcjudomain }}" http: paths: - pathType: Prefix path: "/" backend: service: name: {{ .Values.Name }}-appcjuengineprihttp port: number: 81
备用服务Canary Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: appcj-secondary-ingress annotations: nginx.ingress.kubernetes.io/canary: "true" # 基于主服务的就绪状态触发流量切换 nginx.ingress.kubernetes.io/canary-by-service: "{{ .Values.Name }}-appcjuengineprihttp" # 主服务故障时,100%流量转发到备用服务 nginx.ingress.kubernetes.io/canary-by-service-weight: "100" spec: ingressClassName: nginx rules: - host: "{{ .Values.ingress.appcjudomain }}" http: paths: - pathType: Prefix path: "/" backend: service: name: {{ .Values.Name }}-appcjuenginesechttp port: number: 81
工作逻辑:
- 正常状态下,主服务的Pod就绪探针正常,Canary规则检测到主服务有可用端点,因此备Ingress不会接收流量。
- 当主服务所有Pod的就绪探针失败时,
canary-by-service规则会触发,将所有流量转发到备用服务。
方案二:基于Kubernetes Service+就绪探针实现原生主备
将两个服务的Pod纳入同一个Service,通过自定义就绪探针逻辑控制Pod是否被Service的端点列表包含:
为主备Pod配置不同的就绪探针:
- 主Pod的就绪探针仅检查自身服务是否正常。
- 备Pod的就绪探针额外检查主服务是否存活(比如通过调用主服务的健康检查接口),只有主服务故障时,备Pod的就绪探针才返回成功。
创建一个包含两个Pod标签的Service:
apiVersion: v1 kind: Service metadata: name: appcj-engine-service spec: selector: app: appcj-engine # 假设主备Pod都带有这个标签 ports: - port: 81 targetPort: 81
工作逻辑:
- 正常状态下,备Pod的就绪探针失败,Service仅将主Pod纳入端点列表,流量全部发给主服务。
- 主服务故障时,备Pod的就绪探针返回成功,Service自动将备Pod加入端点列表,流量切换到备服务。
总结
你当前的Ingress配置不符合Kubernetes规范,无法实现预期的多后端主备效果。推荐使用上述两种方案中的任意一种,其中Nginx Ingress Canary方案更灵活,适合需要明确区分主备服务的场景;原生Service+探针方案则更轻量化,依赖Kubernetes原生机制。
内容的提问来源于stack exchange,提问作者windowws
相关产品推荐
相关产品推荐

