<p>I am trying to create a service which follows vertical replication-</p>
<p><a href="https://i.stack.imgur.com/olfNe.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/olfNe.png" alt="enter image description here" /></a></p>
<p>In this architecture, requestes goes to the master node. For that I can use a kubernetes ingress.</p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: / 
        backend:
          serviceName: master-node
          servicePort: http
</code></pre>
<p>Now my requirement is if master is down, then request should go to the slave node.
I can achieve that by creating three paths <code>/master</code>, <code>/slave-1</code>, <code>/slave-2</code>. But the constraint is that <strong>the path of request must remain same</strong>. So, the path must always be <code>/</code></p>
<p>How can I create a ingress in such a way that if <code>master-node</code> is down, then all requests should forward to the <code>slave-1-node</code>?</p>
<p>I want to achieve something like below-</p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: / 
        priority: 1
        backend:
          serviceName: master-node
          servicePort: http
  - host: example.com
    http:
      paths:
      - path: / 
        priority: 2
        backend:
          serviceName: slave-1-node
          servicePort: http
  - host: example.com
    http:
      paths:
      - path: / 
        priority: 3
        backend:
          serviceName: slave-2-node
          servicePort: http
</code></pre>

Prateek Agrawal
<p>I'm not sure how to do this using <em>just</em> an ingress resource, but it would be very easy if you were to deploy an haproxy pod in front of your services, so that your architecture looks like this:</p>
<p><a href="https://i.stack.imgur.com/H7HKx.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H7HKx.png" alt="enter image description here" /></a></p>
<p>Using an haproxy configuration like this, you would get the behavior you want:</p>
<pre><code>global
    log         stdout format raw local0
    maxconn     4000
    user        haproxy
    group       haproxy

defaults
    mode    http
    log global
    option  httplog
    option  dontlognull
    option  http-server-close
    option  forwardfor  except 127.0.0.0/8
    option  redispatch
    retries 3
    timeout connect     10s
    timeout client      1m
    timeout server      1m

frontend  example_fe
    bind 0.0.0.0:8080
    default_backend example_be

backend example_be
    option httpchk GET /healthz

    server alpha example-alpha:80 check
    server beta example-beta:80 check backup
    server gamma example-gamma:80 check backup
</code></pre>
<p>This will send all requests to <code>alpha</code> as long it is running. If <code>alpha</code> is offline, requests will go to <code>beta</code>, and if <code>beta</code> is not running, requests will go to <code>gamma</code>. I found <a href="https://www.haproxy.com/blog/failover-and-worst-case-management-with-haproxy/" rel="nofollow noreferrer">this article</a> useful when looking for information about how to set this up.</p>
<p>You create a Deployment that runs haproxy:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: haproxy
  name: haproxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: haproxy
  template:
    metadata:
      labels:
        app: haproxy
    spec:
      containers:
      - image: docker.io/haproxy:latest
        name: haproxy
        ports:
        - containerPort: 8080
          name: http
        volumeMounts:
        - mountPath: /usr/local/etc/haproxy
          name: haproxy-config
      volumes:
      - configMap:
          name: haproxy-config-ddc898c5f5
        name: haproxy-config

</code></pre>
<p>A Service pointing at that Deployment:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: haproxy
  name: haproxy
spec:
  ports:
  - name: http
    port: 80
    targetPort: http
  selector:
    app: haproxy
</code></pre>
<p>And then point the Ingress at that Service:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: haproxy
            port:
              name: http
        path: /
        pathType: Prefix

</code></pre>
<p>I've put together a complete configuration <a href="https://github.com/larsks/so-example-73996233" rel="nofollow noreferrer">here</a> if you want to try this out.</p>
