mirror of https://github.com/istio/istio.io.git
820 lines
68 KiB
HTML
820 lines
68 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 MongoDB 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,tcp,mongo"><meta property="og:title" content="Consuming External MongoDB 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-mongo/"><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 MongoDB 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 MongoDB 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 MongoDB Services</h1><p>Describes a simple scenario based on Istio's Bookinfo example.</p></div><p class=post-author>Nov 16, 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 the <a href=/v1.21/blog/2018/egress-tcp/>Consuming External TCP Services</a> blog post, I described how external services
|
||
can be consumed by in-mesh Istio applications via TCP. In this post, I demonstrate consuming external MongoDB services.
|
||
You use the <a href=/v1.21/docs/examples/bookinfo/>Istio Bookinfo sample application</a>, the version in which the book
|
||
ratings data is persisted in a MongoDB database. You deploy this database outside the cluster and configure the
|
||
<em>ratings</em> microservice to use it. You will learn multiple options of controlling traffic to external MongoDB services and their
|
||
pros and cons.</p><h2 id=bookinfo-with-external-ratings-database>Bookinfo with external ratings database</h2><p>First, you set up a MongoDB database instance to hold book ratings data outside of your Kubernetes cluster. Then you
|
||
modify the <a href=/v1.21/docs/examples/bookinfo/>Bookinfo sample application</a> to use your database.</p><h3 id=setting-up-the-ratings-database>Setting up the ratings database</h3><p>For this task you set up an instance of <a href=https://www.mongodb.com>MongoDB</a>. You can use any MongoDB instance; I used
|
||
<a href=https://www.ibm.com/cloud/compose/mongodb>Compose for MongoDB</a>.</p><ol><li><p>Set an environment variable for the password of your <code>admin</code> user. To prevent the password from being preserved in
|
||
the Bash history, remove the command from the history immediately after running the command, using
|
||
<a href=https://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins>history -d</a>.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export MONGO_ADMIN_PASSWORD=<your MongoDB admin password>
|
||
</code></pre></li><li><p>Set an environment variable for the password of the new user you will create, namely <code>bookinfo</code>.
|
||
Remove the command from the history using
|
||
<a href=https://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins>history -d</a>.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export BOOKINFO_PASSWORD=<password>
|
||
</code></pre></li><li><p>Set environment variables for your MongoDB service, <code>MONGODB_HOST</code> and <code>MONGODB_PORT</code>.</p></li><li><p>Create the <code>bookinfo</code> user:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
|
||
use test
|
||
db.createUser(
|
||
{
|
||
user: "bookinfo",
|
||
pwd: "$BOOKINFO_PASSWORD",
|
||
roles: [ "read"]
|
||
}
|
||
);
|
||
EOF
|
||
</code></pre></li><li><p>Create a <em>collection</em> to hold ratings. The following command sets both ratings to be equal <code>1</code> to provide a visual
|
||
clue when your database is used by the Bookinfo <em>ratings</em> service (the default Bookinfo <em>ratings</em> are <code>4</code> and <code>5</code>).</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
|
||
use test
|
||
db.createCollection("ratings");
|
||
db.ratings.insert(
|
||
[{rating: 1},
|
||
{rating: 1}]
|
||
);
|
||
EOF
|
||
</code></pre></li><li><p>Check that <code>bookinfo</code> user can get ratings:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u bookinfo -p $BOOKINFO_PASSWORD --authenticationDatabase test
|
||
use test
|
||
db.ratings.find({});
|
||
EOF
|
||
</code></pre><p>The output should be similar to:</p><pre><code class=language-plain data-expandlinks=true data-repo=istio>MongoDB server version: 3.4.10
|
||
switched to db test
|
||
{ "_id" : ObjectId("5b7c29efd7596e65b6ed2572"), "rating" : 1 }
|
||
{ "_id" : ObjectId("5b7c29efd7596e65b6ed2573"), "rating" : 1 }
|
||
bye
|
||
</code></pre></li></ol><h3 id=initial-setting-of-bookinfo-application>Initial setting of Bookinfo application</h3><p>To demonstrate the scenario of using an external database, you start with a Kubernetes cluster with <a href=/v1.21/docs/setup/getting-started/>Istio installed</a>. Then you deploy the
|
||
<a href=/v1.21/docs/examples/bookinfo/>Istio Bookinfo sample application</a>, <a href=/v1.21/docs/examples/bookinfo/#apply-default-destination-rules>apply the default destination rules</a>, 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><p>This application uses the <code>ratings</code> microservice to fetch book ratings, a number between 1 and 5. The ratings are
|
||
displayed as stars for each review. There are several versions of the <code>ratings</code> microservice. You will deploy the
|
||
version that uses <a href=https://www.mongodb.com>MongoDB</a> as the ratings database in the next subsection.</p><p>The example commands in this blog post work with Istio 1.0.</p><p>As a reminder, here is the end-to-end architecture of the application from the
|
||
<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><h3 id=use-the-external-database-in-bookinfo-application>Use the external database in Bookinfo application</h3><ol><li><p>Deploy the spec of the <em>ratings</em> microservice that uses a MongoDB database (<em>ratings v2</em>):</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml@
|
||
serviceaccount "bookinfo-ratings-v2" created
|
||
deployment "ratings-v2" created
|
||
</code></pre></div></li><li><p>Update the <code>MONGO_DB_URL</code> environment variable to the value of your MongoDB:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl set env deployment/ratings-v2 "MONGO_DB_URL=mongodb://bookinfo:$BOOKINFO_PASSWORD@$MONGODB_HOST:$MONGODB_PORT/test?authSource=test&ssl=true"
|
||
deployment.extensions/ratings-v2 env updated
|
||
</code></pre></li><li><p>Route all the traffic destined to the <em>reviews</em> service to its <em>v3</em> version. You do this to ensure that the
|
||
<em>reviews</em> service always calls the <em>ratings</em> service. In addition, route all the traffic destined to the <em>ratings</em>
|
||
service to <em>ratings v2</em> that uses your database.</p><p>Specify the routing for both services above by adding two
|
||
<a href=/v1.21/docs/reference/config/networking/virtual-service/>virtual services</a>. These virtual services are
|
||
specified in <code>samples/bookinfo/networking/virtual-service-ratings-mongodb.yaml</code> of an Istio release archive.
|
||
<em><strong>Important:</strong></em> make sure you
|
||
<a href=/v1.21/docs/examples/bookinfo/#apply-default-destination-rules>applied the default destination rules</a> before running the
|
||
following command.</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-ratings-db.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-db.yaml@
|
||
</code></pre></div></li></ol><p>The updated architecture appears below. Note that the blue arrows inside the mesh mark the traffic configured according
|
||
to the virtual services we added. According to the virtual services, the traffic is sent to <em>reviews v3</em> and
|
||
<em>ratings v2</em>.</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.314858206480224%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-mongo/bookinfo-ratings-v2-mongodb-external.svg title="The Bookinfo application with ratings v2 and an external MongoDB database"><img class=element-to-stretch src=/v1.21/blog/2018/egress-mongo/bookinfo-ratings-v2-mongodb-external.svg alt="The Bookinfo application with ratings v2 and an external MongoDB database"></a></div><figcaption>The Bookinfo application with ratings v2 and an external MongoDB database</figcaption></figure><p>Note that the MongoDB database is outside the Istio service mesh, or more precisely outside the Kubernetes cluster. The
|
||
boundary of the service mesh is marked by a dashed line.</p><h3 id=access-the-webpage>Access the webpage</h3><p>Access the webpage 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>Since you did not configure the egress traffic control yet, the access to the MongoDB service is blocked by Istio.
|
||
This is why instead of the rating stars, the message <em>“Ratings service is currently unavailable”</em> is currently
|
||
displayed below each review:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.18705035971223%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-mongo/errorFetchingBookRating.png title="The Ratings service error messages"><img class=element-to-stretch src=/v1.21/blog/2018/egress-mongo/errorFetchingBookRating.png alt="The Ratings service error messages"></a></div><figcaption>The Ratings service error messages</figcaption></figure><p>In the following sections you will configure egress access to the external MongoDB service, using different options for
|
||
egress control in Istio.</p><h2 id=egress-control-for-tcp>Egress control for TCP</h2><p>Since <a href=https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/>MongoDB Wire Protocol</a> runs on top of TCP, you
|
||
can control the egress traffic to your MongoDB as traffic to any other <a href=/v1.21/blog/2018/egress-tcp/>external TCP service</a>. To
|
||
control TCP traffic, a block of IPs in the <a href=https://tools.ietf.org/html/rfc2317>CIDR</a> notation that includes the IP
|
||
address of your MongoDB host must be specified. The caveat here is that sometimes the IP of the MongoDB host is not
|
||
stable or known in advance.</p><p>In the cases when the IP of the MongoDB host is not stable, the egress traffic can either be
|
||
<a href=/v1.21/blog/2018/egress-mongo/#egress-control-for-tls>controlled as TLS traffic</a>, or the traffic can be routed
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/egress-control/#direct-access-to-external-services>directly</a>, bypassing the Istio sidecar
|
||
proxies.</p><p>Get the IP address of your MongoDB database instance. As an option, you can use the
|
||
<a href=https://linux.die.net/man/1/host>host</a> command:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export MONGODB_IP=$(host $MONGODB_HOST | grep " has address " | cut -d" " -f4)
|
||
</code></pre><h3 id=control-tcp-egress-traffic-without-a-gateway>Control TCP egress traffic without a gateway</h3><p>In case you do not need to direct the traffic through an
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#use-case>egress gateway</a>, for example if you do not have a
|
||
requirement that all the traffic that exists your mesh must exit through the gateway, follow the
|
||
instructions in this section. Alternatively, if you do want to direct your traffic through an egress gateway, proceed to
|
||
<a href=/v1.21/blog/2018/egress-mongo/#direct-tcp-egress-traffic-through-an-egress-gateway>Direct TCP egress traffic through an egress gateway</a>.</p><ol><li><p>Define a TCP mesh-external service entry:</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: mongo
|
||
spec:
|
||
hosts:
|
||
- my-mongo.tcp.svc
|
||
addresses:
|
||
- $MONGODB_IP/32
|
||
ports:
|
||
- number: $MONGODB_PORT
|
||
name: tcp
|
||
protocol: TCP
|
||
location: MESH_EXTERNAL
|
||
resolution: STATIC
|
||
endpoints:
|
||
- address: $MONGODB_IP
|
||
EOF
|
||
</code></pre><p>Note that the protocol <code>TCP</code> is specified instead of <code>MONGO</code> due to the fact that the traffic can be encrypted in
|
||
case <a href=https://docs.mongodb.com/manual/tutorial/configure-ssl/>the MongoDB protocol runs on top of TLS</a>.
|
||
If the traffic is encrypted, the encrypted MongoDB protocol cannot be parsed by the Istio proxy.</p><p>If you know that the plain MongoDB protocol is used, without encryption, you can specify the protocol as <code>MONGO</code> and
|
||
let the Istio proxy produce
|
||
<a href=https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/mongo_proxy_filter#statistics>MongoDB related statistics</a>.
|
||
Also note that when the protocol <code>TCP</code> is specified, the configuration is not specific for MongoDB, but is the same
|
||
for any other database with the protocol on top of TCP.</p><p>Note that the host of your MongoDB is not used in TCP routing, so you can use any host, for example <code>my-mongo.tcp.svc</code>. Notice the <code>STATIC</code> resolution and the endpoint with the IP of your MongoDB service. Once you define such an endpoint, you can access MongoDB services that do not have a domain name.</p></li><li><p>Refresh the web page of the application. Now the application should display the ratings without error:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.69064748201439%><a data-skipendnotes=true href=/v1.21/blog/2018/egress-mongo/externalDBRatings.png title="Book Ratings Displayed Correctly"><img class=element-to-stretch src=/v1.21/blog/2018/egress-mongo/externalDBRatings.png alt="Book Ratings Displayed Correctly"></a></div><figcaption>Book Ratings Displayed Correctly</figcaption></figure><p>Note that you see a one-star rating for both displayed reviews, as expected. You set the ratings to be one star to
|
||
provide yourself with a visual clue that your external database is indeed being used.</p></li><li><p>If you want to direct the traffic through an egress gateway, proceed to the next section. Otherwise, perform
|
||
<a href=/v1.21/blog/2018/egress-mongo/#cleanup-of-tcp-egress-traffic-control>cleanup</a>.</p></li></ol><h3 id=direct-tcp-egress-traffic-through-an-egress-gateway>Direct TCP Egress traffic through an egress gateway</h3><p>In this section you handle the case when you need to direct the traffic through an
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#use-case>egress gateway</a>. The sidecar proxy routes TCP
|
||
connections from the MongoDB client to the egress gateway, by matching the IP of the MongoDB host (a CIDR block of
|
||
length 32). The egress gateway forwards the traffic to the MongoDB host, by its hostname.</p><ol><li><p><a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#deploy-istio-egress-gateway>Deploy Istio egress gateway</a>.</p></li><li><p>If you did not perform the steps in <a href=/v1.21/blog/2018/egress-mongo/#control-tcp-egress-traffic-without-a-gateway>the previous section</a>, perform them now.</p></li><li><p>You may want to enable <span class=term data-title="Mutual TLS Authentication" data-body='<p>Mutual TLS provides strong service-to-service authentication with built-in identity and credential management.
|
||
<a href="/docs/concepts/security/#mutual-tls-authentication">Learn more about mutual TLS authentication</a>.</p>
|
||
'>mutual TLS Authentication</span> between the sidecar proxies of
|
||
your MongoDB clients and the egress gateway to let the egress gateway monitor the identity of the source pods and to
|
||
enable Mixer policy enforcement based on that identity. By enabling mutual TLS you also encrypt the traffic.
|
||
If you do not want to enable mutual TLS, proceed to the <a href=/v1.21/blog/2018/egress-mongo/#mutual-tls-between-the-sidecar-proxies-and-the-egress-gateway>Mutual TLS between the sidecar proxies and the egress gateway</a> section.
|
||
Otherwise, proceed to the following section.</p></li></ol><h4 id=configure-tcp-traffic-from-sidecars-to-the-egress-gateway>Configure TCP traffic from sidecars to the egress gateway</h4><ol><li><p>Define the <code>EGRESS_GATEWAY_MONGODB_PORT</code> environment variable to hold some port for directing traffic through
|
||
the egress gateway, e.g. <code>7777</code>. You must select a port that is not used for any other service in the mesh.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export EGRESS_GATEWAY_MONGODB_PORT=7777
|
||
</code></pre></li><li><p>Add the selected port to the <code>istio-egressgateway</code> service. You should use the same values you used for installing
|
||
Istio, in particular you have to specify all the ports of the <code>istio-egressgateway</code> service that you previously
|
||
configured.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ helm template install/kubernetes/helm/istio/ --name istio-egressgateway --namespace istio-system -x charts/gateways/templates/deployment.yaml -x charts/gateways/templates/service.yaml --set gateways.istio-ingressgateway.enabled=false --set gateways.istio-egressgateway.enabled=true --set gateways.istio-egressgateway.ports[0].port=80 --set gateways.istio-egressgateway.ports[0].name=http --set gateways.istio-egressgateway.ports[1].port=443 --set gateways.istio-egressgateway.ports[1].name=https --set gateways.istio-egressgateway.ports[2].port=$EGRESS_GATEWAY_MONGODB_PORT --set gateways.istio-egressgateway.ports[2].name=mongo | kubectl apply -f -
|
||
</code></pre></li><li><p>Check that the <code>istio-egressgateway</code> service indeed has the selected port:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get svc istio-egressgateway -n istio-system
|
||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||
istio-egressgateway ClusterIP 172.21.202.204 <none> 80/TCP,443/TCP,7777/TCP 34d
|
||
</code></pre></li><li><p>Disable mutual TLS authentication for the <code>istio-egressgateway</code> service:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: authentication.istio.io/v1alpha1
|
||
kind: Policy
|
||
metadata:
|
||
name: istio-egressgateway
|
||
namespace: istio-system
|
||
spec:
|
||
targets:
|
||
- name: istio-egressgateway
|
||
EOF
|
||
</code></pre></li><li><p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and a virtual service to direct the
|
||
traffic through the egress gateway and from the egress gateway 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: Gateway
|
||
metadata:
|
||
name: istio-egressgateway
|
||
spec:
|
||
selector:
|
||
istio: egressgateway
|
||
servers:
|
||
- port:
|
||
number: $EGRESS_GATEWAY_MONGODB_PORT
|
||
name: tcp
|
||
protocol: TCP
|
||
hosts:
|
||
- my-mongo.tcp.svc
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: egressgateway-for-mongo
|
||
spec:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subsets:
|
||
- name: mongo
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: mongo
|
||
spec:
|
||
host: my-mongo.tcp.svc
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: direct-mongo-through-egress-gateway
|
||
spec:
|
||
hosts:
|
||
- my-mongo.tcp.svc
|
||
gateways:
|
||
- mesh
|
||
- istio-egressgateway
|
||
tcp:
|
||
- match:
|
||
- gateways:
|
||
- mesh
|
||
destinationSubnets:
|
||
- $MONGODB_IP/32
|
||
port: $MONGODB_PORT
|
||
route:
|
||
- destination:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subset: mongo
|
||
port:
|
||
number: $EGRESS_GATEWAY_MONGODB_PORT
|
||
- match:
|
||
- gateways:
|
||
- istio-egressgateway
|
||
port: $EGRESS_GATEWAY_MONGODB_PORT
|
||
route:
|
||
- destination:
|
||
host: my-mongo.tcp.svc
|
||
port:
|
||
number: $MONGODB_PORT
|
||
weight: 100
|
||
EOF
|
||
</code></pre></li><li><p><a href=/v1.21/blog/2018/egress-mongo/#verify-that-egress-traffic-is-directed-through-the-egress-gateway>Verify that egress traffic is directed through the egress gateway</a>.</p></li></ol><h4 id=mutual-tls-between-the-sidecar-proxies-and-the-egress-gateway>Mutual TLS between the sidecar proxies and the egress gateway</h4><ol><li><p>Delete the previous configuration:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete gateway istio-egressgateway --ignore-not-found=true
|
||
$ kubectl delete virtualservice direct-mongo-through-egress-gateway --ignore-not-found=true
|
||
$ kubectl delete destinationrule egressgateway-for-mongo mongo --ignore-not-found=true
|
||
$ kubectl delete policy istio-egressgateway -n istio-system --ignore-not-found=true
|
||
</code></pre></li><li><p>Enforce mutual TLS authentication for the <code>istio-egressgateway</code> service:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: authentication.istio.io/v1alpha1
|
||
kind: Policy
|
||
metadata:
|
||
name: istio-egressgateway
|
||
namespace: istio-system
|
||
spec:
|
||
targets:
|
||
- name: istio-egressgateway
|
||
peers:
|
||
- mtls: {}
|
||
EOF
|
||
</code></pre></li><li><p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and a virtual service
|
||
to direct the traffic through the egress gateway and from the egress gateway 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: Gateway
|
||
metadata:
|
||
name: istio-egressgateway
|
||
spec:
|
||
selector:
|
||
istio: egressgateway
|
||
servers:
|
||
- port:
|
||
number: 443
|
||
name: tls
|
||
protocol: TLS
|
||
hosts:
|
||
- my-mongo.tcp.svc
|
||
tls:
|
||
mode: MUTUAL
|
||
serverCertificate: /etc/certs/cert-chain.pem
|
||
privateKey: /etc/certs/key.pem
|
||
caCertificates: /etc/certs/root-cert.pem
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: egressgateway-for-mongo
|
||
spec:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subsets:
|
||
- name: mongo
|
||
trafficPolicy:
|
||
loadBalancer:
|
||
simple: ROUND_ROBIN
|
||
portLevelSettings:
|
||
- port:
|
||
number: 443
|
||
tls:
|
||
mode: ISTIO_MUTUAL
|
||
sni: my-mongo.tcp.svc
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: mongo
|
||
spec:
|
||
host: my-mongo.tcp.svc
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: direct-mongo-through-egress-gateway
|
||
spec:
|
||
hosts:
|
||
- my-mongo.tcp.svc
|
||
gateways:
|
||
- mesh
|
||
- istio-egressgateway
|
||
tcp:
|
||
- match:
|
||
- gateways:
|
||
- mesh
|
||
destinationSubnets:
|
||
- $MONGODB_IP/32
|
||
port: $MONGODB_PORT
|
||
route:
|
||
- destination:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subset: mongo
|
||
port:
|
||
number: 443
|
||
- match:
|
||
- gateways:
|
||
- istio-egressgateway
|
||
port: 443
|
||
route:
|
||
- destination:
|
||
host: my-mongo.tcp.svc
|
||
port:
|
||
number: $MONGODB_PORT
|
||
weight: 100
|
||
EOF
|
||
</code></pre></li><li><p>Proceed to the next section.</p></li></ol><h4 id=verify-that-egress-traffic-is-directed-through-the-egress-gateway>Verify that egress traffic is directed through the egress gateway</h4><ol><li><p>Refresh the web page of the application again and verify that the ratings are still displayed correctly.</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 the egress gateway’s Envoy and see a line that corresponds to your
|
||
requests to the MongoDB service. If Istio is deployed in the <code>istio-system</code> namespace, the command to print the
|
||
log is:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl logs -l istio=egressgateway -n istio-system
|
||
[2019-04-14T06:12:07.636Z] "- - -" 0 - "-" 1591 4393 94 - "-" "-" "-" "-" "<Your MongoDB IP>:<your MongoDB port>" outbound|<your MongoDB port>||my-mongo.tcp.svc 172.30.146.119:59924 172.30.146.119:443 172.30.230.1:59206 -
|
||
</code></pre></li></ol><h3 id=cleanup-of-tcp-egress-traffic-control>Cleanup of TCP egress traffic control</h3><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry mongo
|
||
$ kubectl delete gateway istio-egressgateway --ignore-not-found=true
|
||
$ kubectl delete virtualservice direct-mongo-through-egress-gateway --ignore-not-found=true
|
||
$ kubectl delete destinationrule egressgateway-for-mongo mongo --ignore-not-found=true
|
||
$ kubectl delete policy istio-egressgateway -n istio-system --ignore-not-found=true
|
||
</code></pre><h2 id=egress-control-for-tls>Egress control for TLS</h2><p>In the real life, most of the communication to the external services must be encrypted and
|
||
<a href=https://docs.mongodb.com/manual/tutorial/configure-ssl/>the MongoDB protocol runs on top of TLS</a>.
|
||
Also, the TLS clients usually send
|
||
<a href=https://en.wikipedia.org/wiki/Server_Name_Indication>Server Name Indication</a>, SNI, as part of their handshake. If your
|
||
MongoDB server runs TLS and your MongoDB client sends SNI as part of the handshake, you can control your MongoDB egress
|
||
traffic as any other TLS-with-SNI traffic. With TLS and SNI, you do not need to specify the IP addresses of your MongoDB
|
||
servers. You specify their host names instead, which is more convenient since you do not have to rely on the stability of
|
||
the IP addresses. You can also specify wildcards as a prefix of the host names, for example allowing access to any
|
||
server from the <code>*.com</code> domain.</p><p>To check if your MongoDB server supports TLS, run:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ openssl s_client -connect $MONGODB_HOST:$MONGODB_PORT -servername $MONGODB_HOST
|
||
</code></pre><p>If the command above prints a certificate returned by the server, the server supports TLS. If not, you have to control
|
||
your MongoDB egress traffic on the TCP level, as described in the previous sections.</p><h3 id=control-tls-egress-traffic-without-a-gateway>Control TLS egress traffic without a gateway</h3><p>In case you <a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#use-case>do not need an egress gateway</a>, follow the
|
||
instructions in this section. If you want to direct your traffic through an egress gateway, proceed to
|
||
<a href=/v1.21/blog/2018/egress-mongo/#direct-tcp-egress-traffic-through-an-egress-gateway>Direct TCP Egress traffic through an egress gateway</a>.</p><ol><li><p>Create a <code>ServiceEntry</code> for the MongoDB 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: mongo
|
||
spec:
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
ports:
|
||
- number: $MONGODB_PORT
|
||
name: tls
|
||
protocol: TLS
|
||
resolution: DNS
|
||
EOF
|
||
</code></pre></li><li><p>Refresh the web page of the application. The application should display the ratings without error.</p></li></ol><h4 id=cleanup-of-the-egress-configuration-for-tls>Cleanup of the egress configuration for TLS</h4><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry mongo
|
||
</code></pre><h3 id=direct-tls-egress-traffic-through-an-egress-gateway>Direct TLS Egress traffic through an egress gateway</h3><p>In this section you handle the case when you need to direct the traffic through an
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#use-case>egress gateway</a>. The sidecar proxy routes TLS
|
||
connections from the MongoDB client to the egress gateway, by matching the SNI of the MongoDB host.
|
||
The egress gateway forwards the traffic to the MongoDB host. Note that the sidecar proxy rewrites the destination port
|
||
to be 443. The egress gateway accepts the MongoDB traffic on the port 443, matches the MongoDB host by SNI, and rewrites
|
||
the port again to be the port of the MongoDB server.</p><ol><li><p><a href=/v1.21/docs/tasks/traffic-management/egress/egress-gateway/#deploy-istio-egress-gateway>Deploy Istio egress gateway</a>.</p></li><li><p>Create a <code>ServiceEntry</code> for the MongoDB 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: mongo
|
||
spec:
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
ports:
|
||
- number: $MONGODB_PORT
|
||
name: tls
|
||
protocol: TLS
|
||
- number: 443
|
||
name: tls-port-for-egress-gateway
|
||
protocol: TLS
|
||
resolution: DNS
|
||
location: MESH_EXTERNAL
|
||
EOF
|
||
</code></pre></li><li><p>Refresh the web page of the application and verify that the ratings are displayed correctly.</p></li><li><p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and virtual services
|
||
to direct the traffic through the egress gateway and from the egress gateway to the external service.</p><p>If you want to enable <a href=/v1.21/docs/tasks/security/authentication/authn-policy/>mutual TLS Authentication</a> between the sidecar proxies of
|
||
your application pods and the egress gateway, use the following command. (You may want to enable mutual TLS to let
|
||
the egress gateway monitor the identity of the source pods and to enable Mixer policy enforcement based on that
|
||
identity.)</p><div id=tabset-blog2018egress-mongo-1 role=tablist class=tabset><div class=tab-strip data-category-name=mtls><button aria-selected=true data-category-value=enabled aria-controls=tabset-blog2018egress-mongo-1-0-panel id=tabset-blog2018egress-mongo-1-0-tab role=tab><span>mutual TLS enabled</span>
|
||
</button><button tabindex=-1 data-category-value=disabled aria-controls=tabset-blog2018egress-mongo-1-1-panel id=tabset-blog2018egress-mongo-1-1-tab role=tab><span>mutual TLS disabled</span></button></div><div class=tab-content><div id=tabset-blog2018egress-mongo-1-0-panel role=tabpanel tabindex=0 aria-labelledby=tabset-blog2018egress-mongo-1-0-tab><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: Gateway
|
||
metadata:
|
||
name: istio-egressgateway
|
||
spec:
|
||
selector:
|
||
istio: egressgateway
|
||
servers:
|
||
- port:
|
||
number: 443
|
||
name: tls
|
||
protocol: TLS
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
tls:
|
||
mode: MUTUAL
|
||
serverCertificate: /etc/certs/cert-chain.pem
|
||
privateKey: /etc/certs/key.pem
|
||
caCertificates: /etc/certs/root-cert.pem
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: egressgateway-for-mongo
|
||
spec:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subsets:
|
||
- name: mongo
|
||
trafficPolicy:
|
||
loadBalancer:
|
||
simple: ROUND_ROBIN
|
||
portLevelSettings:
|
||
- port:
|
||
number: 443
|
||
tls:
|
||
mode: ISTIO_MUTUAL
|
||
sni: $MONGODB_HOST
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: direct-mongo-through-egress-gateway
|
||
spec:
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
gateways:
|
||
- mesh
|
||
- istio-egressgateway
|
||
tls:
|
||
- match:
|
||
- gateways:
|
||
- mesh
|
||
port: $MONGODB_PORT
|
||
sni_hosts:
|
||
- $MONGODB_HOST
|
||
route:
|
||
- destination:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subset: mongo
|
||
port:
|
||
number: 443
|
||
tcp:
|
||
- match:
|
||
- gateways:
|
||
- istio-egressgateway
|
||
port: 443
|
||
route:
|
||
- destination:
|
||
host: $MONGODB_HOST
|
||
port:
|
||
number: $MONGODB_PORT
|
||
weight: 100
|
||
EOF
|
||
</code></pre></div><div hidden id=tabset-blog2018egress-mongo-1-1-panel role=tabpanel tabindex=0 aria-labelledby=tabset-blog2018egress-mongo-1-1-tab><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: Gateway
|
||
metadata:
|
||
name: istio-egressgateway
|
||
spec:
|
||
selector:
|
||
istio: egressgateway
|
||
servers:
|
||
- port:
|
||
number: 443
|
||
name: tls
|
||
protocol: TLS
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
tls:
|
||
mode: PASSTHROUGH
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: egressgateway-for-mongo
|
||
spec:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subsets:
|
||
- name: mongo
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: direct-mongo-through-egress-gateway
|
||
spec:
|
||
hosts:
|
||
- $MONGODB_HOST
|
||
gateways:
|
||
- mesh
|
||
- istio-egressgateway
|
||
tls:
|
||
- match:
|
||
- gateways:
|
||
- mesh
|
||
port: $MONGODB_PORT
|
||
sni_hosts:
|
||
- $MONGODB_HOST
|
||
route:
|
||
- destination:
|
||
host: istio-egressgateway.istio-system.svc.cluster.local
|
||
subset: mongo
|
||
port:
|
||
number: 443
|
||
- match:
|
||
- gateways:
|
||
- istio-egressgateway
|
||
port: 443
|
||
sni_hosts:
|
||
- $MONGODB_HOST
|
||
route:
|
||
- destination:
|
||
host: $MONGODB_HOST
|
||
port:
|
||
number: $MONGODB_PORT
|
||
weight: 100
|
||
EOF
|
||
</code></pre></div></div></div></li><li><p><a href=/v1.21/blog/2018/egress-mongo/#verify-that-egress-traffic-is-directed-through-the-egress-gateway>Verify that the traffic is directed though the egress gateway</a></p></li></ol><h4 id=cleanup-directing-tls-egress-traffic-through-an-egress-gateway>Cleanup directing TLS egress traffic through an egress gateway</h4><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry mongo
|
||
$ kubectl delete gateway istio-egressgateway
|
||
$ kubectl delete virtualservice direct-mongo-through-egress-gateway
|
||
$ kubectl delete destinationrule egressgateway-for-mongo
|
||
</code></pre><h3 id=enable-mongodb-tls-egress-traffic-to-arbitrary-wildcarded-domains>Enable MongoDB TLS egress traffic to arbitrary wildcarded domains</h3><p>Sometimes you want to configure egress traffic to multiple hostnames from the same domain, for example traffic to all
|
||
MongoDB services from <code>*.<your company domain>.com</code>. You do not want to create multiple configuration items, one for
|
||
each and every MongoDB service in your company. To configure access to all the external services from the same domain by
|
||
a single configuration, you use <em>wildcarded</em> hosts.</p><p>In this section you configure egress traffic for a wildcarded domain. I used a MongoDB instance at <code>composedb.com</code>
|
||
domain, so configuring egress traffic for <code>*.com</code> worked for me (I could have used <code>*.composedb.com</code> as well).
|
||
You can pick a wildcarded domain according to your MongoDB host.</p><p>To configure egress gateway traffic for a wildcarded domain, you will first need to deploy a custom egress
|
||
gateway with
|
||
<a href=/v1.21/docs/tasks/traffic-management/egress/wildcard-egress-hosts/#wildcard-configuration-for-arbitrary-domains>an additional SNI proxy</a>.
|
||
This is needed due to current limitations of Envoy, the proxy used by the standard Istio egress gateway.</p><h4 id=prepare-a-new-egress-gateway-with-an-sni-proxy>Prepare a new egress gateway with an SNI proxy</h4><p>In this subsection you deploy an egress gateway with an SNI proxy, in addition to the standard Istio Envoy proxy. You
|
||
can use any SNI proxy that is capable of routing traffic according to arbitrary, not-preconfigured SNI values; we used
|
||
<a href=https://nginx.org>Nginx</a> to achieve this functionality.</p><ol><li><p>Create a configuration file for the Nginx SNI proxy. You may want to edit the file to specify additional Nginx
|
||
settings, if required.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF > ./sni-proxy.conf
|
||
user www-data;
|
||
|
||
events {
|
||
}
|
||
|
||
stream {
|
||
log_format log_stream '\$remote_addr [\$time_local] \$protocol [\$ssl_preread_server_name]'
|
||
'\$status \$bytes_sent \$bytes_received \$session_time';
|
||
|
||
access_log /var/log/nginx/access.log log_stream;
|
||
error_log /var/log/nginx/error.log;
|
||
|
||
# tcp forward proxy by SNI
|
||
server {
|
||
resolver 8.8.8.8 ipv6=off;
|
||
listen 127.0.0.1:$MONGODB_PORT;
|
||
proxy_pass \$ssl_preread_server_name:$MONGODB_PORT;
|
||
ssl_preread on;
|
||
}
|
||
}
|
||
EOF
|
||
</code></pre></li><li><p>Create a Kubernetes <a href=https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/>ConfigMap</a>
|
||
to hold the configuration of the Nginx SNI proxy:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl create configmap egress-sni-proxy-configmap -n istio-system --from-file=nginx.conf=./sni-proxy.conf
|
||
</code></pre></li><li><p>The following command will generate <code>istio-egressgateway-with-sni-proxy.yaml</code> to edit and deploy.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | helm template install/kubernetes/helm/istio/ --name istio-egressgateway-with-sni-proxy --namespace istio-system -x charts/gateways/templates/deployment.yaml -x charts/gateways/templates/service.yaml -x charts/gateways/templates/serviceaccount.yaml -x charts/gateways/templates/autoscale.yaml -x charts/gateways/templates/role.yaml -x charts/gateways/templates/rolebindings.yaml --set global.mtls.enabled=true --set global.istioNamespace=istio-system -f - > ./istio-egressgateway-with-sni-proxy.yaml
|
||
gateways:
|
||
enabled: true
|
||
istio-ingressgateway:
|
||
enabled: false
|
||
istio-egressgateway:
|
||
enabled: false
|
||
istio-egressgateway-with-sni-proxy:
|
||
enabled: true
|
||
labels:
|
||
app: istio-egressgateway-with-sni-proxy
|
||
istio: egressgateway-with-sni-proxy
|
||
replicaCount: 1
|
||
autoscaleMin: 1
|
||
autoscaleMax: 5
|
||
cpu:
|
||
targetAverageUtilization: 80
|
||
serviceAnnotations: {}
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 443
|
||
name: https
|
||
secretVolumes:
|
||
- name: egressgateway-certs
|
||
secretName: istio-egressgateway-certs
|
||
mountPath: /etc/istio/egressgateway-certs
|
||
- name: egressgateway-ca-certs
|
||
secretName: istio-egressgateway-ca-certs
|
||
mountPath: /etc/istio/egressgateway-ca-certs
|
||
configVolumes:
|
||
- name: sni-proxy-config
|
||
configMapName: egress-sni-proxy-configmap
|
||
additionalContainers:
|
||
- name: sni-proxy
|
||
image: nginx
|
||
volumeMounts:
|
||
- name: sni-proxy-config
|
||
mountPath: /etc/nginx
|
||
readOnly: true
|
||
EOF
|
||
</code></pre></li><li><p>Deploy the new egress gateway:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f ./istio-egressgateway-with-sni-proxy.yaml
|
||
serviceaccount "istio-egressgateway-with-sni-proxy-service-account" created
|
||
role "istio-egressgateway-with-sni-proxy-istio-system" created
|
||
rolebinding "istio-egressgateway-with-sni-proxy-istio-system" created
|
||
service "istio-egressgateway-with-sni-proxy" created
|
||
deployment "istio-egressgateway-with-sni-proxy" created
|
||
horizontalpodautoscaler "istio-egressgateway-with-sni-proxy" created
|
||
</code></pre></li><li><p>Verify that the new egress gateway is running. Note that the pod has two containers (one is the Envoy proxy and the
|
||
second one is the SNI proxy).</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get pod -l istio=egressgateway-with-sni-proxy -n istio-system
|
||
NAME READY STATUS RESTARTS AGE
|
||
istio-egressgateway-with-sni-proxy-79f6744569-pf9t2 2/2 Running 0 17s
|
||
</code></pre></li><li><p>Create a service entry with a static address equal to 127.0.0.1 (<code>localhost</code>), and disable mutual TLS on the traffic directed to the new
|
||
service entry:</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: sni-proxy
|
||
spec:
|
||
hosts:
|
||
- sni-proxy.local
|
||
location: MESH_EXTERNAL
|
||
ports:
|
||
- number: $MONGODB_PORT
|
||
name: tcp
|
||
protocol: TCP
|
||
resolution: STATIC
|
||
endpoints:
|
||
- address: 127.0.0.1
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: disable-mtls-for-sni-proxy
|
||
spec:
|
||
host: sni-proxy.local
|
||
trafficPolicy:
|
||
tls:
|
||
mode: DISABLE
|
||
EOF
|
||
</code></pre></li></ol><h4 id=configure-access-to-com-using-the-new-egress-gateway>Configure access to <code>*.com</code> using the new egress gateway</h4><ol><li><p>Define a <code>ServiceEntry</code> for <code>*.com</code>:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | kubectl create -f -
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: ServiceEntry
|
||
metadata:
|
||
name: mongo
|
||
spec:
|
||
hosts:
|
||
- "*.com"
|
||
ports:
|
||
- number: 443
|
||
name: tls
|
||
protocol: TLS
|
||
- number: $MONGODB_PORT
|
||
name: tls-mongodb
|
||
protocol: TLS
|
||
location: MESH_EXTERNAL
|
||
EOF
|
||
</code></pre></li><li><p>Create an egress <code>Gateway</code> for <em>*.com</em>, port 443, protocol TLS, a destination rule to set the
|
||
<a href=https://en.wikipedia.org/wiki/Server_Name_Indication>SNI</a> for the gateway, and Envoy filters to prevent tampering
|
||
with SNI by a malicious application (the filters verify that the SNI issued by the application is the SNI reported
|
||
to Mixer).</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: Gateway
|
||
metadata:
|
||
name: istio-egressgateway-with-sni-proxy
|
||
spec:
|
||
selector:
|
||
istio: egressgateway-with-sni-proxy
|
||
servers:
|
||
- port:
|
||
number: 443
|
||
name: tls
|
||
protocol: TLS
|
||
hosts:
|
||
- "*.com"
|
||
tls:
|
||
mode: MUTUAL
|
||
serverCertificate: /etc/certs/cert-chain.pem
|
||
privateKey: /etc/certs/key.pem
|
||
caCertificates: /etc/certs/root-cert.pem
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: mtls-for-egress-gateway
|
||
spec:
|
||
host: istio-egressgateway-with-sni-proxy.istio-system.svc.cluster.local
|
||
subsets:
|
||
- name: mongo
|
||
trafficPolicy:
|
||
loadBalancer:
|
||
simple: ROUND_ROBIN
|
||
portLevelSettings:
|
||
- port:
|
||
number: 443
|
||
tls:
|
||
mode: ISTIO_MUTUAL
|
||
---
|
||
# The following filter is used to forward the original SNI (sent by the application) as the SNI of the mutual TLS
|
||
# connection.
|
||
# The forwarded SNI will be reported to Mixer so that policies will be enforced based on the original SNI value.
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: EnvoyFilter
|
||
metadata:
|
||
name: forward-downstream-sni
|
||
spec:
|
||
filters:
|
||
- listenerMatch:
|
||
portNumber: $MONGODB_PORT
|
||
listenerType: SIDECAR_OUTBOUND
|
||
filterName: forward_downstream_sni
|
||
filterType: NETWORK
|
||
filterConfig: {}
|
||
---
|
||
# The following filter verifies that the SNI of the mutual TLS connection (the SNI reported to Mixer) is
|
||
# identical to the original SNI issued by the application (the SNI used for routing by the SNI proxy).
|
||
# The filter prevents Mixer from being deceived by a malicious application: routing to one SNI while
|
||
# reporting some other value of SNI. If the original SNI does not match the SNI of the mutual TLS connection, the
|
||
# filter will block the connection to the external service.
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: EnvoyFilter
|
||
metadata:
|
||
name: egress-gateway-sni-verifier
|
||
spec:
|
||
workloadLabels:
|
||
app: istio-egressgateway-with-sni-proxy
|
||
filters:
|
||
- listenerMatch:
|
||
portNumber: 443
|
||
listenerType: GATEWAY
|
||
filterName: sni_verifier
|
||
filterType: NETWORK
|
||
filterConfig: {}
|
||
EOF
|
||
</code></pre></li><li><p>Route the traffic destined for <em>*.com</em> to the egress gateway and from the egress gateway to the SNI proxy.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: direct-mongo-through-egress-gateway
|
||
spec:
|
||
hosts:
|
||
- "*.com"
|
||
gateways:
|
||
- mesh
|
||
- istio-egressgateway-with-sni-proxy
|
||
tls:
|
||
- match:
|
||
- gateways:
|
||
- mesh
|
||
port: $MONGODB_PORT
|
||
sni_hosts:
|
||
- "*.com"
|
||
route:
|
||
- destination:
|
||
host: istio-egressgateway-with-sni-proxy.istio-system.svc.cluster.local
|
||
subset: mongo
|
||
port:
|
||
number: 443
|
||
weight: 100
|
||
tcp:
|
||
- match:
|
||
- gateways:
|
||
- istio-egressgateway-with-sni-proxy
|
||
port: 443
|
||
route:
|
||
- destination:
|
||
host: sni-proxy.local
|
||
port:
|
||
number: $MONGODB_PORT
|
||
weight: 100
|
||
EOF
|
||
</code></pre></li><li><p>Refresh the web page of the application again and verify that the ratings are still displayed correctly.</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 the egress gateway’s Envoy proxy. If Istio is deployed in the <code>istio-system</code> namespace, the command
|
||
to print the log is:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl logs -l istio=egressgateway-with-sni-proxy -c istio-proxy -n istio-system
|
||
</code></pre><p>You should see lines similar to the following:</p><pre><code class=language-plain data-expandlinks=true data-repo=istio>[2019-01-02T17:22:04.602Z] "- - -" 0 - 768 1863 88 - "-" "-" "-" "-" "127.0.0.1:28543" outbound|28543||sni-proxy.local 127.0.0.1:49976 172.30.146.115:443 172.30.146.118:58510 <your MongoDB host>
|
||
[2019-01-02T17:22:04.713Z] "- - -" 0 - 1534 2590 85 - "-" "-" "-" "-" "127.0.0.1:28543" outbound|28543||sni-proxy.local 127.0.0.1:49988 172.30.146.115:443 172.30.146.118:58522 <your MongoDB host>
|
||
</code></pre></li><li><p>Check the logs of the SNI proxy. If Istio is deployed in the <code>istio-system</code> namespace, the command to print the
|
||
log is:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl logs -l istio=egressgateway-with-sni-proxy -n istio-system -c sni-proxy
|
||
127.0.0.1 [23/Aug/2018:03:28:18 +0000] TCP [<your MongoDB host>]200 1863 482 0.089
|
||
127.0.0.1 [23/Aug/2018:03:28:18 +0000] TCP [<your MongoDB host>]200 2590 1248 0.095
|
||
</code></pre></li></ol><h4 id=understanding-what-happened>Understanding what happened</h4><p>In this section you configured egress traffic to your MongoDB host using a wildcarded domain. While for a single MongoDB
|
||
host there is no gain in using wildcarded domains (an exact hostname can be specified), it could be beneficial for
|
||
cases when the applications in the cluster access multiple MongoDB hosts that match some wildcarded domain. For example,
|
||
if the applications access <code>mongodb1.composedb.com</code>, <code>mongodb2.composedb.com</code> and <code>mongodb3.composedb.com</code>, the egress
|
||
traffic can be configured by a single configuration for the wildcarded domain <code>*.composedb.com</code>.</p><p>I will leave it as an exercise for the reader to verify that no additional Istio configuration is required when you
|
||
configure an app to use another instance of MongoDB with a hostname that matches the wildcarded domain used in this
|
||
section.</p><h4 id=cleanup-of-configuration-for-mongodb-tls-egress-traffic-to-arbitrary-wildcarded-domains>Cleanup of configuration for MongoDB TLS egress traffic to arbitrary wildcarded domains</h4><ol><li><p>Delete the configuration items for <em>*.com</em>:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry mongo
|
||
$ kubectl delete gateway istio-egressgateway-with-sni-proxy
|
||
$ kubectl delete virtualservice direct-mongo-through-egress-gateway
|
||
$ kubectl delete destinationrule mtls-for-egress-gateway
|
||
$ kubectl delete envoyfilter forward-downstream-sni egress-gateway-sni-verifier
|
||
</code></pre></li><li><p>Delete the configuration items for the <code>egressgateway-with-sni-proxy</code> deployment:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry sni-proxy
|
||
$ kubectl delete destinationrule disable-mtls-for-sni-proxy
|
||
$ kubectl delete -f ./istio-egressgateway-with-sni-proxy.yaml
|
||
$ kubectl delete configmap egress-sni-proxy-configmap -n istio-system
|
||
</code></pre></li><li><p>Remove the configuration files you created:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ rm ./istio-egressgateway-with-sni-proxy.yaml
|
||
$ rm ./nginx-sni-proxy.conf
|
||
</code></pre></li></ol><h2 id=cleanup>Cleanup</h2><ol><li><p>Drop the <code>bookinfo</code> user:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
|
||
use test
|
||
db.dropUser("bookinfo");
|
||
EOF
|
||
</code></pre></li><li><p>Drop the <em>ratings</em> collection:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ cat <<EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
|
||
use test
|
||
db.ratings.drop();
|
||
EOF
|
||
</code></pre></li><li><p>Unset the environment variables you used:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ unset MONGO_ADMIN_PASSWORD BOOKINFO_PASSWORD MONGODB_HOST MONGODB_PORT MONGODB_IP
|
||
</code></pre></li><li><p>Remove the virtual services:</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-ratings-db.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete -f @samples/bookinfo/networking/virtual-service-ratings-db.yaml@
|
||
Deleted config: virtual-service/default/reviews
|
||
Deleted config: virtual-service/default/ratings
|
||
</code></pre></div></li><li><p>Undeploy <em>ratings v2-mongodb</em>:</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml@
|
||
deployment "ratings-v2" deleted
|
||
</code></pre></div></li></ol><h2 id=conclusion>Conclusion</h2><p>In this blog post I demonstrated various options for MongoDB egress traffic control. You can control the MongoDB egress
|
||
traffic on a TCP or TLS level where applicable. In both TCP and TLS cases, you can direct the traffic from the sidecar
|
||
proxies directly to the external MongoDB host, or direct the traffic through an egress gateway, according to your
|
||
organization’s security requirements. In the latter case, you can also decide to apply or disable mutual TLS
|
||
authentication between the sidecar proxies and the egress gateway. If you want to control MongoDB egress traffic on the
|
||
TLS level by specifying wildcarded domains like <code>*.com</code> and you need to direct the traffic through the egress gateway,
|
||
you must deploy a custom egress gateway with an SNI proxy.</p><p>Note that the configuration and considerations described in this blog post for MongoDB are rather the same for other
|
||
non-HTTP protocols on top of TCP/TLS.</p></div><nav class=pagenav><div class=left><a title="How to use Istio for traffic management without deploying sidecar proxies." href=/v1.21/blog/2018/incremental-traffic-management/ class=next-link><svg class="icon left-arrow"><use xlink:href="/v1.21/img/icons.svg#left-arrow"/></svg>Incremental Istio Part 1, Traffic Management</a></div><div class=right><a title="Istio hosting an all day Twitch stream to celebrate the 1.0 release." href=/v1.21/blog/2018/istio-twitch-stream/ class=next-link>All Day Istio Twitch Stream<svg class="icon right-arrow"><use xlink:href="/v1.21/img/icons.svg#right-arrow"/></svg></a></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-mongo/"),!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-mongo/"),!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><script src=https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js defer></script><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> |