Scenario-
I have 2 deployments deployment-1
with label- version:v1
and deployment-2
with label- version:v2
both are hosted under a nodeport service- test-1
. I have created a virtual service with two match conditions as follows
- match:
- uri:
exact: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
exact: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
The code file can be found here
Problem-
When I try to visit this Ingress Gateway IP at http://ingress-gateway-ip/v1/favicon.ico, I encounter a 404 error in the console saying http://ingress-gateway-ip
/favicon.ico not found (because this has been re-written to "/") also the stylings and js are absent at this route. But when I try to visit
http://ingress-gateway-ip/v1
/favicon.ico I can see the favicon icon along with all the js and stylings.
Please find the screenshots of the problem here
Expectation-
How can I access these two services using a prefix routing in the url, meaning when I navigate to /v1, only the V1 version should come up without 404, and when I navigate to /v2, only the V2 version should come up?
EDIT-1:
EDIT-2:
How can I access these two services using a prefix routing in the url, meaning when I navigate to /v1, only the V1 version should come up without 404, and when I navigate to /v2, only the V2 version should come up
I assume your issue is your DestinationRule, in the v2 name your label is version: v1
and it should be version: v2
, that's why your requests from /v1 and /v2 went only to v1 version of your pod.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v1 <---
It should be
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
When I try to visit this Ingress Gateway IP, I encounter a 404 error in the console saying http://ingress-gateway-ip/favicon.ico
It's working as designed, you haven't specified path for /
, just for /v1
and /v2
.
If you want to be able to access then you would have to add another match for /
- match:
- uri:
prefix: /
route:
- destination:
host: test-1
There is working example with 2 nginx pods, take a look.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
spec:
selector:
matchLabels:
version: v1
replicas: 1
template:
metadata:
labels:
app: frontend
version: v1
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v2
spec:
selector:
matchLabels:
version: v2
replicas: 1
template:
metadata:
labels:
app: frontend
version: v2
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx2 > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: test-1
labels:
app: frontend
spec:
ports:
- name: http-front
port: 80
protocol: TCP
selector:
app: frontend
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: simpleexample
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtualservice
spec:
gateways:
- simpleexample
hosts:
- '*'
http:
- match:
- uri:
prefix: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
prefix: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Results from curl:
curl -v ingress-gateway-ip/
404 Not Found
there is no path specified for that in virtual service
curl -v ingress-gateway-ip/v1
HTTP/1.1 200 OK
Hello nginx1
curl -v ingress-gateway-ip/v2
HTTP/1.1 200 OK
Hello nginx2
EDIT
the problem is that all the stylings and js are not readable by the browser at "/" when they are being re-written
It was already explained by @Rinor here
I would add this Istio in practise tutorial here, it explains well a way of dealing with that problem, which is to add more paths for your dependencies(js,css,etc).
Let’s break down the requests that should be routed to Frontend:
Exact path / should be routed to Frontend to get the Index.html
Prefix path /static/* should be routed to Frontend to get any static files needed by the frontend, like Cascading Style Sheets and JavaScript files.
Paths matching the regex ^.*.(ico|png|jpg)$ should be routed to Frontend as it is an image, that the page needs to show.
http:
- match:
- uri:
exact: /
- uri:
exact: /callback
- uri:
prefix: /static
- uri:
regex: '^.*\.(ico|png|jpg)$'
route:
- destination:
host: frontend
port:
number: 80
Let me know if you have any more questions.