I’ve tried to reproduce using Nginx Ingress but without success using server-snippet and configuration-snippet.

I did some researches and see that Nginx Plus there’s a snippet called location-snippet that should work. See here.

Alternatively, I’ve created a custom Nginx deployment with a Service type LoadBalancer and created a configMap with a custom Nginx configuration, and it’s works!

If you want to try, you need to create a configMap with your custom default.conf file, it’s looks like this:

I’m using the namespace: default for this example, but you can create a custom namespace if you want.

nginx-custom-config.yaml:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-nginx-config
  namespace: default
data:
  default.conf: |
    upstream my-svc {
        server echo-svc.default.svc.cluster.local;
    }
    
    server {
        listen       80;
        server_name  localhost;

        location / {

            root   /usr/share/nginx/html;
            index  index.html index.htm;

            if ($http_user_agent ~* "iPhone|iPad" ) {
                add_header X-Vendor "Apple";
                proxy_pass  http://my-svc;
            }
            if ($http_user_agent ~ Chrome ) {
                add_header X-Vendor "OpenSource";
                proxy_pass  http://my-svc;
            }
    
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        }
        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }

Apply to Kubernetes:

kubectl apply -f nginx-custom-config.yaml
  • I’ve created upstream called my-svc pointing to my destination service echo-svc.default.svc.cluster.local.
  • In my location: / there’s a condition that matches the User-agent, in this case, if a request was made from a Apple device "iPhone|iPad" a header named X-Vendor with value Apple will be created and redirected the request to my destination service my-svc. The same will happen if the request was made from “Chrome”, but the header will be X-Vendor: "OpenSource".
  • If the request was made from another browser, like firefox, curl etc… them the Nginx default page will be displayed.

After that you need to create a deployment of a Nginx image mounting our configMap as a file inside the containers, like this:

custom-nginx-deployment.yaml:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-nginx
spec:
  selector:
    matchLabels:
      app: custom-nginx
  template:
    metadata:
      labels:
        app: custom-nginx
    spec:
      containers:
      - name: custom-nginx
        image: nginx
        volumeMounts:
        - name: custom-nginx-config
          mountPath: /etc/nginx/conf.d
        ports:
        - name: http
          containerPort: 80
        imagePullPolicy: IfNotPresent
      volumes:
        - name: custom-nginx-config
          configMap:
            name: custom-nginx-config

kubectl apply -f custom-nginx-deployment.yaml

And finally, creating a LoadBalancer Service to received the requests:

custom-nginx-svc.yaml:

---
apiVersion: v1
kind: Service
metadata:
  name: custom-nginx-svc
  labels:
    app: custom-nginx
spec:
  selector:
    app: custom-nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

kubectl apply -f custom-nginx-svc.yaml

You can check if the container and service was successfully deployed using the commands:

kubectl get pods -l app=custom-nginx
kubectl get svc -l app=custom-nginx