首页 > 解决方案 > 如何使用 nginx 入口控制器拥有标头路由逻辑?

问题描述

我正在尝试使用 nginx 实现标头路由入口规则。为什么 ?因为相同的路径应该根据headers不同的后端。这是我尝试过的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: api-mutli-back
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $dataflag 0;

      if ( $http_content_type ~ "multipart\/form-data.*" ){
      set $dataflag 1;
      }

      if ( $dataflag = 1 ){
      set $service_name "backend-data";
      }

spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: backend-default
          servicePort: 80
        path: /api

但是nginx的日志输出了这个错误:

unknown directive "set $service_name backend-data" in /tmp/nginx-cfg864446123:1237

这对我来说似乎不合逻辑......如果我检查 nginx 生成的配置,每个规则都会在开始时生成一个类似这样的位置:

[...]
       location ~* "^/api" {

            set $namespace      "my-namespace";
            set $ingress_name   "api-multi-back";
            set $service_name   "backend-default";
[...]

我究竟做错了什么 ?是否可以使用注释configuration-snippet重新定义service_name变量?还有其他方法吗?

编辑:我在 nginx 方面的错误是由于set $service_namebackend-data之间缺少确切的空格。然后 nginx 正确生成了配置,但它仍然没有路由到另一个 kubernetes 服务。

标签: nginxkubernetesroutinghttp-headersnginx-ingress

解决方案


你被 YAML-ism 咬了:

您的第二个if块的缩进与其他块的缩进不同,因此 YAML 认为您正在开始一个新键annotations:

你有

metadata:
  name: api-mutli-back
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $dataflag 0;

      if ( $http_content_type ~ "multipart\/form-data.*" ){
      set $dataflag 1;
      }

     if ( $dataflag = 1 ){
     set $service_name "backend-data"
     }

但你应该有:

metadata:
  name: api-mutli-back
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $dataflag 0;

      if ( $http_content_type ~ "multipart\/form-data.*" ){
      set $dataflag 1;
      }

      if ( $dataflag = 1 ){
      set $service_name "backend-data"
      }

推荐阅读