How to access external service using an internal host name?

Hi,

I have an external IBM MQ application and I want to access it from within the mesh being able to apply resilience features on top of it.

The way I thought to do it is:
-define a host for the external app: “external-mq”. I am doing it with a Service Entry that knows to map “external-mq” to an IP address or another external DNS.
-use the “external-mq” host name in consumer apps inside the mesh. So these apps inside the mesh don’t care and don’t know that this service is actually external. In practice I won’t have the “external” word in the host.
-create a virtual service that applies network resilience features for the “external-mq” host.
Is this scenario achievable in Istio? :smile:

Thanks,
Iustin

I also opened an issue for this but I didnt receive yet a working solution: Service Entry not working · Issue #40190 · istio/istio · GitHub

Hi @Iustin.
Did you manage to solve this? I’m facing a similar problem, where I’d like to move a core application from it’s current cluster to an isolated one (for…reasons…) and I thought I could make the client applications continue to use the original, internal name while redirecting the requests using external service.

I did the same tests as you and also didn’t achieve anything…

Cheeers,

@Iustin (and everyone else who may look for this):

I managed to solve this doing the following:

  • keep/create a ClusterIP service pointing to nowhere (no need to have an deployment associated)
  • Create a VirtualService to capture the above service and change it’s authority to the external hostname
  • Create a DestinationRule to forward the request to the external service
  • Create a ServiceEntry corresponding to the external service

Here is an example:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: api2-fake-hml-upg
  namespace: default
spec:
  hosts:
  - "api2-fake.homolog.example.com"
  location: MESH_EXTERNAL
  resolution: DNS
  ports:
    - name: http
      protocol: HTTP
      number: 80
      targetPort: 443
    - name: https
      number: 443
      protocol: HTTPS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: api2-fake
  namespace: default
spec:
  hosts:
  - api2-fake
  - api2-fake.default
  - api2-fake.default.svc.cluster.local
  http:
  - match:
    rewrite:
      authority: api2-fake.homolog.example.com
    route:
    - destination:
        host: api2-fake.homolog.example.com
        port:
          number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: api2-fake
spec:
  host: "api2-fake.homolog.example.com"
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 80
      tls:
        mode: SIMPLE
        sni: api2-fake.homolog.example.com
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: api2-fake
  name: api2-fake
  namespace: default
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: api2-fake
  type: ClusterIP

In this case I’m redirecting a HTTP internal service to a HTTPS external service. But I hope this can put you on the right track.