<p>I want to deploy different versions of the same application in production:</p>
<pre><code>kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0 -n test-a
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:2.0 -n test-b
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-a
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-b
</code></pre>
<p>I've tried to load-balance it like this:</p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    kubernetes.io/ingress.class: &quot;nginx&quot;
    nginx.org/server-snippets: |
        upstream test-servers-upstream {
          server hello-server.test-a:80;
          server hello-server.test-b:80;
        }
spec:
  rules:
    - host: test-servers.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: test-servers-upstream
              servicePort: 80
</code></pre>
<p>but it returns an error:</p>
<blockquote>
<p>/   test-servers-upstream:80 (&lt;error: endpoints &quot;test-servers-upstream&quot; not found&gt;)</p>
</blockquote>
<p>Services:</p>
<pre><code>$ kubectl get services -n test-b         
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
hello-server   ClusterIP   10.128.199.113   &lt;none&gt;        80/TCP    75m
$ kubectl get services -n test-a 
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
hello-server   ClusterIP   10.128.207.6   &lt;none&gt;        80/TCP    75m
</code></pre>
<p>How can I load-balance it?</p>

<p>Fresh <code>ingress-nginx</code> supports weight-based canary deployments out of box.<br />
Looks like what you're asking for.<br />
<a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary" rel="nofollow noreferrer">https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary</a>.</p>
<p>Great example here.<br />
<a href="https://medium.com/@domi.stoehr/canary-deployments-on-kubernetes-without-service-mesh-425b7e4cc862" rel="nofollow noreferrer">https://medium.com/@domi.stoehr/canary-deployments-on-kubernetes-without-service-mesh-425b7e4cc862</a></p>
<p>Basically, you create 2 identical ingresses, one for each namespace.<br />
They are different only in annotations and in pointing to different services.</p>
<pre><code># ingress for a service A in namespace A
kind: Ingress
metadata:
  name: demo-ingress
  namespace: demo-prod
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-prod
          servicePort: 80
        path: /

# ingress for a service B in namespace B
# note canary annotations
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: &quot;true&quot;
    nginx.ingress.kubernetes.io/canary-weight: &quot;20&quot;
  name: demo-ingress
  namespace: demo-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-canary
          servicePort: 80
        path: /
</code></pre>
<p>Note, that <code>ingress-nginx</code> canary implementation actually <em><strong>requires</strong></em> your services to be in different namespaces.</p>
