mirror of https://github.com/istio/istio.io.git
214 lines
38 KiB
HTML
214 lines
38 KiB
HTML
<!doctype html><html lang=en itemscope itemtype=https://schema.org/WebPage><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=theme-color content="#466BB0"><meta name=title content="Consuming External Web Services"><meta name=description content="Describes a simple scenario based on Istio's Bookinfo example."><meta name=author content="Vadim Eisenberg"><meta name=keywords content="microservices,services,mesh,traffic-management,egress,https"><meta property="og:title" content="Consuming External Web Services"><meta property="og:type" content="website"><meta property="og:description" content="Describes a simple scenario based on Istio's Bookinfo example."><meta property="og:url" content="/v1.21/blog/2018/egress-https/"><meta property="og:image" content="https://raw.githubusercontent.com/istio/istio.io/master/static/img/istio-social.png"><meta property="og:image:alt" content="The Istio sailboat logo"><meta property="og:image:width" content="4096"><meta property="og:image:height" content="2048"><meta property="og:site_name" content="Istio"><meta name=twitter:card content="summary_large_image"><meta name=twitter:site content="@IstioMesh"><title>Istioldie 1.21 / Consuming External Web Services</title>
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-98480406-2"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","UA-98480406-2")</script><link rel=alternate type=application/rss+xml title="Istio Blog" href=/v1.21/blog/feed.xml><link rel=alternate type=application/rss+xml title="Istio News" href=/v1.21/news/feed.xml><link rel=alternate type=application/rss+xml title="Istio Blog and News" href=/v1.21/feed.xml><link rel="shortcut icon" href=/v1.21/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.21/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.21/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.21/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.21/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.21/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.21/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.21/favicons/android-96x96.png sizes=96xW96><link rel=icon type=image/png href=/v1.21/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.21/favicons/android-192x192.png sizes=192x192><link rel=icon type=image/svg+xml href=/v1.21/favicons/favicon.svg><link rel=icon type=image/png href=/v1.21/favicons/favicon.png><link rel=mask-icon href=/v1.21/favicons/safari-pinned-tab.svg color=#466BB0><link rel=manifest href=/v1.21/manifest.json><meta name=apple-mobile-web-app-title content="Istio"><meta name=application-name content="Istio"><meta name=msapplication-config content="/browserconfig.xml"><meta name=msapplication-TileColor content="#466BB0"><meta name=theme-color content="#466BB0"><link rel=stylesheet href=/v1.21/css/all.css><link rel=preconnect href=https://fonts.googleapis.com><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600&display=swap"><script src=/v1.21/js/themes_init.min.js></script></head><body class="language-unknown archive-site"><script>const branchName="release-1.21",docTitle="Consuming External Web Services",iconFile="/v1.21//img/icons.svg",buttonCopy="Copy to clipboard",buttonPrint="Print",buttonDownload="Download"</script><script src="https://www.google.com/cse/brand?form=search-form" defer></script><script src=/v1.21/js/all.min.js data-manual defer></script><header class=main-navigation><nav class="main-navigation-wrapper container-l"><div class=main-navigation-header><a id=brand href=/v1.21/ aria-label=logotype><span class=logo><svg xmlns="http://www.w3.org/2000/svg" width="128" height="60" viewBox="0 0 128 60"><path d="M58.434 48.823A.441.441.0 0158.3 48.497V22.583a.444.444.0 01.134-.326.446.446.0 01.327-.134h3.527a.447.447.0 01.325.134.447.447.0 01.134.326v25.914a.443.443.0 01-.134.326.444.444.0 01-.325.134h-3.527a.444.444.0 01-.327-.134z"/><path d="m70.969 48.477a6.556 6.556.0 01-2.818-1.955 4.338 4.338.0 01-1-2.78v-.345a.443.443.0 01.134-.326.444.444.0 01.326-.135h3.374a.444.444.0 01.326.135.445.445.0 01.134.326v.077a2.014 2.014.0 001.054 1.667 4.672 4.672.0 002.664.709 4.446 4.446.0 002.492-.633 1.862 1.862.0 00.958-1.591 1.426 1.426.0 00-.786-1.322 12.7 12.7.0 00-2.549-.939l-1.457-.46a21.526 21.526.0 01-3.3-1.227 6.57 6.57.0 01-2.262-1.783 4.435 4.435.0 01-.92-2.894 5.081 5.081.0 012.109-4.275 8.993 8.993.0 015.558-1.591 10.445 10.445.0 014.1.748 6.3 6.3.0 012.722 2.07 5 5 0 01.958 3.009.441.441.0 01-.134.326.441.441.0 01-.325.134h-3.258a.441.441.0 01-.326-.134.443.443.0 01-.134-.326 1.974 1.974.0 00-.978-1.667 4.647 4.647.0 00-2.665-.671 4.741 4.741.0 00-2.435.556 1.724 1.724.0 00-.938 1.553 1.512 1.512.0 00.9 1.4 15.875 15.875.0 003.01 1.055l.843.229a27.368 27.368.0 013.412 1.246 6.67 6.67.0 012.338 1.763 4.387 4.387.0 01.958 2.933 4.988 4.988.0 01-2.146 4.275 9.543 9.543.0 01-5.712 1.552 11.626 11.626.0 01-4.227-.709z"/><path d="m97.039 32.837a.443.443.0 01-.326.135h-3.911a.169.169.0 00-.191.192v9.239a2.951 2.951.0 00.632 2.108 2.7 2.7.0 002.013.652h1.15a.444.444.0 01.325.134.441.441.0 01.134.326v2.875a.471.471.0 01-.459.5l-1.994.039a8 8 0 01-4.524-1.035q-1.495-1.035-1.533-3.91V33.166A.17.17.0 0088.164 32.974H85.978A.441.441.0 0185.652 32.839.441.441.0 0185.518 32.513V29.83a.441.441.0 01.134-.326.444.444.0 01.326-.135h2.186a.169.169.0 00.191-.192v-4.485a.438.438.0 01.134-.326.44.44.0 01.325-.134h3.336a.443.443.0 01.325.134.442.442.0 01.135.326v4.485a.169.169.0 00.191.192h3.911a.446.446.0 01.326.135.446.446.0 01.134.326v2.683a.446.446.0 01-.133.324z"/><path d="m101.694 25.917a2.645 2.645.0 01-.767-1.955 2.65 2.65.0 01.767-1.955 2.65 2.65.0 011.955-.767 2.65 2.65.0 011.955.767 2.652 2.652.0 01.767 1.955 2.647 2.647.0 01-.767 1.955 2.646 2.646.0 01-1.955.767 2.645 2.645.0 01-1.955-.767zm-.211 22.906a.441.441.0 01-.134-.326V29.79a.444.444.0 01.134-.326.446.446.0 01.326-.134h3.527a.446.446.0 01.326.134.445.445.0 01.134.326v18.707a.443.443.0 01-.134.326.443.443.0 01-.326.134h-3.527a.443.443.0 01-.326-.134z"/><path d="m114.019 47.734a8.1 8.1.0 01-3.047-4.255 14.439 14.439.0 01-.652-4.37 14.3 14.3.0 01.614-4.371A7.869 7.869.0 01114 30.56a9.072 9.072.0 015.252-1.5 8.543 8.543.0 015.041 1.5 7.985 7.985.0 013.009 4.14 12.439 12.439.0 01.69 4.37 13.793 13.793.0 01-.651 4.37 8.255 8.255.0 01-3.028 4.275 8.475 8.475.0 01-5.1 1.553 8.754 8.754.0 01-5.194-1.534zm7.629-3.1a4.536 4.536.0 001.476-2.262 11.335 11.335.0 00.383-3.221 10.618 10.618.0 00-.383-3.22 4.169 4.169.0 00-1.457-2.243 4.066 4.066.0 00-2.531-.785 3.942 3.942.0 00-2.453.785 4.376 4.376.0 00-1.5 2.243 11.839 11.839.0 00-.383 3.22 11.84 11.84.0 00.383 3.221 4.222 4.222.0 001.476 2.262 4.075 4.075.0 002.549.8 3.8 3.8.0 002.44-.809z"/><path d="m15.105 32.057v15.565a.059.059.0 01-.049.059L.069 50.25A.06.06.0 01.005 50.167l14.987-33.47a.06.06.0 01.114.025z"/><path d="m17.631 23.087v24.6a.06.06.0 00.053.059l22.449 2.507a.06.06.0 00.061-.084L17.745.032a.06.06.0 00-.114.024z"/><path d="m39.961 52.548-24.833 7.45a.062.062.0 01-.043.0L.079 52.548a.059.059.0 01.026-.113h39.839a.06.06.0 01.017.113z"/></svg></span>
|
||
</a><button id=hamburger class=main-navigation-toggle aria-label="Open navigation">
|
||
<svg class="icon menu-hamburger"><use xlink:href="/v1.21/img/icons.svg#menu-hamburger"/></svg>
|
||
</button>
|
||
<button id=menu-close class=main-navigation-toggle aria-label="Close navigation"><svg class="icon menu-close"><use xlink:href="/v1.21/img/icons.svg#menu-close"/></svg></button></div><div id=header-links class=main-navigation-links-wrapper><ul class=main-navigation-links><li class=main-navigation-links-item><a class="main-navigation-links-link has-dropdown"><span>About</span><svg class="icon dropdown-arrow"><use xlink:href="/v1.21/img/icons.svg#dropdown-arrow"/></svg></a><ul class=main-navigation-links-dropdown><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/service-mesh class=main-navigation-links-link>Service mesh</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/solutions class=main-navigation-links-link>Solutions</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/case-studies class=main-navigation-links-link>Case studies</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/ecosystem class=main-navigation-links-link>Ecosystem</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/deployment class=main-navigation-links-link>Deployment</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.21/about/faq class=main-navigation-links-link>FAQ</a></li></ul></li><li class=main-navigation-links-item><a href=/v1.21/blog/ class=main-navigation-links-link><span>Blog</span></a></li><li class=main-navigation-links-item><a href=/v1.21/news/ class=main-navigation-links-link><span>News</span></a></li><li class=main-navigation-links-item><a href=/v1.21/get-involved/ class=main-navigation-links-link><span>Get involved</span></a></li><li class=main-navigation-links-item><a href=/v1.21/docs/ class=main-navigation-links-link><span>Documentation</span></a></li></ul><div class=main-navigation-footer><button id=search-show class=search-show title='Search this site' aria-label=Search><svg class="icon magnifier"><use xlink:href="/v1.21/img/icons.svg#magnifier"/></svg></button>
|
||
<a href=/v1.21/docs/setup/getting-started class="btn btn--primary" id=try-istio>Try Istio</a></div></div><form id=search-form class=search name=cse role=search><input type=hidden name=cx value=002184991200833970123:iwwf17ikgf4>
|
||
<input type=hidden name=ie value=utf-8>
|
||
<input type=hidden name=hl value=en>
|
||
<input type=hidden id=search-page-url value=/search>
|
||
<input id=search-textbox class="search-textbox form-control" name=q type=search aria-label='Search this site' placeholder=Search>
|
||
<button id=search-close title='Cancel search' type=reset aria-label='Cancel search'><svg class="icon menu-close"><use xlink:href="/v1.21/img/icons.svg#menu-close"/></svg></button></form></nav></header><div class=banner-container></div><article class=post itemscope itemtype=http://schema.org/BlogPosting><div class=header-content><h1>Consuming External Web Services</h1><p>Describes a simple scenario based on Istio's Bookinfo example.</p></div><p class=post-author>Jan 31, 2018 <span>| </span>By Vadim Eisenberg</p><div><aside class="callout warning"><div class=type><svg class="large-icon"><use xlink:href="/v1.21/img/icons.svg#callout-warning"/></svg></div><div class=content>This blog post was written assuming Istio 1.1, so some of this content may now be outdated.</div></aside></div><div><p>In many cases, not all the parts of a microservices-based application reside in a <em>service mesh</em>. Sometimes, the
|
||
microservices-based applications use functionality provided by legacy systems that reside outside the mesh. You may want
|
||
to migrate these systems to the service mesh gradually. Until these systems are migrated, they must be accessed by the
|
||
applications inside the mesh. In other cases, the applications use web services provided by third parties.</p><p>In this blog post, I modify the <a href=/v1.21/docs/examples/bookinfo/>Istio Bookinfo Sample Application</a> to fetch book details from
|
||
an external web service (<a href=https://developers.google.com/books/docs/v1/getting_started>Google Books APIs</a>). I show how
|
||
to enable egress HTTPS traffic in Istio by using <em>mesh-external service entries</em>. I provide two options for egress
|
||
HTTPS traffic and describe the pros and cons of each of the options.</p><h2 id=initial-setting>Initial setting</h2><p>To demonstrate the scenario of consuming an external web service, I start with a Kubernetes cluster with <a href=/v1.21/docs/setup/getting-started/>Istio installed</a>. Then I deploy
|
||
<a href=/v1.21/docs/examples/bookinfo/>Istio Bookinfo Sample Application</a>. This application uses the <em>details</em> microservice to fetch
|
||
book details, such as the number of pages and the publisher. The original <em>details</em> microservice provides the book
|
||
details without consulting any external service.</p><p>The example commands in this blog post work with Istio 1.0+, with or without
|
||
<a href=/v1.21/docs/concepts/security/#mutual-tls-authentication>mutual TLS</a> enabled. The Bookinfo configuration files reside in the
|
||
<code>samples/bookinfo</code> directory of the Istio release archive.</p><p>Here is a copy of the end-to-end architecture of the application from the original
|
||
<a href=/v1.21/docs/examples/bookinfo/>Bookinfo sample application</a>.</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.086918235567985%><a data-skipendnotes=true href=/v1.21/docs/examples/bookinfo/withistio.svg title="The Original Bookinfo Application"><img class=element-to-stretch src=/v1.21/docs/examples/bookinfo/withistio.svg alt="The Original Bookinfo Application"></a></div><figcaption>The Original Bookinfo Application</figcaption></figure><p>Perform the steps in the
|
||
<a href=/v1.21/docs/examples/bookinfo/#deploying-the-application>Deploying the application</a>,
|
||
<a href=/v1.21/docs/examples/bookinfo/#confirm-the-app-is-accessible-from-outside-the-cluster>Confirm the app is running</a>,
|
||
<a href=/v1.21/docs/examples/bookinfo/#apply-default-destination-rules>Apply default destination rules</a>
|
||
sections, and
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy>change Istio to the blocking-egress-by-default policy</a>.</p><h2 id=bookinfo-with-https-access-to-a-google-books-web-service>Bookinfo with HTTPS access to a Google Books web service</h2><p>Deploy a new version of the <em>details</em> microservice, <em>v2</em>, that fetches the book details from <a href=https://developers.google.com/books/docs/v1/getting_started>Google Books APIs</a>. Run the following command; it sets the
|
||
<code>DO_NOT_ENCRYPT</code> environment variable of the service’s container to <code>false</code>. This setting will instruct the deployed
|
||
service to use HTTPS (instead of HTTP) to access to the external service.</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@ --dry-run -o yaml | kubectl set env --local -f - 'DO_NOT_ENCRYPT=false' -o yaml | kubectl apply -f -
|
||
</code></pre></div><p>The updated architecture of the application now looks as follows:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:65.1654485092242%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-https/bookinfo-details-v2.svg title="The Bookinfo Application with details V2"><img class=element-to-stretch src=/v1.21/blog/2018/egress-https/bookinfo-details-v2.svg alt="The Bookinfo Application with details V2"></a></div><figcaption>The Bookinfo Application with details V2</figcaption></figure><p>Note that the Google Books web service is outside the Istio service mesh, the boundary of which is marked by a dashed
|
||
line.</p><p>Now direct all the traffic destined to the <em>details</em> microservice, to <em>details version v2</em>.</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
|
||
</code></pre></div><p>Note that the virtual service relies on a destination rule that you created in the <a href=/v1.21/docs/examples/bookinfo/#apply-default-destination-rules>Apply default destination rules</a> section.</p><p>Access the web page of the application, after
|
||
<a href=/v1.21/docs/examples/bookinfo/#determine-the-ingress-ip-and-port>determining the ingress IP and port</a>.</p><p>Oops… Instead of the book details you have the <em>Error fetching product details</em> message displayed:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.18649965205289%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-https/errorFetchingBookDetails.png title="The Error Fetching Product Details Message"><img class=element-to-stretch src=/v1.21/blog/2018/egress-https/errorFetchingBookDetails.png alt="The Error Fetching Product Details Message"></a></div><figcaption>The Error Fetching Product Details Message</figcaption></figure><p>The good news is that your application did not crash. With a good microservice design, you do not have <strong>failure
|
||
propagation</strong>. In your case, the failing <em>details</em> microservice does not cause the <code>productpage</code> microservice to fail.
|
||
Most of the functionality of the application is still provided, despite the failure in the <em>details</em> microservice. You
|
||
have <strong>graceful service degradation</strong>: as you can see, the reviews and the ratings are displayed correctly, and the
|
||
application is still useful.</p><p>So what might have gone wrong? Ah… The answer is that I forgot to tell you to enable traffic from inside the mesh to
|
||
an external service, in this case to the Google Books web service. By default, the Istio sidecar proxies
|
||
(<a href=https://www.envoyproxy.io>Envoy proxies</a>) <strong>block all the traffic to destinations outside the cluster</strong>. To enable
|
||
such traffic, you must define a
|
||
<a href=/v1.21/docs/reference/config/networking/service-entry/>mesh-external service entry</a>.</p><h3 id=enable-https-access-to-a-google-books-web-service>Enable HTTPS access to a Google Books web service</h3><p>No worries, define a <strong>mesh-external service entry</strong> and fix your application. You must also define a <em>virtual
|
||
service</em> to perform routing by <a href=https://en.wikipedia.org/wiki/Server_Name_Indication>SNI</a> to the external service.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: ServiceEntry
|
||
metadata:
|
||
name: googleapis
|
||
spec:
|
||
hosts:
|
||
- www.googleapis.com
|
||
ports:
|
||
- number: 443
|
||
name: https
|
||
protocol: HTTPS
|
||
location: MESH_EXTERNAL
|
||
resolution: DNS
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: googleapis
|
||
spec:
|
||
hosts:
|
||
- www.googleapis.com
|
||
tls:
|
||
- match:
|
||
- port: 443
|
||
sni_hosts:
|
||
- www.googleapis.com
|
||
route:
|
||
- destination:
|
||
host: www.googleapis.com
|
||
port:
|
||
number: 443
|
||
weight: 100
|
||
EOF
|
||
</code></pre><p>Now accessing the web page of the application displays the book details without error:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:34.82831114225648%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-https/externalBookDetails.png title="Book Details Displayed Correctly"><img class=element-to-stretch src=/v1.21/blog/2018/egress-https/externalBookDetails.png alt="Book Details Displayed Correctly"></a></div><figcaption>Book Details Displayed Correctly</figcaption></figure><p>You can query your service entries:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get serviceentries
|
||
NAME AGE
|
||
googleapis 8m
|
||
</code></pre><p>You can delete your service entry:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry googleapis
|
||
serviceentry "googleapis" deleted
|
||
</code></pre><p>and see in the output that the service entry is deleted.</p><p>Accessing the web page after deleting the service entry produces the same error that you experienced before, namely
|
||
<em>Error fetching product details</em>. As you can see, the service entries are defined <strong>dynamically</strong>, as are many other
|
||
Istio configuration artifacts. The Istio operators can decide dynamically which domains they allow the microservices to
|
||
access. They can enable and disable traffic to the external domains on the fly, without redeploying the microservices.</p><h3 id=cleanup-of-https-access-to-a-google-books-web-service>Cleanup of HTTPS access to a Google Books web service</h3><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml>Zip</a><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry googleapis
|
||
$ kubectl delete virtualservice googleapis
|
||
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
|
||
$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@
|
||
</code></pre></div><h2 id=tls-origination-by-istio>TLS origination by Istio</h2><p>There is a caveat to this story. Suppose you want to monitor which specific set of
|
||
<a href=https://developers.google.com/apis-explorer/>Google APIs</a> your microservices use
|
||
(<a href=https://developers.google.com/books/docs/v1/getting_started>Books</a>,
|
||
<a href=https://developers.google.com/calendar/>Calendar</a>, <a href=https://developers.google.com/tasks/>Tasks</a> etc.)
|
||
Suppose you want to enforce a policy that using only
|
||
<a href=https://developers.google.com/books/docs/v1/getting_started>Books APIs</a> is allowed. Suppose you want to monitor the
|
||
book identifiers that your microservices access. For these monitoring and policy tasks you need to know the URL path.
|
||
Consider for example the URL
|
||
<a href="https://www.googleapis.com/books/v1/volumes?q=isbn:0486424618"><code>www.googleapis.com/books/v1/volumes?q=isbn:0486424618</code></a>.
|
||
In that URL, <a href=https://developers.google.com/books/docs/v1/getting_started>Books APIs</a> is specified by the path segment
|
||
<code>/books</code>, and the <a href=https://en.wikipedia.org/wiki/International_Standard_Book_Number>ISBN</a> number by the path segment
|
||
<code>/volumes?q=isbn:0486424618</code>. However, in HTTPS, all the HTTP details (hostname, path, headers etc.) are encrypted and
|
||
such monitoring and policy enforcement by the sidecar proxies is not possible. Istio can only know the server name of
|
||
the encrypted requests by the <a href=https://tools.ietf.org/html/rfc3546#section-3.1>SNI</a> (<em>Server Name Indication</em>) field,
|
||
in this case <code>www.googleapis.com</code>.</p><p>To allow Istio to perform monitoring and policy enforcement of egress requests based on HTTP details, the microservices
|
||
must issue HTTP requests. Istio then opens an HTTPS connection to the destination (performs TLS origination). The code
|
||
of the microservices must be written differently or configured differently, according to whether the microservice runs
|
||
inside or outside an Istio service mesh. This contradicts the Istio design goal of <a href=/v1.21/docs/ops/deployment/architecture/#design-goals>maximizing transparency</a>. Sometimes you need to compromise…</p><p>The diagram below shows two options for sending HTTPS traffic to external services. On the top, a microservice sends
|
||
regular HTTPS requests, encrypted end-to-end. On the bottom, the same microservice sends unencrypted HTTP requests
|
||
inside a pod, which are intercepted by the sidecar Envoy proxy. The sidecar proxy performs TLS origination, so the
|
||
traffic between the pod and the external service is encrypted.</p><figure style=width:60%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:95.1355088590701%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-https/https_from_the_app.svg title="HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy"><img class=element-to-stretch src=/v1.21/blog/2018/egress-https/https_from_the_app.svg alt="HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy"></a></div><figcaption>HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy</figcaption></figure><p>Here is how both patterns are supported in the
|
||
<a href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/src/details/details.rb>Bookinfo details microservice code</a>, using the Ruby
|
||
<a href=https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html>net/http module</a>:</p><pre><code class=language-ruby data-expandlinks=true data-repo=istio>uri = URI.parse('https://www.googleapis.com/books/v1/volumes?q=isbn:' + isbn)
|
||
http = Net::HTTP.new(uri.host, ENV['DO_NOT_ENCRYPT'] === 'true' ? 80:443)
|
||
...
|
||
unless ENV['DO_NOT_ENCRYPT'] === 'true' then
|
||
http.use_ssl = true
|
||
end
|
||
</code></pre><p>When the <code>DO_NOT_ENCRYPT</code> environment variable is defined, the request is performed without SSL (plain HTTP) to port 80.</p><p>You can set the <code>DO_NOT_ENCRYPT</code> environment variable to <em>“true”</em> in the
|
||
<a href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml>Kubernetes deployment spec of details v2</a>,
|
||
the <code>container</code> section:</p><pre><code class=language-yaml data-expandlinks=true data-repo=istio>env:
|
||
- name: DO_NOT_ENCRYPT
|
||
value: "true"
|
||
</code></pre><p>In the next section you will configure TLS origination for accessing an external web service.</p><h2 id=bookinfo-with-tls-origination-to-a-google-books-web-service>Bookinfo with TLS origination to a Google Books web service</h2><ol><li><p>Deploy a version of <em>details v2</em> that sends an HTTP request to
|
||
<a href=https://developers.google.com/books/docs/v1/getting_started>Google Books APIs</a>. The <code>DO_NOT_ENCRYPT</code> variable
|
||
is set to true in
|
||
<a href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml><code>bookinfo-details-v2.yaml</code></a>.</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@
|
||
</code></pre></div></li><li><p>Direct the traffic destined to the <em>details</em> microservice, to <em>details version v2</em>.</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
|
||
</code></pre></div></li><li><p>Create a mesh-external service entry for <code>www.google.apis</code> , a virtual service to rewrite the destination port from
|
||
80 to 443, and a destination rule to perform TLS origination.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: ServiceEntry
|
||
metadata:
|
||
name: googleapis
|
||
spec:
|
||
hosts:
|
||
- www.googleapis.com
|
||
ports:
|
||
- number: 80
|
||
name: http
|
||
protocol: HTTP
|
||
- number: 443
|
||
name: https
|
||
protocol: HTTPS
|
||
resolution: DNS
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: rewrite-port-for-googleapis
|
||
spec:
|
||
hosts:
|
||
- www.googleapis.com
|
||
http:
|
||
- match:
|
||
- port: 80
|
||
route:
|
||
- destination:
|
||
host: www.googleapis.com
|
||
port:
|
||
number: 443
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: originate-tls-for-googleapis
|
||
spec:
|
||
host: www.googleapis.com
|
||
trafficPolicy:
|
||
loadBalancer:
|
||
simple: ROUND_ROBIN
|
||
portLevelSettings:
|
||
- port:
|
||
number: 443
|
||
tls:
|
||
mode: SIMPLE # initiates HTTPS when accessing www.googleapis.com
|
||
EOF
|
||
</code></pre></li><li><p>Access the web page of the application and verify that the book details are displayed without errors.</p></li><li><p><a href=/v1.21/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging>Enable Envoy’s access logging</a></p></li><li><p>Check the log of of the sidecar proxy of <em>details v2</em> and see the HTTP request.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl logs $(kubectl get pods -l app=details -l version=v2 -o jsonpath='{.items[0].metadata.name}') istio-proxy | grep googleapis
|
||
[2018-08-09T11:32:58.171Z] "GET /books/v1/volumes?q=isbn:0486424618 HTTP/1.1" 200 - 0 1050 264 264 "-" "Ruby" "b993bae7-4288-9241-81a5-4cde93b2e3a6" "www.googleapis.com:80" "172.217.20.74:80"
|
||
EOF
|
||
</code></pre><p>Note the URL path in the log, the path can be monitored and access policies can be applied based on it. To read more
|
||
about monitoring and access policies for HTTP egress traffic, check out <a href=https://archive.istio.io/v0.8/blog/2018/egress-monitoring-access-control/#logging>this blog post</a>.</p></li></ol><h3 id=cleanup-of-tls-origination-to-a-google-books-web-service>Cleanup of TLS origination to a Google Books web service</h3><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml>Zip</a><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-details-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry googleapis
|
||
$ kubectl delete virtualservice rewrite-port-for-googleapis
|
||
$ kubectl delete destinationrule originate-tls-for-googleapis
|
||
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
|
||
$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@
|
||
</code></pre></div><h3 id=relation-to-istio-mutual-tls>Relation to Istio mutual TLS</h3><p>Note that the TLS origination in this case is unrelated to
|
||
<a href=/v1.21/docs/concepts/security/#mutual-tls-authentication>the mutual TLS</a> applied by Istio. The TLS origination for the
|
||
external services will work, whether the Istio mutual TLS is enabled or not. The <strong>mutual</strong> TLS secures
|
||
service-to-service communication <strong>inside</strong> the service mesh and provides each service with a strong identity. The
|
||
<strong>external services</strong> in this blog post were accessed using <strong>one-way TLS</strong>, the same mechanism used to secure communication between a
|
||
web browser and a web server. TLS is applied to the communication with external services to verify the identity of the
|
||
external server and to encrypt the traffic.</p><h2 id=conclusion>Conclusion</h2><p>In this blog post I demonstrated how microservices in an Istio service mesh can consume external web services by
|
||
HTTPS. By default, Istio blocks all the traffic to the hosts outside the cluster. To enable such traffic, mesh-external
|
||
service entries must be created for the service mesh. It is possible to access the external sites either by
|
||
issuing HTTPS requests, or by issuing HTTP requests with Istio performing TLS origination. When the microservices issue
|
||
HTTPS requests, the traffic is encrypted end-to-end, however Istio cannot monitor HTTP details like the URL paths of the
|
||
requests. When the microservices issue HTTP requests, Istio can monitor the HTTP details of the requests and enforce
|
||
HTTP-based access policies. However, in that case the traffic between microservice and the sidecar proxy is unencrypted.
|
||
Having part of the traffic unencrypted can be forbidden in organizations with very strict security requirements.</p></div><nav class=pagenav><div class=left><a title="Describes a simple scenario based on Istio's Bookinfo example." href=/v1.21/blog/2018/egress-tcp/ class=next-link><svg class="icon left-arrow"><use xlink:href="/v1.21/img/icons.svg#left-arrow"/></svg>Consuming External TCP Services</a></div><div class=right></div></nav></article><footer class=footer><div class="footer-wrapper container-l"><div class="user-links footer-links"><a class=channel title='GitHub is where development takes place on Istio code' href=https://github.com/istio/community aria-label=GitHub><svg class="icon github"><use xlink:href="/v1.21/img/icons.svg#github"/></svg>
|
||
</a><a class=channel title="Access our team drive if you'd like to take a look at the Istio technical design documents" href=https://groups.google.com/forum/#!forum/istio-team-drive-access aria-label="team drive"><svg class="icon drive"><use xlink:href="/v1.21/img/icons.svg#drive"/></svg>
|
||
</a><a class=channel title='Interactively discuss issues with the Istio community on Slack' href=https://slack.istio.io aria-label=slack><svg class="icon slack"><use xlink:href="/v1.21/img/icons.svg#slack"/></svg>
|
||
</a><a class=channel title='Stack Overflow is where you can ask questions and find curated answers on deploying, configuring, and using Istio' href=https://stackoverflow.com/questions/tagged/istio aria-label="Stack Overflow"><svg class="icon stackoverflow"><use xlink:href="/v1.21/img/icons.svg#stackoverflow"/></svg>
|
||
</a><a class=channel title='Follow us on Twitter to get the latest news' href=https://twitter.com/IstioMesh aria-label=Twitter><svg class="icon twitter"><use xlink:href="/v1.21/img/icons.svg#twitter"/></svg></a></div><hr class=footer-separator role=separator><div class="info footer-info"><a class=logo href=/v1.21/ aria-label=logotype><svg xmlns="http://www.w3.org/2000/svg" width="128" height="60" viewBox="0 0 128 60"><path d="M58.434 48.823A.441.441.0 0158.3 48.497V22.583a.444.444.0 01.134-.326.446.446.0 01.327-.134h3.527a.447.447.0 01.325.134.447.447.0 01.134.326v25.914a.443.443.0 01-.134.326.444.444.0 01-.325.134h-3.527a.444.444.0 01-.327-.134z"/><path d="m70.969 48.477a6.556 6.556.0 01-2.818-1.955 4.338 4.338.0 01-1-2.78v-.345a.443.443.0 01.134-.326.444.444.0 01.326-.135h3.374a.444.444.0 01.326.135.445.445.0 01.134.326v.077a2.014 2.014.0 001.054 1.667 4.672 4.672.0 002.664.709 4.446 4.446.0 002.492-.633 1.862 1.862.0 00.958-1.591 1.426 1.426.0 00-.786-1.322 12.7 12.7.0 00-2.549-.939l-1.457-.46a21.526 21.526.0 01-3.3-1.227 6.57 6.57.0 01-2.262-1.783 4.435 4.435.0 01-.92-2.894 5.081 5.081.0 012.109-4.275 8.993 8.993.0 015.558-1.591 10.445 10.445.0 014.1.748 6.3 6.3.0 012.722 2.07 5 5 0 01.958 3.009.441.441.0 01-.134.326.441.441.0 01-.325.134h-3.258a.441.441.0 01-.326-.134.443.443.0 01-.134-.326 1.974 1.974.0 00-.978-1.667 4.647 4.647.0 00-2.665-.671 4.741 4.741.0 00-2.435.556 1.724 1.724.0 00-.938 1.553 1.512 1.512.0 00.9 1.4 15.875 15.875.0 003.01 1.055l.843.229a27.368 27.368.0 013.412 1.246 6.67 6.67.0 012.338 1.763 4.387 4.387.0 01.958 2.933 4.988 4.988.0 01-2.146 4.275 9.543 9.543.0 01-5.712 1.552 11.626 11.626.0 01-4.227-.709z"/><path d="m97.039 32.837a.443.443.0 01-.326.135h-3.911a.169.169.0 00-.191.192v9.239a2.951 2.951.0 00.632 2.108 2.7 2.7.0 002.013.652h1.15a.444.444.0 01.325.134.441.441.0 01.134.326v2.875a.471.471.0 01-.459.5l-1.994.039a8 8 0 01-4.524-1.035q-1.495-1.035-1.533-3.91V33.166A.17.17.0 0088.164 32.974H85.978A.441.441.0 0185.652 32.839.441.441.0 0185.518 32.513V29.83a.441.441.0 01.134-.326.444.444.0 01.326-.135h2.186a.169.169.0 00.191-.192v-4.485a.438.438.0 01.134-.326.44.44.0 01.325-.134h3.336a.443.443.0 01.325.134.442.442.0 01.135.326v4.485a.169.169.0 00.191.192h3.911a.446.446.0 01.326.135.446.446.0 01.134.326v2.683a.446.446.0 01-.133.324z"/><path d="m101.694 25.917a2.645 2.645.0 01-.767-1.955 2.65 2.65.0 01.767-1.955 2.65 2.65.0 011.955-.767 2.65 2.65.0 011.955.767 2.652 2.652.0 01.767 1.955 2.647 2.647.0 01-.767 1.955 2.646 2.646.0 01-1.955.767 2.645 2.645.0 01-1.955-.767zm-.211 22.906a.441.441.0 01-.134-.326V29.79a.444.444.0 01.134-.326.446.446.0 01.326-.134h3.527a.446.446.0 01.326.134.445.445.0 01.134.326v18.707a.443.443.0 01-.134.326.443.443.0 01-.326.134h-3.527a.443.443.0 01-.326-.134z"/><path d="m114.019 47.734a8.1 8.1.0 01-3.047-4.255 14.439 14.439.0 01-.652-4.37 14.3 14.3.0 01.614-4.371A7.869 7.869.0 01114 30.56a9.072 9.072.0 015.252-1.5 8.543 8.543.0 015.041 1.5 7.985 7.985.0 013.009 4.14 12.439 12.439.0 01.69 4.37 13.793 13.793.0 01-.651 4.37 8.255 8.255.0 01-3.028 4.275 8.475 8.475.0 01-5.1 1.553 8.754 8.754.0 01-5.194-1.534zm7.629-3.1a4.536 4.536.0 001.476-2.262 11.335 11.335.0 00.383-3.221 10.618 10.618.0 00-.383-3.22 4.169 4.169.0 00-1.457-2.243 4.066 4.066.0 00-2.531-.785 3.942 3.942.0 00-2.453.785 4.376 4.376.0 00-1.5 2.243 11.839 11.839.0 00-.383 3.22 11.84 11.84.0 00.383 3.221 4.222 4.222.0 001.476 2.262 4.075 4.075.0 002.549.8 3.8 3.8.0 002.44-.809z"/><path d="m15.105 32.057v15.565a.059.059.0 01-.049.059L.069 50.25A.06.06.0 01.005 50.167l14.987-33.47a.06.06.0 01.114.025z"/><path d="m17.631 23.087v24.6a.06.06.0 00.053.059l22.449 2.507a.06.06.0 00.061-.084L17.745.032a.06.06.0 00-.114.024z"/><path d="m39.961 52.548-24.833 7.45a.062.062.0 01-.043.0L.079 52.548a.059.059.0 01.026-.113h39.839a.06.06.0 01.017.113z"/></svg></a><div class=footer-languages><a tabindex=-1 lang=en id=switch-lang-en class="footer-languages-item active"><svg class="icon tick"><use xlink:href="/v1.21/img/icons.svg#tick"/></svg>
|
||
English
|
||
</a><a tabindex=-1 lang=zh id=switch-lang-zh class=footer-languages-item>中文</a></div></div><ul class=footer-policies><li class=footer-policies-item><a class=footer-policies-link href=https://www.linuxfoundation.org/legal/terms>Terms and Conditions
|
||
</a>|
|
||
<a class=footer-policies-link href=https://www.linuxfoundation.org/legal/privacy-policy>Privacy policy
|
||
</a>|
|
||
<a class=footer-policies-link href=https://www.linuxfoundation.org/legal/trademark-usage>Trademarks
|
||
</a>|
|
||
<a class=footer-policies-link href=https://github.com/istio/istio.io/edit/release-1.21/content/en/index>Edit this Page on GitHub</a></li></ul><div class=footer-base><span class=footer-base-copyright>© 2024 the Istio Authors.</span>
|
||
<span class=footer-base-version>Version
|
||
Archive
|
||
1.21.2</span><ul class=footer-base-releases><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link onclick='return navigateToUrlOrRoot("https://istio.io/blog/2018/egress-https/"),!1'>current release</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link onclick='return navigateToUrlOrRoot("https://preliminary.istio.io/blog/2018/egress-https/"),!1'>next release</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link href=https://istio.io/archive>older releases</a></li></ul></div></div></footer><div id=scroll-to-top-container aria-hidden=true><button id=scroll-to-top title='Back to top' tabindex=-1><svg class="icon top"><use xlink:href="/v1.21/img/icons.svg#top"/></svg></button></div></body></html> |