Egress Gateways with TLS Origination

The TLS Origination for Egress Traffic example shows how to configure Istio to perform TLS origination for traffic to an external service. The Configure an Egress Gateway example shows how to configure Istio to direct egress traffic through a dedicated egress gateway service. This example combines the previous two by describing how to configure an egress gateway to perform TLS origination for traffic to external services.

Before you begin

  • Setup Istio by following the instructions in the Installation guide.

  • Start the sleep sample which will be used as a test source for external calls.

    If you have enabled automatic sidecar injection, do

    Zip

    1. $ kubectl apply -f @samples/sleep/sleep.yaml@

    otherwise, you have to manually inject the sidecar before deploying the sleep application:

    Zip

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)

    Note that any pod that you can exec and curl from would do.

  • Create a shell variable to hold the name of the source pod for sending requests to external services. If you used the sleep sample, run:

    1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
  • Deploy Istio egress gateway.

  • Enable Envoy’s access logging

Perform TLS origination with an egress gateway

This section describes how to perform the same TLS origination as in the TLS Origination for Egress Traffic example, only this time using an egress gateway. Note that in this case the TLS origination will be done by the egress gateway, as opposed to by the sidecar in the previous example.

  1. Define a ServiceEntry for edition.cnn.com:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: ServiceEntry
    4. metadata:
    5. name: cnn
    6. spec:
    7. hosts:
    8. - edition.cnn.com
    9. ports:
    10. - number: 80
    11. name: http
    12. protocol: HTTP
    13. - number: 443
    14. name: https
    15. protocol: HTTPS
    16. resolution: DNS
    17. EOF
  2. Verify that your ServiceEntry was applied correctly by sending a request to http://edition.cnn.com/politics.

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
    2. HTTP/1.1 301 Moved Permanently
    3. ...
    4. location: https://edition.cnn.com/politics
    5. ...
    6. command terminated with exit code 35

    Your ServiceEntry was configured correctly if you see 301 Moved Permanently in the output.

  3. Create an egress Gateway for edition.cnn.com, port 80, and a destination rule for sidecar requests that will be directed to the egress gateway.

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. name: istio-egressgateway
    6. spec:
    7. selector:
    8. istio: egressgateway
    9. servers:
    10. - port:
    11. number: 80
    12. name: http-port-for-tls-origination
    13. protocol: HTTP
    14. hosts:
    15. - edition.cnn.com
    16. ---
    17. apiVersion: networking.istio.io/v1alpha3
    18. kind: DestinationRule
    19. metadata:
    20. name: egressgateway-for-cnn
    21. spec:
    22. host: istio-egressgateway.istio-system.svc.cluster.local
    23. subsets:
    24. - name: cnn
    25. EOF
  4. Define a VirtualService to direct the traffic through the egress gateway, and a DestinationRule to perform TLS origination for requests to edition.cnn.com:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: VirtualService
    4. metadata:
    5. name: direct-cnn-through-egress-gateway
    6. spec:
    7. hosts:
    8. - edition.cnn.com
    9. gateways:
    10. - istio-egressgateway
    11. - mesh
    12. http:
    13. - match:
    14. - gateways:
    15. - mesh
    16. port: 80
    17. route:
    18. - destination:
    19. host: istio-egressgateway.istio-system.svc.cluster.local
    20. subset: cnn
    21. port:
    22. number: 80
    23. weight: 100
    24. - match:
    25. - gateways:
    26. - istio-egressgateway
    27. port: 80
    28. route:
    29. - destination:
    30. host: edition.cnn.com
    31. port:
    32. number: 443
    33. weight: 100
    34. ---
    35. apiVersion: networking.istio.io/v1alpha3
    36. kind: DestinationRule
    37. metadata:
    38. name: originate-tls-for-edition-cnn-com
    39. spec:
    40. host: edition.cnn.com
    41. trafficPolicy:
    42. loadBalancer:
    43. simple: ROUND_ROBIN
    44. portLevelSettings:
    45. - port:
    46. number: 443
    47. tls:
    48. mode: SIMPLE # initiates HTTPS for connections to edition.cnn.com
    49. EOF
  5. Send an HTTP request to http://edition.cnn.com/politics.

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
    2. HTTP/1.1 200 OK
    3. ...
    4. content-length: 150793
    5. ...

    The output should be the same as in the TLS Origination for Egress Traffic example, with TLS origination: without the 301 Moved Permanently message.

  6. Check the log of the istio-egressgateway pod and you should see a line corresponding to our request. If Istio is deployed in the istio-system namespace, the command to print the log is:

    1. $ kubectl logs -l istio=egressgateway -c istio-proxy -n istio-system | tail

    You should see a line similar to the following:

    1. "[2018-06-14T13:49:36.340Z] "GET /politics HTTP/1.1" 200 - 0 148528 5096 90 "172.30.146.87" "curl/7.35.0" "c6bfdfc3-07ec-9c30-8957-6904230fd037" "edition.cnn.com" "151.101.65.67:443"

Cleanup the TLS origination example

Remove the Istio configuration items you created:

  1. $ kubectl delete gateway istio-egressgateway
  2. $ kubectl delete serviceentry cnn
  3. $ kubectl delete virtualservice direct-cnn-through-egress-gateway
  4. $ kubectl delete destinationrule originate-tls-for-edition-cnn-com
  5. $ kubectl delete destinationrule egressgateway-for-cnn

Perform mutual TLS origination with an egress gateway

Similar to the previous section, this section describes how to configure an egress gateway to perform TLS origination for an external service, only this time using a service that requires mutual TLS.

This example is considerably more involved because you need to first:

  1. generate client and server certificates
  2. deploy an external service that supports the mutual TLS protocol
  3. redeploy the egress gateway with the needed mutual TLS certs

Only then can you configure the external traffic to go through the egress gateway which will perform TLS origination.

Generate client and server certificates and keys

  1. Clone the https://github.com/nicholasjackson/mtls-go-example repository:

    1. $ git clone https://github.com/nicholasjackson/mtls-go-example
  2. Change directory to the cloned repository:

    1. $ cd mtls-go-example
  3. Generate the certificates for nginx.example.com. Use any password with the following command:

    1. $ ./generate.sh nginx.example.com <password>

    Select y for all prompts that appear.

  4. Move the certificates into the nginx.example.com directory:

    1. $ mkdir ../nginx.example.com && mv 1_root 2_intermediate 3_application 4_client ../nginx.example.com
  5. Go back to your previous directory:

    1. $ cd ..

Deploy a mutual TLS server

To simulate an actual external service that supports the mutual TLS protocol, deploy an NGINX server in your Kubernetes cluster, but running outside of the Istio service mesh, i.e., in a namespace without Istio sidecar proxy injection enabled.

  1. Create a namespace to represent services outside the Istio mesh, namely mesh-external. Note that the sidecar proxy will not be automatically injected into the pods in this namespace since the automatic sidecar injection was not enabled on it.

    1. $ kubectl create namespace mesh-external
  2. Create Kubernetes Secrets to hold the server’s and CA certificates.

    1. $ kubectl create -n mesh-external secret tls nginx-server-certs --key nginx.example.com/3_application/private/nginx.example.com.key.pem --cert nginx.example.com/3_application/certs/nginx.example.com.cert.pem
    2. $ kubectl create -n mesh-external secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
  3. Create a configuration file for the NGINX server:

    1. $ cat <<EOF > ./nginx.conf
    2. events {
    3. }
    4. http {
    5. log_format main '$remote_addr - $remote_user [$time_local] $status '
    6. '"$request" $body_bytes_sent "$http_referer" '
    7. '"$http_user_agent" "$http_x_forwarded_for"';
    8. access_log /var/log/nginx/access.log main;
    9. error_log /var/log/nginx/error.log;
    10. server {
    11. listen 443 ssl;
    12. root /usr/share/nginx/html;
    13. index index.html;
    14. server_name nginx.example.com;
    15. ssl_certificate /etc/nginx-server-certs/tls.crt;
    16. ssl_certificate_key /etc/nginx-server-certs/tls.key;
    17. ssl_client_certificate /etc/nginx-ca-certs/ca-chain.cert.pem;
    18. ssl_verify_client on;
    19. }
    20. }
    21. EOF
  4. Create a Kubernetes ConfigMap to hold the configuration of the NGINX server:

    1. $ kubectl create configmap nginx-configmap -n mesh-external --from-file=nginx.conf=./nginx.conf
  5. Deploy the NGINX server:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: v1
    3. kind: Service
    4. metadata:
    5. name: my-nginx
    6. namespace: mesh-external
    7. labels:
    8. run: my-nginx
    9. spec:
    10. ports:
    11. - port: 443
    12. protocol: TCP
    13. selector:
    14. run: my-nginx
    15. ---
    16. apiVersion: apps/v1
    17. kind: Deployment
    18. metadata:
    19. name: my-nginx
    20. namespace: mesh-external
    21. spec:
    22. selector:
    23. matchLabels:
    24. run: my-nginx
    25. replicas: 1
    26. template:
    27. metadata:
    28. labels:
    29. run: my-nginx
    30. spec:
    31. containers:
    32. - name: my-nginx
    33. image: nginx
    34. ports:
    35. - containerPort: 443
    36. volumeMounts:
    37. - name: nginx-config
    38. mountPath: /etc/nginx
    39. readOnly: true
    40. - name: nginx-server-certs
    41. mountPath: /etc/nginx-server-certs
    42. readOnly: true
    43. - name: nginx-ca-certs
    44. mountPath: /etc/nginx-ca-certs
    45. readOnly: true
    46. volumes:
    47. - name: nginx-config
    48. configMap:
    49. name: nginx-configmap
    50. - name: nginx-server-certs
    51. secret:
    52. secretName: nginx-server-certs
    53. - name: nginx-ca-certs
    54. secret:
    55. secretName: nginx-ca-certs
    56. EOF
  6. Define a ServiceEntry and a VirtualService for nginx.example.com to instruct Istio to direct traffic destined to nginx.example.com to your NGINX server:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: ServiceEntry
    4. metadata:
    5. name: nginx
    6. spec:
    7. hosts:
    8. - nginx.example.com
    9. ports:
    10. - number: 80
    11. name: http
    12. protocol: HTTP
    13. - number: 443
    14. name: https
    15. protocol: HTTPS
    16. resolution: DNS
    17. endpoints:
    18. - address: my-nginx.mesh-external.svc.cluster.local
    19. ports:
    20. https: 443
    21. ---
    22. apiVersion: networking.istio.io/v1alpha3
    23. kind: VirtualService
    24. metadata:
    25. name: nginx
    26. spec:
    27. hosts:
    28. - nginx.example.com
    29. tls:
    30. - match:
    31. - port: 443
    32. sniHosts:
    33. - nginx.example.com
    34. route:
    35. - destination:
    36. host: nginx.example.com
    37. port:
    38. number: 443
    39. weight: 100
    40. EOF

Deploy a container to test the NGINX deployment

  1. Create Kubernetes Secrets to hold the client’s and CA certificates:

    1. $ kubectl create secret tls nginx-client-certs --key nginx.example.com/4_client/private/nginx.example.com.key.pem --cert nginx.example.com/4_client/certs/nginx.example.com.cert.pem
    2. $ kubectl create secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
  2. Deploy the sleep sample with mounted client and CA certificates to test sending requests to the NGINX server:

    1. $ kubectl apply -f - <<EOF
    2. # Copyright 2017 Istio Authors
    3. #
    4. # Licensed under the Apache License, Version 2.0 (the "License");
    5. # you may not use this file except in compliance with the License.
    6. # You may obtain a copy of the License at
    7. #
    8. # http://www.apache.org/licenses/LICENSE-2.0
    9. #
    10. # Unless required by applicable law or agreed to in writing, software
    11. # distributed under the License is distributed on an "AS IS" BASIS,
    12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. # See the License for the specific language governing permissions and
    14. # limitations under the License.
    15. ##################################################################################################
    16. # Sleep service
    17. ##################################################################################################
    18. apiVersion: v1
    19. kind: Service
    20. metadata:
    21. name: sleep
    22. labels:
    23. app: sleep
    24. spec:
    25. ports:
    26. - port: 80
    27. name: http
    28. selector:
    29. app: sleep
    30. ---
    31. apiVersion: apps/v1
    32. kind: Deployment
    33. metadata:
    34. name: sleep
    35. spec:
    36. replicas: 1
    37. selector:
    38. matchLabels:
    39. app: sleep
    40. template:
    41. metadata:
    42. labels:
    43. app: sleep
    44. spec:
    45. containers:
    46. - name: sleep
    47. image: tutum/curl
    48. command: ["/bin/sleep","infinity"]
    49. imagePullPolicy: IfNotPresent
    50. volumeMounts:
    51. - name: nginx-client-certs
    52. mountPath: /etc/nginx-client-certs
    53. readOnly: true
    54. - name: nginx-ca-certs
    55. mountPath: /etc/nginx-ca-certs
    56. readOnly: true
    57. volumes:
    58. - name: nginx-client-certs
    59. secret:
    60. secretName: nginx-client-certs
    61. - name: nginx-ca-certs
    62. secret:
    63. secretName: nginx-ca-certs
    64. EOF
  3. Define an environment variable to hold the name of the sleep pod:

    1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
  4. Use the deployed sleep pod to send requests to the NGINX server. Since nginx.example.com does not actually exist and therefore DNS cannot resolve it, the following curl command uses the --resolve option to resolve the hostname manually. The IP value passed in the –resolve option (1.1.1.1 below) is not significant. Any value other than 127.0.0.1 can be used. Normally, a DNS entry exists for the destination hostname and you would not use the --resolve option of curl.

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -v --resolve nginx.example.com:443:1.1.1.1 --cacert /etc/nginx-ca-certs/ca-chain.cert.pem --cert /etc/nginx-client-certs/tls.crt --key /etc/nginx-client-certs/tls.key https://nginx.example.com
    2. ...
    3. Server certificate:
    4. subject: C=US; ST=Denial; L=Springfield; O=Dis; CN=nginx.example.com
    5. start date: 2018-08-16 04:31:20 GMT
    6. expire date: 2019-08-26 04:31:20 GMT
    7. common name: nginx.example.com (matched)
    8. issuer: C=US; ST=Denial; O=Dis; CN=nginx.example.com
    9. SSL certificate verify ok.
    10. > GET / HTTP/1.1
    11. > User-Agent: curl/7.35.0
    12. > Host: nginx.example.com
    13. ...
    14. < HTTP/1.1 200 OK
    15. < Server: nginx/1.15.2
    16. ...
    17. <!DOCTYPE html>
    18. <html>
    19. <head>
    20. <title>Welcome to nginx!</title>
    21. ...
  5. Verify that the server requires the client’s certificate:

    1. $ kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl -k --resolve nginx.example.com:443:1.1.1.1 https://nginx.example.com
    2. <html>
    3. <head><title>400 No required SSL certificate was sent</title></head>
    4. <body bgcolor="white">
    5. <center><h1>400 Bad Request</h1></center>
    6. <center>No required SSL certificate was sent</center>
    7. <hr><center>nginx/1.15.2</center>
    8. </body>
    9. </html>

Redeploy the egress gateway with the client certificates

  1. Create Kubernetes Secrets to hold the client’s and CA certificates.

    1. $ kubectl create -n istio-system secret tls nginx-client-certs --key nginx.example.com/4_client/private/nginx.example.com.key.pem --cert nginx.example.com/4_client/certs/nginx.example.com.cert.pem
    2. $ kubectl create -n istio-system secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
  2. To include a volume mounted from the new created secret, update the istio-egressgateway deployment. To patch the istio-egressgateway deployment, create the following gateway-patch.json file:

    1. $ cat > gateway-patch.json <<EOF
    2. [{
    3. "op": "add",
    4. "path": "/spec/template/spec/containers/0/volumeMounts/0",
    5. "value": {
    6. "mountPath": "/etc/istio/nginx-client-certs",
    7. "name": "nginx-client-certs",
    8. "readOnly": true
    9. }
    10. },
    11. {
    12. "op": "add",
    13. "path": "/spec/template/spec/volumes/0",
    14. "value": {
    15. "name": "nginx-client-certs",
    16. "secret": {
    17. "secretName": "nginx-client-certs",
    18. "optional": true
    19. }
    20. }
    21. },
    22. {
    23. "op": "add",
    24. "path": "/spec/template/spec/containers/0/volumeMounts/1",
    25. "value": {
    26. "mountPath": "/etc/istio/nginx-ca-certs",
    27. "name": "nginx-ca-certs",
    28. "readOnly": true
    29. }
    30. },
    31. {
    32. "op": "add",
    33. "path": "/spec/template/spec/volumes/1",
    34. "value": {
    35. "name": "nginx-ca-certs",
    36. "secret": {
    37. "secretName": "nginx-ca-certs",
    38. "optional": true
    39. }
    40. }
    41. }]
    42. EOF
  3. Apply istio-egressgateway deployment patch with the following command:

    1. $ kubectl -n istio-system patch --type=json deploy istio-egressgateway -p "$(cat gateway-patch.json)"
  4. Verify that the key and the certificate are successfully loaded in the istio-egressgateway pod:

    1. $ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=egressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/nginx-client-certs /etc/istio/nginx-ca-certs

    tls.crt and tls.key should exist in /etc/istio/nginx-client-certs, while ca-chain.cert.pem in /etc/istio/nginx-ca-certs.

Configure mutual TLS origination for egress traffic

  1. Create an egress Gateway for nginx.example.com, port 443, and destination rules and virtual services to direct the traffic through the egress gateway and from the egress gateway to the external service.

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. name: istio-egressgateway
    6. spec:
    7. selector:
    8. istio: egressgateway
    9. servers:
    10. - port:
    11. number: 443
    12. name: https
    13. protocol: HTTPS
    14. hosts:
    15. - nginx.example.com
    16. tls:
    17. mode: MUTUAL
    18. serverCertificate: /etc/certs/cert-chain.pem
    19. privateKey: /etc/certs/key.pem
    20. caCertificates: /etc/certs/root-cert.pem
    21. ---
    22. apiVersion: networking.istio.io/v1alpha3
    23. kind: DestinationRule
    24. metadata:
    25. name: egressgateway-for-nginx
    26. spec:
    27. host: istio-egressgateway.istio-system.svc.cluster.local
    28. subsets:
    29. - name: nginx
    30. trafficPolicy:
    31. loadBalancer:
    32. simple: ROUND_ROBIN
    33. portLevelSettings:
    34. - port:
    35. number: 443
    36. tls:
    37. mode: ISTIO_MUTUAL
    38. sni: nginx.example.com
    39. EOF
  2. Define a VirtualService to direct the traffic through the egress gateway, and a DestinationRule to perform mutual TLS origination:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: VirtualService
    4. metadata:
    5. name: direct-nginx-through-egress-gateway
    6. spec:
    7. hosts:
    8. - nginx.example.com
    9. gateways:
    10. - istio-egressgateway
    11. - mesh
    12. http:
    13. - match:
    14. - gateways:
    15. - mesh
    16. port: 80
    17. route:
    18. - destination:
    19. host: istio-egressgateway.istio-system.svc.cluster.local
    20. subset: nginx
    21. port:
    22. number: 443
    23. weight: 100
    24. - match:
    25. - gateways:
    26. - istio-egressgateway
    27. port: 443
    28. route:
    29. - destination:
    30. host: nginx.example.com
    31. port:
    32. number: 443
    33. weight: 100
    34. ---
    35. apiVersion: networking.istio.io/v1alpha3
    36. kind: DestinationRule
    37. metadata:
    38. name: originate-mtls-for-nginx
    39. spec:
    40. host: nginx.example.com
    41. trafficPolicy:
    42. loadBalancer:
    43. simple: ROUND_ROBIN
    44. portLevelSettings:
    45. - port:
    46. number: 443
    47. tls:
    48. mode: MUTUAL
    49. clientCertificate: /etc/istio/nginx-client-certs/tls.crt
    50. privateKey: /etc/istio/nginx-client-certs/tls.key
    51. caCertificates: /etc/istio/nginx-ca-certs/ca-chain.cert.pem
    52. sni: nginx.example.com
    53. EOF
  3. Send an HTTP request to http://nginx.example.com:

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -s --resolve nginx.example.com:80:1.1.1.1 http://nginx.example.com
    2. <!DOCTYPE html>
    3. <html>
    4. <head>
    5. <title>Welcome to nginx!</title>
    6. ...
  4. Check the log of the istio-egressgateway pod for a line corresponding to our request. If Istio is deployed in the istio-system namespace, the command to print the log is:

    1. $ kubectl logs -l istio=egressgateway -n istio-system | grep 'nginx.example.com' | grep HTTP

    You should see a line similar to the following:

    1. [2018-08-19T18:20:40.096Z] "GET / HTTP/1.1" 200 - 0 612 7 5 "172.30.146.114" "curl/7.35.0" "b942b587-fac2-9756-8ec6-303561356204" "nginx.example.com" "172.21.72.197:443"

Cleanup the mutual TLS origination example

  1. Remove created Kubernetes resources:

    1. $ kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external
    2. $ kubectl delete secret nginx-client-certs nginx-ca-certs
    3. $ kubectl delete secret nginx-client-certs nginx-ca-certs -n istio-system
    4. $ kubectl delete configmap nginx-configmap -n mesh-external
    5. $ kubectl delete service my-nginx -n mesh-external
    6. $ kubectl delete deployment my-nginx -n mesh-external
    7. $ kubectl delete namespace mesh-external
    8. $ kubectl delete gateway istio-egressgateway
    9. $ kubectl delete serviceentry nginx
    10. $ kubectl delete virtualservice direct-nginx-through-egress-gateway
    11. $ kubectl delete destinationrule originate-mtls-for-nginx
    12. $ kubectl delete destinationrule egressgateway-for-nginx
  2. Delete the directory of certificates and the repository used to generate them:

    1. $ rm -rf nginx.example.com mtls-go-example
  3. Delete the generated configuration files used in this example:

    1. $ rm -f ./nginx.conf ./istio-egressgateway.yaml

Cleanup

Delete the sleep service and deployment:

  1. $ kubectl delete service sleep
  2. $ kubectl delete deployment sleep

See also

Secure Control of Egress Traffic in Istio, part 3

Comparison of alternative solutions to control egress traffic including performance considerations.

Secure Control of Egress Traffic in Istio, part 2

Use Istio Egress Traffic Control to prevent attacks involving egress traffic.

Secure Control of Egress Traffic in Istio, part 1

Attacks involving egress traffic and requirements for egress traffic control.

Egress Gateway Performance Investigation

Verifies the performance impact of adding an egress gateway.

Consuming External MongoDB Services

Describes a simple scenario based on Istio’s Bookinfo example.

Monitoring and Access Policies for HTTP Egress Traffic

Describes how to configure Istio for monitoring and access policies of HTTP egress traffic.