Kelindil
Kelindil

Reputation: 471

How to have a header routing logic with nginx ingress-controller?

I'm trying to achieve a header routing ingress rule with nginx. Why ? Because the same path should go to different backend based on headers. Here what i've tried:

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

But the logs of nginx output this error:

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

which seems unlogic to me... If I check the configuration generated by nginx, each rule generate a location with something like this at the begining:

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

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

What am I doing wrong ? Isn't it possible to redefine service_name variable with annotation configuration-snippet ? Is there any other method ?

Edit: My error on nginx side was due to the lack of exact spaces between set $service_name and backend-data. Then nginx generated correctly the configuration but it still not routing to another kubernetes service.

Upvotes: 9

Views: 6702

Answers (1)

mdaniel
mdaniel

Reputation: 33203

You got bitten by a YAML-ism:

The indentation of your 2nd if block isn't the same as the indentation of the others, and thus YAML thinks you are starting a new key under annotations:

You have

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"
     }

but you should have:

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"
      }

Upvotes: 3

Related Questions