<p>I am defining canary routes in mesh-virtual-service and wondering whether I can make it applicable for ingress traffic (with ingress-virtual-service) as well. With something like below, but it does not work (all traffic from ingress is going to non-canary version)</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: test-deployment-app
  namespace: test-ns
spec:
  gateways:
  - mesh 
  hosts:
  - test-deployment-app.test-ns.svc.cluster.local
  http:
  - name: canary
    match:
    - headers:
        x-canary:
          exact: &quot;true&quot;
    - port: 8080
    headers:
      response:
        set:
          x-canary: &quot;true&quot;
    route:
    - destination:
        host: test-deployment-app-canary.test-ns.svc.cluster.local
        port:
          number: 8080
      weight: 100
  - name: stable
    route:
    - destination:
        host: test-deployment-app.test-ns.svc.cluster.local
        port:
          number: 8080
      weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: test-deployment-app-internal
  namespace: test-ns
spec:
  gateways:
  - istio-system/default-gateway
  hosts:
  - myapp.dev.bla
  http:
  - name: default
    route:
    - destination:
        host: test-deployment-app.test-ns.svc.cluster.local
        port:
          number: 8080
      weight: 100

</code></pre>
<p>So I am expecting <code>x-canary:true</code> response header when I call <code>myapp.dev.bla</code> but I don't see that.</p>

<p>Well the answer is only partially inside the link you included. I think the essential thing to realize when working with Istio 'what even is Istio Service Mesh'. Service mesh is every pod with Istio envoy-proxy sidecar + all the gateways (gateway is standalone envoy-proxy). They all know about each other because of IstioD so they can cooperate.</p>
<p>Any pod without Istio sidecar (including ingress pods or i.e. kube-system pods) in your k8s cluster doesn't know anything about Istio or Service Mesh. If such pod wants to send traffic to Service Mesh (to apply some Traffic Management rules like you have) must send it through Istio Gateway. <code>Gateway</code> is object that creates standard deployment + service. Pods in the deployment consist standalone <code>envoy-proxy</code> container.</p>
<p><code>Gateway</code> object is a very similar concept to k8s ingress. But it doesn't have to listen on nodePort necessarily. You can use it also as an 'internal' gateway. Gateway serves as entry point into your service mesh. Either for external or even internal traffic.</p>
<ol>
<li>If you're using i.e. Nginx as the Ingress solution you must reconfigure the Ingress rule to send traffic to one of the gateways instead of the target service. Most likely to your <code>mesh</code> gateway. It's nothing else than k8s Service inside <code>istio-gateway</code> or <code>istio-system</code> namespace</li>
<li>Alternatively you can configure Istio Gateway as 'new' Ingress. As I'm not sure if some default Istio Gateway listens on nodePort you need to check it (again in <code>istio-gateway</code> or <code>istio-system</code> namespace. Alternatively you can create new Gateway just for your application and apply <code>VirtualService</code> to the new gateway as well.</li>
</ol>
