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