I have to get the existing microservices run. They are given as docker images. They talk to each other by configured hostnames and ports. I started to use Istio to view and configure the outgoing calls of each microservice. Now I am at the point that I need to rewrite / redirect the host and the port of a request that goes out of one container. How can I do that with Istio?
I will try to give a minimum example. There are two services, service-a and service-b.
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-b
spec:
selector:
matchLabels:
run: service-b
replicas: 1
template:
metadata:
labels:
run: service-b
spec:
containers:
- name: service-b
image: nginx
ports:
- containerPort: 80
name: web
---
apiVersion: v1
kind: Service
metadata:
name: service-b
labels:
run: service-b
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 80
name: service-b
selector:
run: service-b
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-a
spec:
selector:
matchLabels:
run: service-a
replicas: 1
template:
metadata:
labels:
run: service-a
spec:
containers:
- name: service-a
image: nginx
ports:
- containerPort: 80
name: web
---
apiVersion: v1
kind: Service
metadata:
name: service-a
labels:
run: service-a
spec:
ports:
- port: 8081
protocol: TCP
targetPort: 80
name: service-a
selector:
run: service-a
I can docker exec into service-a and successfully execute:
root@service-a-d44f55d8c-8cp8m:/# curl -v service-b:8080
< HTTP/1.1 200 OK
< server: envoy
Now, to simulate my problem, I want to reach service-b by using another hostname and port. I want to configure Istio the way that this call will also work:
root@service-a-d44f55d8c-8cp8m:/# curl -v service-x:7777
Best regards, Christian
There are two solutions which can be used depending on necessity of using istio
features.
If no istio
features are planned to use, it can be solved using native kubernetes. In turn, if some istio
feature are intended to use, it can be solved using istio virtual service
. Below are two options:
1. Native kubernetes
Service-x
should be pointed to the backend of service-b
deployment. Below is selector
which points to deployment: service-b
:
apiVersion: v1
kind: Service
metadata:
name: service-x
labels:
run: service-x
spec:
ports:
- port: 7777
protocol: TCP
targetPort: 80
name: service-x
selector:
run: service-b
This way request will go through istio
anyway because sidecar containers are injected.
# curl -vI service-b:8080
* Trying xx.xx.xx.xx:8080...
* Connected to service-b (xx.xx.xx.xx) port 8080 (#0)
> Host: service-b:8080
< HTTP/1.1 200 OK
< server: envoy
and
# curl -vI service-x:7777
* Trying yy.yy.yy.yy:7777...
* Connected to service-x (yy.yy.yy.yy) port 7777 (#0)
> Host: service-x:7777
< HTTP/1.1 200 OK
< server: envoy
2. Istio virtual service
In this example virtual service is used. Service service-x
still needs to be created, but now we don't specify any selectors:
apiVersion: v1
kind: Service
metadata:
name: service-x
labels:
run: service-x
spec:
ports:
- port: 7777
protocol: TCP
targetPort: 80
name: service-x
Test it from another pod:
# curl -vI service-x:7777
* Trying yy.yy.yy.yy:7777...
* Connected to service-x (yy.yy.yy.yy) port 7777 (#0)
> Host: service-x:7777
< HTTP/1.1 503 Service Unavailable
< server: envoy
503
error which is expected. Now creating virtual service
which will route requests to service-b
on port: 8080
:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: service-x-to-b
spec:
hosts:
- service-x
http:
- route:
- destination:
host: service-b
port:
number: 8080
Testing from the pod:
# curl -vI service-x:7777
* Trying yy.yy.yy.yy:7777...
* Connected to service-x (yy.yy.yy.yy) port 7777 (#0)
> Host: service-x:7777
< HTTP/1.1 200 OK
< server: envoy
See it works as expected.
Useful links: