mirror of https://github.com/istio/istio.io.git
175 lines
49 KiB
HTML
175 lines
49 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 TCP 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"><meta property="og:title" content="Consuming External TCP 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.0/blog/2018/egress-tcp/"><meta property="og:image" content="/v1.0/img/istio-logo-blue-background.svg"><meta property="og:image:alt" content="Istio Logo"><meta property="og:image:width" content="112"><meta property="og:image:height" content="150"><meta property="og:site_name" content="Istio"><meta name=twitter:card content="summary"><meta name=twitter:site content="@IstioMesh"><title>Istioldie 1.0 / Consuming External TCP 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><script>var branchName="release-1.0";var docTitle="Consuming External TCP Services";</script><link rel=alternate type=application/rss+xml title="Istio Blog" href=/v1.0/feed.xml><link rel="shortcut icon" href=/v1.0/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.0/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.0/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.0/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.0/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.0/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.0/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.0/favicons/android-96x196.png sizes=96x196><link rel=icon type=image/png href=/v1.0/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.0/favicons/android-192x192.png sizes=192x192><link rel=manifest href=/v1.0/manifest.json><meta name=apple-mobile-web-app-title content="Istio"><meta name=application-name content="Istio"><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Chivo:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic"><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Work Sans:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic"><link rel=stylesheet href=https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css integrity=sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm crossorigin=anonymous><link rel=stylesheet href=https://use.fontawesome.com/releases/v5.0.6/css/all.css><link rel=stylesheet href=/v1.0/css/light_theme_archive.css title=light><link rel="alternate stylesheet" href=/v1.0/css/dark_theme_archive.css title=dark><script src=/v1.0/js/styleSwitcher.min.js></script></head><body class=language-unknown><header><nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark justify-content-between"><a class=navbar-brand href=/v1.0/><span class=logo><svg viewBox="0 0 300 300"><circle cx="150" cy="150" r="150" stroke-width="2" /><polygon points="65,240 225,240 125,270"/><polygon points="65,230 125,220 125,110"/><polygon points="135,220 225,230 135,30"/></svg></span><span class=brand-name>Istioldie 1.0</span></a>
|
|
<button class=navbar-toggler type=button data-toggle=collapse data-target=#navbarCollapse aria-controls=navbarCollapse aria-expanded=false aria-label="Toggle navigation">
|
|
<span class=navbar-toggler-icon></span></button><div class="collapse navbar-collapse justify-content-end" id=navbarCollapse><ul id=navbar-links class="navbar-nav active"><li class=nav-item><a class=nav-link title="Learn how to deploy, use, and operate Istio." href=/v1.0/docs/>Docs</a></li><li class=nav-item><a class="nav-link active" title="Posts about using Istio." href=/v1.0/blog/2019/announcing-1.0.6/>Blog</a></li><li class=nav-item><a class=nav-link title="A bunch of resources to help you deploy, configure and use Istio." href=/v1.0/help/>Help</a></li><li class=nav-item><a class=nav-link title="Get a bit more in-depth info about the Istio project." href=/v1.0/about/>About</a></li><li class="nav-item dropdown" id=gearDropdown style=white-space:nowrap><a title="Options and Settings" href class=nav-link data-toggle=dropdown aria-label=Tools aria-haspopup=true aria-expanded=false><i style=width:1em class="fa fa-lg fa-cog"></i></a><div class="dropdown-menu dropdown-menu-right" aria-labelledby=gearDropdown><a class=dropdown-item id=light-theme-item href onclick="setActiveStyleSheet('light');return false;">Light Theme</a>
|
|
<a class=dropdown-item id=dark-theme-item href onclick="setActiveStyleSheet('dark');return false;">Dark Theme</a><div class=dropdown-divider></div><h6 class=dropdown-header>Other versions of this site</h6><a href=https://istio.io class=dropdown-item>Current Release</a>
|
|
<a href=https://preliminary.istio.io class=dropdown-item>Next Release</a>
|
|
<a href=https://archive.istio.io class=dropdown-item>Older Releases</a></div></li><li class=nav-item><a id=search_show class=nav-link href title="Search istio.io" aria-label=Search><i style=width:1em class="fa fa-lg fa-search"></i></a></li></ul><form name=cse id=search_form class="form-inline mr-sm-2" role=search><input type=hidden name=cx value=013699703217164175118:iwwf17ikgf4>
|
|
<input type=hidden name=ie value=utf-8>
|
|
<input type=hidden name=hl value=en>
|
|
<input type=hidden id=search_page_url value=/v1.0/search.html>
|
|
<input id=search_textbox class=form-control name=q type=text aria-label="Search this site">
|
|
<button id=search_close type=reset aria-label="Cancel Search"><i class="far fa-lg fa-times-circle"></i></button></form></div></nav></header><div class=blog><div class=container-fluid><div class="row row-offcanvas"><div class="col-0 col-md-3 col-xl-2 sidebar-offcanvas"><nav class="sidebar d-print-none"><div class=spacer></div><div class=directory role=tablist><div class=card><div class=card-header role=tab id=header0><a data-toggle=collapse href=#collapse0 title="Blog posts for 2019." role=button aria-controls=collapse0><div><img src=/v1.0/img/blog.svg alt=Icon class=page_icon>
|
|
2019 Posts</div></a></div><div id=collapse0 class=collapse data-parent=#sidebar role=tabpanel aria-labelledby=header0><div class=card-body><ul class=tree><li><a title="Istio 1.0.6 patch release." href=/v1.0/blog/2019/announcing-1.0.6/>Announcing Istio 1.0.6</a></li><li><a title="Addressing application startup ordering and startup latency using AppSwitch." href=/v1.0/blog/2019/appswitch/>Sidestepping Dependency Ordering with AppSwitch</a></li><li><a title="Describes how to deploy a custom ingress gateway using cert-manager manually." href=/v1.0/blog/2019/custom-ingress-gateway/>Deploy a custom ingress gateway using cert-manager</a></li><li><a title="Istio has a new discussion board." href=/v1.0/blog/2019/announcing-discuss.istio.io/>Announcing discuss.istio.io</a></li></ul></div></div></div><div class=card><div class=card-header role=tab id=header1><a data-toggle=collapse href=#collapse1 title="Blog posts for 2018." role=button aria-controls=collapse1><div><img src=/v1.0/img/blog.svg alt=Icon class=page_icon>
|
|
2018 Posts</div></a></div><div id=collapse1 class="collapse show" data-parent=#sidebar role=tabpanel aria-labelledby=header1><div class=card-body><ul class=tree><li><a title="Istio 1.0.5 patch release." href=/v1.0/blog/2018/announcing-1.0.5/>Announcing Istio 1.0.5</a></li><li><a title="How to use Istio for traffic management without deploying sidecar proxies." href=/v1.0/blog/2018/incremental-traffic-management/>Incremental Istio Part 1, Traffic Management</a></li><li><a title="Istio 1.0.4 patch release." href=/v1.0/blog/2018/announcing-1.0.4/>Announcing Istio 1.0.4</a></li><li><a title="Istio 1.0.3 patch release." href=/v1.0/blog/2018/announcing-1.0.3/>Announcing Istio 1.0.3</a></li><li><a title="Istio 1.0.2 patch release." href=/v1.0/blog/2018/announcing-1.0.2/>Announcing Istio 1.0.2</a></li><li><a title="Istio 1.0.1 patch release." href=/v1.0/blog/2018/announcing-1.0.1/>Announcing Istio 1.0.1</a></li><li><a title="Istio hosting an all day Twitch stream to celebrate the 1.0 release." href=/v1.0/blog/2018/istio-twitch-stream/>All Day Istio Twitch Stream</a></li><li><a title="How HP is building its next-generation footwear personalization platform on Istio." href=/v1.0/blog/2018/hp/>Istio a Game Changer for HP's FitStation Platform</a></li><li><a title="Istio is ready for production use with its 1.0 release." href=/v1.0/blog/2018/announcing-1.0/>Announcing Istio 1.0</a></li><li><a title="Automatic application onboarding and latency optimizations using AppSwitch." href=/v1.0/blog/2018/delayering-istio/delayering-istio/>Delayering Istio with AppSwitch</a></li><li><a title="Describe Istio's authorization feature and how to use it in various use cases." href=/v1.0/blog/2018/istio-authorization/>Micro-Segmentation with Istio Authorization</a></li><li><a title="How to export Istio Access Logs to different sinks like BigQuery, GCS, Pub/Sub through Stackdriver." href=/v1.0/blog/2018/export-logs-through-stackdriver/>Exporting Logs to BigQuery, GCS, Pub/Sub through Stackdriver</a></li><li><a title="Introduction, motivation and design principles for the Istio v1alpha3 routing API." href=/v1.0/blog/2018/v1alpha3-routing/>Introducing the Istio v1alpha3 routing API</a></li><li><a title="Describes how to configure Istio ingress with a network load balancer on AWS." href=/v1.0/blog/2018/aws-nlb/>Configuring Istio Ingress with AWS NLB</a></li><li><a title="Using Kubernetes namespaces and RBAC to create an Istio soft multi-tenancy environment." href=/v1.0/blog/2018/soft-multitenancy/>Istio Soft Multi-tenancy Support</a></li><li><a title="An introduction to safer, lower-risk deployments and release to production." href=/v1.0/blog/2018/traffic-mirroring/>Traffic Mirroring with Istio for Testing in Production</a></li><li><span class=current title="Describes a simple scenario based on Istio's Bookinfo example.">Consuming External TCP Services</span></li><li><a title="Describes a simple scenario based on Istio's Bookinfo example." href=/v1.0/blog/2018/egress-https/>Consuming External Web Services</a></li></ul></div></div></div><div class=card><div class=card-header role=tab id=header2><a data-toggle=collapse href=#collapse2 title="Blog posts for 2017." role=button aria-controls=collapse2><div><img src=/v1.0/img/blog.svg alt=Icon class=page_icon>
|
|
2017 Posts</div></a></div><div id=collapse2 class=collapse data-parent=#sidebar role=tabpanel aria-labelledby=header2><div class=card-body><ul class=tree><li><a title="Improving availability and reducing latency." href=/v1.0/blog/2017/mixer-spof-myth/>Mixer and the SPOF Myth</a></li><li><a title="Provides an overview of Mixer's plug-in architecture." href=/v1.0/blog/2017/adapter-model/>Mixer Adapter Model</a></li><li><a title="Istio 0.2 announcement." href=/v1.0/blog/2017/0.2-announcement/>Announcing Istio 0.2</a></li><li><a title="How Kubernetes Network Policy relates to Istio policy." href=/v1.0/blog/2017/0.1-using-network-policy/>Using Network Policy with Istio</a></li><li><a title="Using Istio to create autoscaled canary deployments." href=/v1.0/blog/2017/0.1-canary/>Canary Deployments using Istio</a></li><li><a title="Istio Auth 0.1 announcement." href=/v1.0/blog/2017/0.1-auth/>Using Istio to Improve End-to-End Security</a></li><li><a title="Istio 0.1 announcement." href=/v1.0/blog/2017/0.1-announcement/>Introducing Istio</a></li></ul></div></div></div></div></nav></div><div class="col-12 col-md-9 col-xl-8"><p class=d-md-none><label class=sidebar-toggler data-toggle=offcanvas><i class="fa fa-sign-out-alt"></i></label></p><main aria-labelledby=title><div class=pagenav><p><a href=/v1.0/blog/2018/ title="Blog posts for 2018."><i style=transform:scaleX(-1) class="fa fa-level-up-alt"></i> 2018 Posts</a></p></div><h1 id=title>Consuming External TCP Services</h1><p class=subtitle>Mesh-external Service Entries for TCP traffic</p><p class=byline>By <span class=attribution>Vadim Eisenberg</span>
|
|
/
|
|
<span class=publish_date>February 6, 2018</span></p><nav class="toc-inlined d-xl-none d-print-none"><hr><div class=directory role=directory><nav id=InlinedTableOfContents><ul><li><a href=#bookinfo-sample-application-with-external-ratings-database>Bookinfo sample application with external ratings database</a></li><ul><li><a href=#setting-up-the-database-for-ratings-data>Setting up the database for ratings data</a></li><li><a href=#initial-setting-of-bookinfo-application>Initial setting of Bookinfo application</a></li><li><a href=#use-the-database-for-ratings-data-in-bookinfo-application>Use the database for ratings data in Bookinfo application</a></li><li><a href=#access-the-webpage>Access the webpage</a></li><li><a href=#mesh-external-service-entry-for-an-external-mysql-instance>Mesh-external service entry for an external MySQL instance</a></li></ul><li><a href=#motivation-for-egress-tcp-traffic-control>Motivation for egress TCP traffic control</a></li><li><a href=#service-entries-for-tcp-traffic>Service entries for TCP traffic</a></li><li><a href=#relation-to-mesh-expansion>Relation to mesh expansion</a></li><li><a href=#cleanup>Cleanup</a></li><li><a href=#conclusion>Conclusion</a></li><li><a href=#see-also>See also</a></li></ul></nav></div><hr></nav><blockquote><p>This blog post was updated on July 23, 2018 to use the new
|
|
<a href=/v1.0/blog/2018/v1alpha3-routing/>v1alpha3 traffic management API</a>. If you need to use the old version, follow the docs
|
|
<a href=https://archive.istio.io/v0.7/blog/2018/egress-tcp.html>here</a>.</p></blockquote><p>In my previous blog post, <a href=/v1.0/blog/2018/egress-https/>Consuming External Web Services</a>, I described how external services
|
|
can be consumed by in-mesh Istio applications via HTTPS. In this post, I demonstrate consuming external services
|
|
over TCP. You will use the <a href=/v1.0/docs/examples/bookinfo/>Istio Bookinfo sample application</a>, the version in which the book
|
|
ratings data is persisted in a MySQL database. You deploy this database outside the cluster and configure the
|
|
<em>ratings</em> microservice to use it. You define a
|
|
<a href=/v1.0/docs/reference/config/istio.networking.v1alpha3/#ServiceEntry>Service Entry</a> to allow the in-mesh applications to
|
|
access the external database.</p><h2 id=bookinfo-sample-application-with-external-ratings-database>Bookinfo sample application with external ratings database</h2><p>First, you set up a MySQL database instance to hold book ratings data outside of your Kubernetes cluster. Then you
|
|
modify the <a href=/v1.0/docs/examples/bookinfo/>Bookinfo sample application</a> to use your database.</p><h3 id=setting-up-the-database-for-ratings-data>Setting up the database for ratings data</h3><p>For this task you set up an instance of <a href=https://www.mysql.com>MySQL</a>. You can use any MySQL instance; I used
|
|
<a href=https://www.ibm.com/cloud/compose/mysql>Compose for MySQL</a>. I used <code>mysqlsh</code>
|
|
(<a href=https://dev.mysql.com/doc/mysql-shell/en/>MySQL Shell</a>) as a MySQL client to feed the ratings data.</p><ol><li><p>Set the <code>MYSQL_DB_HOST</code> and <code>MYSQL_DB_PORT</code> environment variables:</p><pre><code class=language-command>$ export MYSQL_DB_HOST=<your MySQL database host>
|
|
$ export MYSQL_DB_PORT=<your MySQL database port></code></pre><p>In case of a local MySQL database with the default port, the values are <code>localhost</code> and <code>3306</code>, respectively.</p></li><li><p>To initialize the database, run the following command entering the password when prompted. The command is
|
|
performed with the credentials of the <code>admin</code> user, created by default by
|
|
<a href=https://www.ibm.com/cloud/compose/mysql>Compose for MySQL</a>.</p><pre><code class=language-command>$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/src/mysql/mysqldb-init.sql | mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT</code></pre><p><em><strong>OR</strong></em></p><p>When using the <code>mysql</code> client and a local MySQL database, run:</p><pre><code class=language-command>$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT</code></pre></li><li><p>Create a user with the name <code>bookinfo</code> and grant it <em>SELECT</em> privilege on the <code>test.ratings</code> table:</p><pre><code class=language-command>$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "CREATE USER 'bookinfo' IDENTIFIED BY '<password you choose>'; GRANT SELECT ON test.ratings to 'bookinfo';"</code></pre><p><em><strong>OR</strong></em></p><p>For <code>mysql</code> and the local database, the command is:</p><pre><code class=language-command>$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "CREATE USER 'bookinfo' IDENTIFIED BY '<password you choose>'; GRANT SELECT ON test.ratings to 'bookinfo';"</code></pre><p>Here you apply the <a href=https://en.wikipedia.org/wiki/Principle_of_least_privilege>principle of least privilege</a>. This
|
|
means that you do not use your <code>admin</code> user in the Bookinfo application. Instead, you create a special user for the
|
|
Bookinfo application , <code>bookinfo</code>, with minimal privileges. In this case, the <em>bookinfo</em> user only has the <code>SELECT</code>
|
|
privilege on a single table.</p><p>After running the command to create the user, you may want to clean your bash history by checking the number of the last
|
|
command and running <code>history -d <the number of the command that created the user></code>. You don't want the password of the
|
|
new user to be stored in the bash history. If you're using <code>mysql</code>, remove the last command from
|
|
<code>~/.mysql_history</code> file as well. Read more about password protection of the newly created user in <a href=https://dev.mysql.com/doc/refman/5.5/en/create-user.html>MySQL documentation</a>.</p></li><li><p>Inspect the created ratings to see that everything worked as expected:</p><pre><code class=language-command>$ mysqlsh --sql --ssl-mode=REQUIRED -u bookinfo -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "select * from test.ratings;"
|
|
Enter password:
|
|
+----------+--------+
|
|
| ReviewID | Rating |
|
|
+----------+--------+
|
|
| 1 | 5 |
|
|
| 2 | 4 |
|
|
+----------+--------+</code></pre><p><em><strong>OR</strong></em></p><p>For <code>mysql</code> and the local database:</p><pre><code class=language-command>$ mysql -u bookinfo -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "select * from test.ratings;"
|
|
Enter password:
|
|
+----------+--------+
|
|
| ReviewID | Rating |
|
|
+----------+--------+
|
|
| 1 | 5 |
|
|
| 2 | 4 |
|
|
+----------+--------+</code></pre></li><li><p>Set the ratings temporarily to <code>1</code> to provide a visual clue when our database is used by the Bookinfo <em>ratings</em>
|
|
service:</p><pre><code class=language-command>$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "update test.ratings set rating=1; select * from test.ratings;"
|
|
Enter password:
|
|
|
|
Rows matched: 2 Changed: 2 Warnings: 0
|
|
+----------+--------+
|
|
| ReviewID | Rating |
|
|
+----------+--------+
|
|
| 1 | 1 |
|
|
| 2 | 1 |
|
|
+----------+--------+</code></pre><p><em><strong>OR</strong></em></p><p>For <code>mysql</code> and the local database:</p><pre><code class=language-command>$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "update test.ratings set rating=1; select * from test.ratings;"
|
|
Enter password:
|
|
+----------+--------+
|
|
| ReviewID | Rating |
|
|
+----------+--------+
|
|
| 1 | 1 |
|
|
| 2 | 1 |
|
|
+----------+--------+</code></pre><p>You used the <code>admin</code> user (and <code>root</code> for the local database) in the last command since the <code>bookinfo</code> user does not
|
|
have the <code>UPDATE</code> privilege on the <code>test.ratings</code> table.</p></li></ol><p>Now you are ready to deploy a version of the Bookinfo application that will use your database.</p><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.0/docs/setup/kubernetes/quick-start/#installation-steps>Istio installed</a>. Then you deploy the
|
|
<a href=/v1.0/docs/examples/bookinfo/>Istio Bookinfo sample application</a> and <a href=/v1.0/docs/examples/bookinfo/#apply-default-destination-rules>apply the default destination rules</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. Some use <a href=https://www.mongodb.com>MongoDB</a>, others use <a href=https://www.mysql.com>MySQL</a>
|
|
as their database.</p><p>The example commands in this blog post work with Istio 0.8+, with or without
|
|
<a href=/v1.0/docs/concepts/security/#mutual-tls-authentication>mutual TLS</a> enabled.</p><p>As a reminder, here is the end-to-end architecture of the application from the
|
|
<a href=/v1.0/docs/examples/bookinfo/>Bookinfo sample application</a>.</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.08%><a class=not-for-endnotes href=/v1.0/docs/examples/bookinfo/withistio.svg><img class=element-to-stretch src=/v1.0/docs/examples/bookinfo/withistio.svg alt="The original Bookinfo application" title="The original Bookinfo application"></a></div><figcaption>The original Bookinfo application</figcaption></figure><h3 id=use-the-database-for-ratings-data-in-bookinfo-application>Use the database for ratings data in Bookinfo application</h3><ol><li><p>Modify the deployment spec of a version of the <em>ratings</em> microservice that uses a MySQL database, to use your
|
|
database instance. The spec is in <a href=https://github.com/istio/istio/blob/release-1.0/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml><code>samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml</code></a>
|
|
of an Istio release archive. Edit the following lines:</p><pre><code class=language-yaml>- name: MYSQL_DB_HOST
|
|
value: mysqldb
|
|
- name: MYSQL_DB_PORT
|
|
value: "3306"
|
|
- name: MYSQL_DB_USER
|
|
value: root
|
|
- name: MYSQL_DB_PASSWORD
|
|
value: password</code></pre><p>Replace the values in the snippet above, specifying the database host, port, user, and password. Note that the
|
|
correct way to work with passwords in container's environment variables in Kubernetes is <a href=https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables>to use secrets</a>. For this
|
|
example task only, you may want to write the password directly in the deployment spec. <strong>Do not do it</strong> in a real
|
|
environment! I also assume everyone realizes that <code>"password"</code> should not be used as a password…</p></li><li><p>Apply the modified spec to deploy the version of the <em>ratings</em> microservice, <em>v2-mysql</em>, that will use your
|
|
database.</p><pre><code class=language-command>$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
|
|
deployment "ratings-v2-mysql" created</code></pre><a hidden style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml></a></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-mysql</em> that uses your database.</p><p>Specify the routing for both services above by adding two
|
|
<a href=/v1.0/docs/reference/config/istio.networking.v1alpha3/#VirtualService>virtual services</a>. These virtual services are
|
|
specified in <code>samples/bookinfo/networking/virtual-service-ratings-mysql.yaml</code> of an Istio release archive.
|
|
<em><strong>Important:</strong></em> make sure you
|
|
<a href=/v1.0/docs/examples/bookinfo/#apply-default-destination-rules>applied the default destination rules</a> before running the
|
|
following command.</p><pre><code class=language-command>$ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-mysql.yaml@</code></pre><a hidden style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml></a></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-mysql</em>.</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.31%><a class=not-for-endnotes href=/v1.0/blog/2018/egress-tcp/./bookinfo-ratings-v2-mysql-external.svg><img class=element-to-stretch src=/v1.0/blog/2018/egress-tcp/./bookinfo-ratings-v2-mysql-external.svg alt="The Bookinfo application with ratings v2-mysql and an external MySQL database" title="The Bookinfo application with ratings v2-mysql and an external MySQL database"></a></div><figcaption>The Bookinfo application with ratings v2-mysql and an external MySQL database</figcaption></figure><p>Note that the MySQL 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.0/docs/examples/bookinfo/#determining-the-ingress-ip-and-port>determining the ingress IP and port</a>.</p><p>You have a problem… 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.19%><a class=not-for-endnotes href=/v1.0/blog/2018/egress-tcp/./errorFetchingBookRating.png><img class=element-to-stretch src=/v1.0/blog/2018/egress-tcp/./errorFetchingBookRating.png alt="The Ratings service error messages" title="The Ratings service error messages"></a></div><figcaption>The Ratings service error messages</figcaption></figure><p>As in <a href=/v1.0/blog/2018/egress-https/>Consuming External Web Services</a>, you experience <strong>graceful service degradation</strong>,
|
|
which is good. The application did not crash due to the error in the <em>ratings</em> microservice. The webpage of the
|
|
application correctly displayed the book information, the details, and the reviews, just without the rating stars.</p><p>You have the same problem as in <a href=/v1.0/blog/2018/egress-https/>Consuming External Web Services</a>, namely all the traffic
|
|
outside the Kubernetes cluster, both TCP and HTTP, is blocked by default by the sidecar proxies. To enable such traffic
|
|
for TCP, a mesh-external service entry for TCP must be defined.</p><h3 id=mesh-external-service-entry-for-an-external-mysql-instance>Mesh-external service entry for an external MySQL instance</h3><p>TCP mesh-external service entries come to our rescue.</p><ol><li><p>Get the IP address of your MySQL 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-command>$ export MYSQL_DB_IP=$(host $MYSQL_DB_HOST | grep " has address " | cut -d" " -f4)</code></pre><p>For a local database, set <code>MYSQL_DB_IP</code> to contain the IP of your machine, accessible from your cluster.</p></li><li><p>Define a TCP mesh-external service entry:</p><pre><code class=language-bash>cat <<EOF | kubectl apply -f -
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: ServiceEntry
|
|
metadata:
|
|
name: mysql-external
|
|
spec:
|
|
hosts:
|
|
- $MYSQL_DB_HOST
|
|
addresses:
|
|
- $MYSQL_DB_IP/32
|
|
ports:
|
|
- name: tcp
|
|
number: $MYSQL_DB_PORT
|
|
protocol: tcp
|
|
location: MESH_EXTERNAL
|
|
EOF</code></pre></li><li><p>Review the service entry you just created and check that it contains the correct values:</p><pre><code class=language-command>$ kubectl get serviceentry mysql-external -o yaml
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: ServiceEntry
|
|
metadata:
|
|
...</code></pre></li></ol><p>Note that for a TCP service entry, you specify <code>tcp</code> as the protocol of a port of the entry. Also note that you have to
|
|
specify the IP of the external service in the list of addresses, as a <a href=https://tools.ietf.org/html/rfc2317>CIDR</a> block
|
|
with suffix <code>32</code>.</p><p>I will talk more about TCP service entries
|
|
<a href=#service-entries-for-tcp-traffic>below</a>. For now, verify that the service entry we added fixed the problem. Access the
|
|
webpage and see if the stars are back.</p><p>It worked! Accessing the web page of the application displays the ratings without error:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.69%><a class=not-for-endnotes href=/v1.0/blog/2018/egress-tcp/./externalMySQLRatings.png><img class=element-to-stretch src=/v1.0/blog/2018/egress-tcp/./externalMySQLRatings.png alt="Book Ratings Displayed Correctly" title="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 changed the ratings to be one star to
|
|
provide us with a visual clue that our external database is indeed being used.</p><p>As with service entries for HTTP/HTTPS, you can delete and create service entries for TCP using <code>kubectl</code>, dynamically.</p><h2 id=motivation-for-egress-tcp-traffic-control>Motivation for egress TCP traffic control</h2><p>Some in-mesh Istio applications must access external services, for example legacy systems. In many cases, the access is
|
|
not performed over HTTP or HTTPS protocols. Other TCP protocols are used, such as database-specific protocols like
|
|
<a href=https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/>MongoDB Wire Protocol</a> and <a href=https://dev.mysql.com/doc/internals/en/client-server-protocol.html>MySQL Client/Server Protocol</a> to communicate with external databases.</p><p>Next let me provide more details about the service entries for TCP traffic.</p><h2 id=service-entries-for-tcp-traffic>Service entries for TCP traffic</h2><p>The service entries for enabling TCP traffic to a specific port must specify <code>TCP</code> as the protocol of the port.
|
|
Additionally, for the <a href=https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/>MongoDB Wire Protocol</a>, the
|
|
protocol can be specified as <code>MONGO</code>, instead of <code>TCP</code>.</p><p>For the <code>addresses</code> field of the entry, a block of IPs in <a href=https://tools.ietf.org/html/rfc2317>CIDR</a>
|
|
notation must be used. Note that the <code>hosts</code> field is ignored for TCP service entries.</p><p>To enable TCP traffic to an external service by its hostname, all the IPs of the hostname must be specified. Each IP
|
|
must be specified by a CIDR block.</p><p>Note that all the IPs of an external service are not always known. To enable egress TCP traffic, only the IPs that are
|
|
used by the applications must be specified.</p><p>Also note that the IPs of an external service are not always static, for example in the case of
|
|
<a href=https://en.wikipedia.org/wiki/Content_delivery_network>CDNs</a>. Sometimes the IPs are static most of the time, but can
|
|
be changed from time to time, for example due to infrastructure changes. In these cases, if the range of the possible
|
|
IPs is known, you should specify the range by CIDR blocks. If the range of the possible IPs is not known, service
|
|
entries for TCP cannot be used and
|
|
<a href=/v1.0/docs/tasks/traffic-management/egress/#calling-external-services-directly>the external services must be called directly</a>,
|
|
bypassing the sidecar proxies.</p><h2 id=relation-to-mesh-expansion>Relation to mesh expansion</h2><p>Note that the scenario described in this post is different from the mesh expansion scenario, described in the
|
|
<a href=/v1.0/docs/examples/integrating-vms/>Integrating Virtual Machines</a> example. In that scenario, a MySQL instance runs on an
|
|
external
|
|
(outside the cluster) machine (a bare metal or a VM), integrated with the Istio service mesh. The MySQL service becomes
|
|
a first-class citizen of the mesh with all the beneficial features of Istio applicable. Among other things, the service
|
|
becomes addressable by a local cluster domain name, for example by <code>mysqldb.vm.svc.cluster.local</code>, and the communication
|
|
to it can be secured by
|
|
<a href=/v1.0/docs/concepts/security/#mutual-tls-authentication>mutual TLS authentication</a>. There is no need to create a service
|
|
entry to access this service; however, the service must be registered with Istio. To enable such integration, Istio
|
|
components (<em>Envoy proxy</em>, <em>node-agent</em>, <em>istio-agent</em>) must be installed on the machine and the Istio control plane
|
|
(<em>Pilot</em>, <em>Mixer</em>, <em>Citadel</em>) must be accessible from it. See the
|
|
<a href=/v1.0/docs/setup/kubernetes/mesh-expansion/>Istio Mesh Expansion</a> instructions for more details.</p><p>In our case, the MySQL instance can run on any machine or can be provisioned as a service by a cloud provider. There is
|
|
no requirement to integrate the machine with Istio. The Istio control plane does not have to be accessible from the
|
|
machine. In the case of MySQL as a service, the machine which MySQL runs on may be not accessible and installing on it
|
|
the required components may be impossible. In our case, the MySQL instance is addressable by its global domain name,
|
|
which could be beneficial if the consuming applications expect to use that domain name. This is especially relevant when
|
|
that expected domain name cannot be changed in the deployment configuration of the consuming applications.</p><h2 id=cleanup>Cleanup</h2><ol><li><p>Drop the <code>test</code> database and the <code>bookinfo</code> user:</p><pre><code class=language-command>$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "drop database test; drop user bookinfo;"</code></pre><p><em><strong>OR</strong></em></p><p>For <code>mysql</code> and the local database:</p><pre><code class=language-command>$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "drop database test; drop user bookinfo;"</code></pre></li><li><p>Remove the virtual services:</p><pre><code class=language-command>$ kubectl delete -f @samples/bookinfo/networking/virtual-service-ratings-mysql.yaml@
|
|
Deleted config: virtual-service/default/reviews
|
|
Deleted config: virtual-service/default/ratings</code></pre><a hidden style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml></a></li><li><p>Undeploy <em>ratings v2-mysql</em>:</p><pre><code class=language-command>$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
|
|
deployment "ratings-v2-mysql" deleted</code></pre><a hidden style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml></a></li><li><p>Delete the service entry:</p><pre><code class=language-command>$ kubectl delete serviceentry mysql-external -n default
|
|
Deleted config: serviceentry mysql-external</code></pre></li></ol><h2 id=conclusion>Conclusion</h2><p>In this blog post, I demonstrated how the microservices in an Istio service mesh can consume external services via TCP.
|
|
By default, Istio blocks all the traffic, TCP and HTTP, to the hosts outside the cluster. To enable such traffic for
|
|
TCP, TCP mesh-external service entries must be created for the service mesh.</p><h2 id=see-also>See also</h2><div class=see-also><div class=container-fluid><div class=row><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/blog/2018/egress-https/>Consuming External Web Services</a></p><p class=desc>Describes a simple scenario based on Istio's Bookinfo example.</p></div><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/docs/examples/advanced-egress/egress-gateway/>Configure an Egress Gateway</a></p><p class=desc>Describes how to configure Istio to direct traffic to external services through a dedicated gateway.</p></div><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/docs/tasks/traffic-management/egress/>Control Egress Traffic</a></p><p class=desc>Describes how to configure Istio to route traffic from services in the mesh to external services.</p></div><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/docs/examples/advanced-egress/egress-tls-origination/>TLS Origination for Egress Traffic</a></p><p class=desc>Describes how to configure Istio to perform TLS origination for traffic to external services.</p></div><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/blog/2019/custom-ingress-gateway/>Deploy a custom ingress gateway using cert-manager</a></p><p class=desc>Describes how to deploy a custom ingress gateway using cert-manager manually.</p></div><div class="col-xs-12 col-sm-6 col-xl-4"><p class=link><a href=/v1.0/blog/2018/incremental-traffic-management/>Incremental Istio Part 1, Traffic Management</a></p><p class=desc>How to use Istio for traffic management without deploying sidecar proxies.</p></div></div></div></div></main><div class="container-fluid d-print-none"><br><div class=row><div class="col-6 pagenav"><p><a title="An introduction to safer, lower-risk deployments and release to production." href=/v1.0/blog/2018/traffic-mirroring/><i class="fa fa-long-arrow-alt-left"></i>Traffic Mirroring with Istio for Testing in Production</a></p></div><div class="col-6 pagenav" style=text-align:right><p><a title="Describes a simple scenario based on Istio's Bookinfo example." href=/v1.0/blog/2018/egress-https/>Consuming External Web Services
|
|
<i class="fa fa-long-arrow-alt-right"></i></a></p></div></div></div><div class="d-none d-print-block" aria-hidden=true><h2>Links</h2><ol id=endnotes></ol></div></div><div class="col-12 col-md-2 d-none d-xl-block d-print-none"><nav class=toc><div class=spacer></div><div id=toc class=directory role=directory><nav id=TableOfContents><ul><li><a href=#bookinfo-sample-application-with-external-ratings-database>Bookinfo sample application with external ratings database</a></li><ul><li><a href=#setting-up-the-database-for-ratings-data>Setting up the database for ratings data</a></li><li><a href=#initial-setting-of-bookinfo-application>Initial setting of Bookinfo application</a></li><li><a href=#use-the-database-for-ratings-data-in-bookinfo-application>Use the database for ratings data in Bookinfo application</a></li><li><a href=#access-the-webpage>Access the webpage</a></li><li><a href=#mesh-external-service-entry-for-an-external-mysql-instance>Mesh-external service entry for an external MySQL instance</a></li></ul><li><a href=#motivation-for-egress-tcp-traffic-control>Motivation for egress TCP traffic control</a></li><li><a href=#service-entries-for-tcp-traffic>Service entries for TCP traffic</a></li><li><a href=#relation-to-mesh-expansion>Relation to mesh expansion</a></li><li><a href=#cleanup>Cleanup</a></li><li><a href=#conclusion>Conclusion</a></li><li><a href=#see-also>See also</a></li></ul></nav></div></nav></div></div></div></div><footer class="d-print-none container-fluid"><div class=row><div class="col-5 col-lg-4" role=navigation><div class=container-fluid><div class=row><div class=icon><span>discuss</span>
|
|
<a title="Join the Istio discussion board to participate in discussions and get help troubleshooting problems" href=https://discuss.istio.io aria-label="Istio discussion board"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M225.9 32C103.3 32 0 130.5.0 252.1.0 256 .1 480 .1 480l225.8-.2c122.7.0 222.1-102.3 222.1-223.9S348.6 32 225.9 32zM224 384c-19.4.0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z" /></svg></a></div><div class=icon><span>slack</span>
|
|
<a title="Interactively discuss issues with the Istio community on Slack" href=https://istio.slack.com aria-label=slack><svg viewBox="0 0 31.444 31.443"><path d="M31.202 16.369c-.62-1.388-2.249-2.011-3.637-1.391l-1.325.594-3.396-7.591 1.325-.592c1.388-.622 2.01-2.25 1.389-3.637-.62-1.389-2.248-2.012-3.637-1.39l-1.324.593-.593-1.326c-.621-1.388-2.249-2.009-3.637-1.388-1.388.62-2.009 2.247-1.389 3.637l.593 1.325L7.98 8.598 7.388 7.273c-.621-1.39-2.249-2.009-3.637-1.39C2.363 6.504 1.742 8.132 2.362 9.52l.592 1.324L1.63 11.438c-1.388.621-2.01 2.247-1.389 3.636.62 1.388 2.249 2.01 3.637 1.39l1.325-.594 3.394 7.592-1.325.592c-1.388.621-2.009 2.25-1.389 3.637.621 1.389 2.249 2.011 3.637 1.391l1.324-.593.593 1.325c.621 1.389 2.249 2.01 3.637 1.389 1.387-.62 2.009-2.248 1.388-3.636l-.591-1.326 7.591-3.394.592 1.321c.621 1.391 2.248 2.013 3.637 1.392 1.388-.619 2.01-2.248 1.389-3.637l-.592-1.324 1.323-.594C31.201 19.384 31.823 17.757 31.202 16.369zM13.623 21.215l-3.395-7.593 7.591-3.394 3.395 7.591L13.623 21.215z"/></svg></a></div><div class=icon><span>twitter</span>
|
|
<a title="Follow us on Twitter to get the latest news" href=https://twitter.com/IstioMesh aria-label=Twitter><svg viewBox="0 0 310 310"><path d="M302.973 57.388c-4.87 2.16-9.877 3.983-14.993 5.463 6.057-6.85 10.675-14.91 13.494-23.73.632-1.977-.023-4.141-1.648-5.434-1.623-1.294-3.878-1.449-5.665-.39-10.865 6.444-22.587 11.075-34.878 13.783-12.381-12.098-29.197-18.983-46.581-18.983-36.695.0-66.549 29.853-66.549 66.547.0 2.89.183 5.764.545 8.598C101.163 99.244 58.83 76.863 29.76 41.204c-1.036-1.271-2.632-1.956-4.266-1.825-1.635.128-3.104 1.05-3.93 2.467-5.896 10.117-9.013 21.688-9.013 33.461.0 16.035 5.725 31.249 15.838 43.137-3.075-1.065-6.059-2.396-8.907-3.977-1.529-.851-3.395-.838-4.914.033-1.52.871-2.473 2.473-2.513 4.224-.007.295-.007.59-.007.889.0 23.935 12.882 45.484 32.577 57.229-1.692-.169-3.383-.414-5.063-.735-1.732-.331-3.513.276-4.681 1.597-1.17 1.32-1.557 3.16-1.018 4.84 7.29 22.76 26.059 39.501 48.749 44.605-18.819 11.787-40.34 17.961-62.932 17.961-4.714.0-9.455-.277-14.095-.826-2.305-.274-4.509 1.087-5.294 3.279-.785 2.193.047 4.638 2.008 5.895 29.023 18.609 62.582 28.445 97.047 28.445 67.754.0 110.139-31.95 133.764-58.753 29.46-33.421 46.356-77.658 46.356-121.367.0-1.826-.028-3.67-.084-5.508 11.623-8.757 21.63-19.355 29.773-31.536 1.237-1.85 1.103-4.295-.33-5.998C307.394 57.037 305.009 56.486 302.973 57.388z"/></svg></a></div><div class=icon><span>stack overflow</span>
|
|
<a 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 viewBox="0 0 120 120"><polygon points="84.4,93.8 84.4,70.6 92.1,70.6 92.1,101.5 22.6,101.5 22.6,70.6 30.3,70.6 30.3,93.8"/><path d="M38.8 68.4l37.8 7.9 1.6-7.6-37.8-7.9L38.8 68.4zM43.8 50.4l35 16.3 3.2-7-35-16.4L43.8 50.4zM53.5 33.2l29.7 24.7 4.9-5.9L58.4 27.3 53.5 33.2zM72.7 14.9l-6.2 4.6 23 31 6.2-4.6-23-31zM38 86h38.6v-7.7H38V86z"/></svg></a></div></div><div class="tag row d-none d-lg-flex">for everyone</div></div></div><div class="col-7 col-lg-4"><p class="text-center copyright" role=contentinfo>Istio
|
|
Archive
|
|
1.0<br>© 2019 Istio Authors, <a href=https://policies.google.com/privacy>Privacy Policy</a><br>Archived on March 19, 2019</p></div><div class="col-6 col-lg-4 d-none d-lg-flex" role=navigation><div class=container-fluid><div class="row justify-content-end"><div class=icon><span>github</span>
|
|
<a title="GitHub is where development takes place on Istio code" href=https://github.com/istio/community aria-label=GitHub><svg viewBox="0 0 478.165 478.165"><path d="M349.22 55.768c6.136 14.046 10.241 37.556 4.224 54.69 24.426 20.999 33.073 71.904 21.079 113.704 35.006 2.73 76.666-1.235 103.642 9.484-25.183-3.248-59.651-9.563-91.987-7.431-6.136.458-15.361-.239-14.903 8.408 37.735 3.008 75.092 6.117 105.894 15.779-30.702-4.981-67.74-12.552-105.894-13.668-15.54 30.921-47.239 46.262-90.991 49.49 4.682 10.261 13.847 14.066 15.879 30.702 3.267 24.406-4.881 60.328 3.208 76.686 4.064 7.89 10.579 8.009 14.863 14.604-10.699 12.871-37.257-1.395-40.186-14.604-5.14-22.852 7.89-58.256-6.415-73.737.996 24.865-5.718 59.85.996 82.145 2.789 8.806 10.659 12.113 8.647 20.063-49.809 5.08-28.989-64.373-37.177-105.356-7.471.697-4.204 11.197-4.224 15.76-.199 40.106 8.189 94.836-34.846 89.556-1.315-8.348 5.838-11.217 8.467-19.007 7.91-22.434-1.454-56.045 2.112-83.161-16.417 12.512 1.793 55.666-8.428 77.961-5.838 12.671-24.785 18.27-39.19 12.651 1.873-9.464 11.695-7.989 15.879-16.875 5.818-12.452.02-30.244 2.092-48.494-30.423 6.097-53.993-.877-65.608-20.023-5.12-8.507-6.356-18.708-12.632-26.219-6.117-7.551-16.098-8.507-19.087-18.808 37.755-9.185 39.17 38.771 73.06 39.807 10.44.418 15.799-2.909 25.402-5.16 2.749-12.113 8.428-21.039 16.875-27.494-42.078-5.658-76.865-18.788-93.023-50.466-38.293 1.893-73.339 7.013-105.894 14.843 29.547-10.679 65.807-14.604 104.778-15.819-2.351-13.807-22.434-10.022-34.866-9.543C47.677 227.17 18.449 230.138.0 233.645c26.817-9.543 64.233-8.348 100.454-8.428-11.038-34.767-7.232-90.014 17.015-110.615-6.854-17.254-4.722-45.346 4.184-58.834 27.036 1.175 43.374 12.891 60.388 24.247 21.019-6.017 43.035-9.045 71.904-7.451 12.133.677 24.705 6.097 33.731 5.32 8.906-.877 18.728-10.898 27.534-14.843C326.507 58.099 336.17 56.206 349.22 55.768z"/></svg></a></div><div class=icon><span>drive</span>
|
|
<a 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 viewBox="0 0 207.027 207.027"><path d="M69.866 15.557.0 138.919l28.732 52.552 143.288-.029 35.008-59.588L136.39 15.735 69.866 15.557zM17.166 139.046 74.268 38.205 91.21 67.783 33.24 168.447 17.166 139.046zM99.841 82.851l23.805 41.558-47.732-.006L99.841 82.851zM163.434 176.443l-117.332.024 21.53-37.065 64.606.008.067.119 52.865-.085L163.434 176.443zM140.932 124.411 90.157 35.767l-2.966-5.178 40.751.121 57.003 93.706L140.932 124.411z"/></svg></a></div><div class=icon><span>working groups</span>
|
|
<a title="If you'd like to contribute to the Istio project, consider participating in our working groups" href=https://github.com/istio/community/blob/master/WORKING-GROUPS.md aria-label="working groups"><svg viewBox="0 -45 439.833 439.833"><polygon points="246.048,195.833 299.966,235.085 319.497,227.296 276.278,195.833"/><polygon points="193.786,195.833 163.556,195.833 120.33,227.3 139.862,235.089"/><path d="M219.927 11.558c-23.854.0-37.057 12.362-36.814 36.182.348 32.623 14.211 52.414 36.814 52.068.0.0 36.802 1.492 36.802-52.068C256.729 23.918 244.294 11.558 219.927 11.558z"/><path d="M285.017 124.567l-36.77-14.659-8.608-7.256c-2.274-1.922-5.636-1.78-7.741.317l-11.973 11.904-12.008-11.907c-2.109-2.094-5.465-2.229-7.736-.313l-8.611 7.256-36.77 14.661c-11.842 4.715-11.83 46.647-12.848 50.497h155.93C296.866 171.228 296.862 129.28 285.017 124.567z"/><path d="M77.976 228.568s36.801 1.492 36.801-52.068c0-23.82-12.434-36.182-36.801-36.182-23.854.0-37.057 12.362-36.814 36.182C41.509 209.124 55.372 228.915 77.976 228.568z"/><path d="M143.065 253.329l-36.77-14.658-8.609-7.256c-2.275-1.923-5.635-1.781-7.742.315l-11.971 11.904-12.008-11.908c-2.109-2.094-5.465-2.229-7.736-.312l-8.611 7.256-36.77 14.66C1.006 258.045 1.018 299.977.0 303.827h155.93C154.915 299.988 154.911 258.042 143.065 253.329z"/><path d="M361.878 228.568s36.801 1.492 36.801-52.068c0-23.82-12.434-36.182-36.801-36.182-23.854.0-37.057 12.362-36.812 36.182C325.411 209.124 339.274 228.915 361.878 228.568z"/><path d="M426.968 253.329l-36.77-14.658-8.609-7.256c-2.273-1.923-5.635-1.781-7.742.315l-11.971 11.904-12.008-11.908c-2.109-2.094-5.465-2.229-7.736-.312l-8.61 7.256-36.771 14.66c-11.842 4.715-11.83 46.646-12.848 50.497h155.93C438.817 299.988 438.812 258.042 426.968 253.329z"/></svg></a></div></div><div class="tag row justify-content-end text-right">for developers</div></div></div></div></footer><div class="d-xl-none d-print-none"><button id=scroll-to-top aria-hidden=true onclick=scrollToTop() title="Back to top"><i class="fa fa-lg fa-arrow-up"></i></button></div><script src=https://code.jquery.com/jquery-3.2.1.slim.min.js integrity=sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN crossorigin=anonymous></script><script src=https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js integrity=sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl crossorigin=anonymous></script><script src=https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js></script><script src="https://www.google.com/cse/brand?form=search_form"></script><script src=/v1.0/js/all.min.js data-manual></script></body></html> |