This article will cover how to send traffic to an external host using HTTPS retries and timeouts.
Understanding the problem
Considering an external application added to the mesh with a ServiceEntry. The application listens on HTTPS so the traffic you will be sending is expected to use simple TLS.
The application client within the mesh will initiate an HTTP request and it will be converted to HTTPS at the sidecar to the external application host, e.g.
www.tetrate.io. This is achieved due to outbound traffic policy defined in the DestinationRule.
Here is what you need to set to achieve the communication between the client and the external host:
This only works using TSB direct mode config.
First, create a namespace for your istio objects:
kubectl create ns tetrate
Create a file
tetrate.yaml with the following ServiceEntry, VirtualService and DestinationRule.
- address: www.tetrate.io
- name: http
Apply with kubectl:
kubectl apply -f tetrate.yaml
It is important to pay attention on how the external host is added to the service registry. On the yaml above, you can see that the single ServiceEntry has port 80 as the matching port but your external application listens on HTTPS which most of the time will be 443 (you may change this if your application listens on 8443 or other port).
In other words, the traffic is sent to the same port that matched, i.e. port 80, which is not right for the outgoing HTTPS connection. In order to forward to upstream 443 port, you would need to make the endpoints stanza in the ServiceEntry look like this:
- address: www.tetrate.io
First, send a request using HTTPS:
curl -I https://www.tetrate.io
date: Tue, 13 Sep 2022 16:21:37 GMT
content-type: text/html; charset=UTF-8
link: <https://www.tetrate.io/wp-json/>; rel="https://api.w.org/", <https://www.tetrate.io/wp-json/wp/v2/pages/29256>; rel="alternate"; type="application/json", <https://www.tetrate.io/>; rel=shortlink
x-xss-protection: 1; mode=block
cache-control: must-revalidate, public, max-age=300, stale-while-revalidate=360, stale-if-error=43200
x-varnish: 107840197 105743030
via: 1.1 varnish (Varnish/6.5)
You can see how the first curl command succeeds, as it goes through the pass-through proxy (TCP proxy). That means no rule is applied from DestinationRule or VirtualService.
Now, perform a request instead sending and HTTPS this will be a plain HTTP. Remember the sidecar will initiate and HTTPS request as we instructed in the DestinationRule.
curl -I http://www.tetrate.io
HTTP/1.1 504 Gateway Timeout
date: Tue, 13 Sep 2022 16:24:32 GMT
This will return an obvious response since you have an aggressive timeout defined in the virtual service which it gets applied hence is working as expected.
Destroy all the resources with the same yaml file as following:
kubectl delete -f tetrate.yaml
Finally delete the namespace.
kubectl delete ns tetrate