mirror of https://github.com/istio/istio.io.git
98 lines
40 KiB
HTML
98 lines
40 KiB
HTML
<!doctype html><html lang=zh 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="使用外部 TCP 服务"><meta name=description content="描述基于 Istio 的 Bookinfo 示例的简单场景。"><meta name=author content="Vadim Eisenberg"><meta name=keywords content="microservices,services,mesh,traffic-management,egress,tcp"><meta property="og:title" content="使用外部 TCP 服务"><meta property="og:type" content="website"><meta property="og:description" content="描述基于 Istio 的 Bookinfo 示例的简单场景。"><meta property="og:url" content="/v1.10/zh/blog/2018/egress-tcp/"><meta property="og:image" content="https://raw.githubusercontent.com/istio/istio.io/master/static/img/istio-whitelogo-bluebackground-framed.svg"><meta property="og:image:alt" content="Istio Logo"><meta property="og:image:width" content="1024"><meta property="og:image:height" content="1024"><meta property="og:site_name" content="Istio"><meta name=twitter:card content="summary"><meta name=twitter:site content="@IstioMesh"><title>Istioldie 1.10 / 使用外部 TCP 服务</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.10/blog/feed.xml><link rel=alternate type=application/rss+xml title="Istio News" href=/v1.10/news/feed.xml><link rel=alternate type=application/rss+xml title="Istio Blog and News" href=/v1.10/feed.xml><link rel="shortcut icon" href=/v1.10/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.10/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.10/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.10/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.10/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.10/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.10/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.10/favicons/android-96x96.png sizes=96xW96><link rel=icon type=image/png href=/v1.10/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.10/favicons/android-192x192.png sizes=192x192><link rel=manifest href=/v1.10/manifest.json><meta name=apple-mobile-web-app-title content="Istio"><meta name=application-name content="Istio"><link rel=stylesheet href=/v1.10/css/all.css><link rel=preconnect href=https://fonts.gstatic.com><link rel=stylesheet href="https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,400;0,500;0,600;0,700;1,600&display=swap"><script src=/v1.10/js/themes_init.min.js></script></head><body class="language-unknown archive-site"><script>const branchName="release-1.10";const docTitle="使用外部 TCP 服务";const iconFile="\/v1.10/img/icons.svg";const buttonCopy='复制到剪切板';const buttonPrint='打印';const buttonDownload='下载';</script><script src="https://www.google.com/cse/brand?form=search-form" defer></script><script src=/v1.10/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.10/zh/><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.371 7.869 7.869.0 013.066-4.178 9.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.10/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.10/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>关于</span><svg class="icon dropdown-arrow"><use xlink:href="/v1.10/img/icons.svg#dropdown-arrow"/></svg></a><ul class=main-navigation-links-dropdown><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/service-mesh class=main-navigation-links-link>服务网格</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/solutions class=main-navigation-links-link>解决方案</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/case-studies class=main-navigation-links-link>案例学习</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/ecosystem class=main-navigation-links-link>生态系统</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/deployment class=main-navigation-links-link>部署</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.10/zh/about/faq class=main-navigation-links-link>FAQ</a></li></ul></li><li class=main-navigation-links-item><a href=/v1.10/zh/blog/ class=main-navigation-links-link><span>博客</span></a></li><li class=main-navigation-links-item><a href=/v1.10/zh/news/ class=main-navigation-links-link><span>新闻</span></a></li><li class=main-navigation-links-item><a href=/v1.10/zh/get-involved/ class=main-navigation-links-link><span>加入我们</span></a></li><li class=main-navigation-links-item><a href=/v1.10/zh/docs/ class=main-navigation-links-link><span>文档</span></a></li></ul><div class=main-navigation-footer><button id=search-show class=search-show title="搜索 istio.io" aria-label=搜索><svg class="icon magnifier"><use xlink:href="/v1.10/img/icons.svg#magnifier"/></svg></button>
|
||
<a href=/v1.10/zh/docs/setup/getting-started class="btn btn--primary" id=try-istio>试用 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=zh>
|
||
<input type=hidden id=search-page-url value=/zh/search>
|
||
<input id=search-textbox class="search-textbox form-control" name=q type=search aria-label="搜索 istio.io" placeholder=搜索>
|
||
<button id=search-close title=取消搜索 type=reset aria-label=取消搜索><svg class="icon menu-close"><use xlink:href="/v1.10/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>使用外部 TCP 服务</h1><p>描述基于 Istio 的 Bookinfo 示例的简单场景。</p></div><p class=post-author>Feb 6, 2018 <span>|</span> By Vadim Eisenberg</p><div><div><aside class="callout tip"><div class=content>这篇博客在 2018 年 7 月 23 日有修改,修改的内容使用了新的 <a href=/v1.10/zh/blog/2018/v1alpha3-routing/>v1alpha3 流量管理 API</a>。如果你想使用旧版本 API,请参考<a href=https://archive.istio.io/v0.7/blog/2018/egress-tcp.html>这个文档</a>。</div></aside></div><p>在我之前的博客文章<a href=/v1.10/zh/blog/2018/egress-https/>使用外部 Web 服务</a>中,我描述了如何通过 HTTPS 在网格 Istio 应用程序中使用外部服务,在这篇文章中,我演示了通过 TCP 使用外部服务。你会用到 <a href=/v1.10/zh/docs/examples/bookinfo/>Istio Bookinfo 示例应用程序</a>,这是将书籍评级数据保存在 MySQL 数据库中的版本。你会在集群外部署此数据库并配置 <em>ratings</em> 服务以使用它,你还会定义<a href=/v1.10/zh/docs/reference/config/networking/service-entry/>服务 Entry</a> 以允许网格内应用程序访问外部数据库。</p><h2 id=Bookinfo-sample-application-with-external-ratings-database>Bookinfo 示例应用程序与外部评级数据库</h2><p>首先,在 Kubernetes 集群之外设置了一个 MySQL 数据库实例来保存 Bookinfo 评级数据,然后修改 <a href=/v1.10/zh/docs/examples/bookinfo/>Bookinfo 示例应用程序</a>以使用这个数据库。</p><h3 id=setting-up-the-database-for-ratings-data>为评级数据设置数据库</h3><p>为此,你设置了 <a href=https://www.mysql.com>MySQL</a> 的实例,你可以使用任何 MySQL 实例; 我使用 <a href=https://www.ibm.com/cloud/compose/mysql>Compose for MySQL</a>,我使用 <code>mysqlsh</code>(<a href=https://dev.mysql.com/doc/mysql-shell/en/>MySQL Shell</a>)作为 MySQL 客户端来提供评级数据。</p><ol><li><p>设置 <code>MYSQL_DB_HOST</code> 和 <code>MYSQL_DB_PORT</code> 环境变量。</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export MYSQL_DB_HOST=<你的 MySQL host>
|
||
$ export MYSQL_DB_PORT=<你的 MySQL port>
|
||
</code></pre><p>如果你使用的是本地数据库,使用的是默认 MYSQL port,那 <code>host</code> 和 <code>port</code> 分别是 <code>localhost</code> 和 <code>3306</code>。</p></li><li><p>初始化数据库时,如果出现提示,执行下面的命令输入密码。这个命令通过 <code>admin</code> 数据库用户凭证来执行。这个 <code>admin</code> 用户是通过 <a href=https://www.ibm.com/cloud/compose/mysql>Compose for Mysql</a> 创建数据库时默认存在的。</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.10/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>或者</strong></em></p><p>使用 <code>mysql</code> 客户端和本地 MySQL 数据库时,运行:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT
|
||
</code></pre></li><li><p>创建一个名为 <code>bookinfo</code> 的用户,并在 <code>test.ratings</code> 表上授予它 <em>SELECT</em> 权限:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>或者</strong></em></p><p>对于 <code>mysql</code> 和本地数据库,命令是:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>在这里,你会应用<a href=https://en.wikipedia.org/wiki/Principle_of_least_privilege>最小特权原则</a>,这意味着不在 Bookinfo 应用程序中使用 <code>admin</code> 用户。相反,你为应用程序 Bookinfo 创建了一个最小权限的特殊用户 <code>bookinfo</code>,在这种情况下,<code>bookinfo</code> 用户只对单个表具有 <code>SELECT</code> 特权。</p><p>在运行命令创建用户之后,你可能会想通过检查最后一个命令的编号并运行 <code>history -d <创建用户的命令编号></code> 来清理我的 bash 历史记录。你可能不希望新用户的密码存储在 bash 历史记录中,如果你使用了 <code>mysql</code> 命令行工具,记得要删除 <code>~/.mysql_history</code> 文件中的最后一个命令。在 <a href=https://dev.mysql.com/doc/refman/5.5/en/create-user.html>MySQL 文档</a>中阅读有关新创建用户的密码保护的更多信息。</p></li><li><p>检查创建的评级,看看一切都按预期工作:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>或者</strong></em></p><p>对于 <code>mysql</code> 和本地数据库:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>暂时将评级设置为<code>1</code>,以便在 Bookinfo <em>ratings</em> 服务使用我们的数据库时提供可视线索:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>或</strong></em></p><p>对于<code>mysql</code>和本地数据库:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>在最后一个命令中使用了 <code>admin</code> 用户(和 <code>root</code> 用于本地数据库),因为 <code>bookinfo</code> 用户在 <code>test.ratings</code> 表上没有 <code>UPDATE</code> 权限。</p></li></ol><p>现在你已经可以去部署使用外部数据库的 Bookinfo 应用程序版本了。</p><h3 id=initial-setting-of-Bookinfo-application>Bookinfo 应用程序的初始设置</h3><p>为了演示使用外部数据库的场景,你首先使用安装了 <a href=/v1.10/zh/docs/setup/getting-started/>Istio</a> 的 Kubernetes 集群,然后部署 <a href=/v1.10/zh/docs/examples/bookinfo/>Istio Bookinfo 示例应用程序</a>、<a href=/v1.10/zh/docs/examples/bookinfo/#apply-default-destination-rules>应用默认的 destination rule</a> 并<a href=/v1.10/zh/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy>将 Istio 默认策略修改为禁止 Egress</a>。</p><p>此应用程序使用 <code>ratings</code> 微服务来获取书籍评级,评分在 1 到 5 之间。评级显示为每个评论的星号,有几个版本的 <code>ratings</code> 微服务。有些人使用 <a href=https://www.mongodb.com>MongoDB</a>,有些使用 <a href=https://www.mysql.com>MySQL</a> 作为他们的数据库。</p><p>这篇博客例子里的命令是以 Istio 0.8 以上版本为基础的,无论启用或不启用<a href=/v1.10/zh/docs/concepts/security/#mutual-TLS-authentication>双向 TLS</a>。</p><p>提醒一下,这是 <a href=/v1.10/zh/docs/examples/bookinfo/>Bookinfo 示例应用程序</a>中应用程序的原始整体架构图。</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.086918235567985%><a data-skipendnotes=true href=/v1.10/zh/docs/examples/bookinfo/withistio.svg title="原始的 Bookinfo 应用程序"><img class=element-to-stretch src=/v1.10/zh/docs/examples/bookinfo/withistio.svg alt="原始的 Bookinfo 应用程序"></a></div><figcaption>原始的 Bookinfo 应用程序</figcaption></figure><h3 id=use-the-database-for-ratings-data-in-Bookinfo-application>将数据库用于 Bookinfo 应用程序中的评级数据</h3><ol><li><p>修改使用 MySQL 数据库的 <em>ratings</em> 服务版本的 <code>deployment spec</code>,以使用你的数据库实例。该 <code>spec</code> 位于 Istio 发行档案的 <a href=https://github.com/istio/istio/blob/release-1.10/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml><code>samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml</code></a> 中。编辑以下几行:</p><pre><code class=language-yaml data-expandlinks=true data-repo=istio>- 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>替换上面代码段中的值,指定数据库主机,端口,用户和密码,请注意,在 Kubernetes 中使用容器环境变量中密码的正确方法是 <a href=https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables>使用 secret</a>,仅对于此示例任务,你可能会在 deployment spec 中直接配置明文的密码,<strong>切记!不要在真实环境中这样做</strong>!我想你们应该也知道,<code>"password"</code> 这个值也不应该用作密码。</p></li><li><p>应用修改后的 <code>spec</code> 来部署使用外部数据库的 <em>ratings</em> 服务,<em>v2-mysql</em> 的版本。</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
|
||
deployment "ratings-v2-mysql" created
|
||
</code></pre></div></li><li><p>将发往 <em>reviews</em> 服务的所有流量路由到 <em>v3</em> 版本,这样做是为了确保 <em>reviews</em> 服务始终调用 <em>ratings</em> 服务,此外,将发往 <em>ratings</em> 服务的所有流量路由到使用外部数据库的 _ratings v2-mysql_。</p><p>通过添加两个<a href=/v1.10/zh/docs/reference/config/networking/virtual-service/>虚拟服务(virtual service)</a>,可以为上述两种服务指定路由。这些虚拟服务在 Istio 发行档案的 <code>samples/bookinfo/networking/virtual-service-ratings-mysql.yaml</code> 中指定。
|
||
<strong><em>注意:</em></strong> 确保你在完成了<a href=/v1.10/zh/docs/examples/bookinfo/#apply-default-destination-rules>添加默认目标路由</a>才执行下面的命令。</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-mysql.yaml@
|
||
</code></pre></div></li></ol><p>更新的架构如下所示,请注意,网格内的蓝色箭头标记根据我们添加的虚拟服务配置的流量,根据虚拟服务的定义,流量将发送到 <em>reviews v3</em> 和 <em>ratings v2-mysql</em> 。</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:59.314858206480224%><a data-skipendnotes=true href=/v1.10/zh/blog/2018/egress-tcp/bookinfo-ratings-v2-mysql-external.svg title="Bookinfo 应用程序,其评级为 v2-mysql,外部为 MySQL 数据库"><img class=element-to-stretch src=/v1.10/zh/blog/2018/egress-tcp/bookinfo-ratings-v2-mysql-external.svg alt="Bookinfo 应用程序,其评级为 v2-mysql,外部为 MySQL 数据库"></a></div><figcaption>Bookinfo 应用程序,其评级为 v2-mysql,外部为 MySQL 数据库</figcaption></figure><p>请注意,MySQL 数据库位于 Istio 服务网格之外,或者更准确地说是在 Kubernetes 集群之外,服务网格的边界由虚线标记。</p><h3 id=access-the-webpage>访问网页</h3><p>在<a href=/v1.10/zh/docs/examples/bookinfo/#determine-the-ingress-IP-and-port>确定入口 IP 和端口</a>之后,访问应用程序的网页。</p><p>你会发现问题,在每次审核下方都会显示消息 <em>“Ratings service is currently unavailable”</em> 而不是评级星标。</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.18705035971223%><a data-skipendnotes=true href=/v1.10/zh/blog/2018/egress-tcp/errorFetchingBookRating.png title="Ratings 服务的错误信息"><img class=element-to-stretch src=/v1.10/zh/blog/2018/egress-tcp/errorFetchingBookRating.png alt="Ratings 服务的错误信息"></a></div><figcaption>Ratings 服务的错误信息</figcaption></figure><p>与<a href=/v1.10/zh/blog/2018/egress-https/>使用外部 Web 服务</a>一样,你会体验到<strong>优雅的服务降级</strong>,这很好,虽然 <em>ratings</em> 服务中有错误,但是应用程序并没有因此而崩溃,应用程序的网页正确显示了书籍信息,详细信息和评论,只是没有评级星。</p><p>你遇到的问题与<a href=/v1.10/zh/blog/2018/egress-https/>使用外部 Web 服务</a>中的问题相同,即 Kubernetes 集群外的所有流量(TCP 和 HTTP)都被 sidecar 代理默认阻止,要为 TCP 启用此类流量,必须定义 TCP 的网格外部服务入口。</p><h3 id=mesh-external-service-entry-for-an-external-MySQL-instance>外部 MySQL 实例的网格外部服务入口</h3><p>“TCP 网格外部服务入口”功能可以解决上面的问题。</p><ol><li><p>获取你的 MySQL 数据库事例的 IP 地址,作为参考,你可以通过 <a href=https://linux.die.net/man/1/host>host</a> 命令实现:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ export MYSQL_DB_IP=$(host $MYSQL_DB_HOST | grep " has address " | cut -d" " -f4)
|
||
</code></pre><p>如果是本地数据库,设置 <code>MYSQL_DB_IP</code> 环境变量为你的本机 IP,保证这个环境变量能被集群访问到。</p></li><li><p>定义一个网格外部服务入口:</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: 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>检查你刚刚新增的服务入口,确保它的值是正确的</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get serviceentry mysql-external -o yaml
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: ServiceEntry
|
||
metadata:
|
||
...
|
||
</code></pre></li></ol><p>请注意,对于 TCP 服务入口,将 <code>tcp</code> 指定为入口 “port” 的 “protocol” 的值,另请注意,要在 “addresses” 列表里面指定外部服务的 IP 地址,作为一个 <code>32</code> 为后缀的 <a href=https://tools.ietf.org/html/rfc2317>CIDR</a> 块。</p><p><a href=#service-entries-for-tcp-traffic>下面</a>我将详细讨论 TCP 服务入口。现在先来验证我们添加的出口规则是否解决了问题。访问网页看看评星是否回来了。</p><p>有效!访问应用程序的网页会显示评级而不会出现错误:</p><figure style=width:80%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:36.69064748201439%><a data-skipendnotes=true href=/v1.10/zh/blog/2018/egress-tcp/externalMySQLRatings.png title="Book Ratings 显示正常"><img class=element-to-stretch src=/v1.10/zh/blog/2018/egress-tcp/externalMySQLRatings.png alt="Book Ratings 显示正常"></a></div><figcaption>Book Ratings 显示正常</figcaption></figure><p>请注意,正如预期的那样,你会看到两个显示评论的一星评级。将评级更改为一颗星,为我们提供了一个视觉线索,确实使用了我们的外部数据库。</p><p>与 HTTP/HTTPS 的服务入口一样,你可以动态地使用 <code>kubectl</code> 删除和创建 TCP 的服务入口。</p><h2 id=motivation-for-egress-TCP-traffic-control>出口 TCP 流量控制的动机</h2><p>一些网内 Istio 应用程序必须访问外部服务,例如遗留系统,在许多情况下,不通过 HTTP 或 HTTPS 协议执行访问,使用其他 TCP 协议,例如 <a href=https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/>MongoDB Wire 协议</a>和 <a href=https://dev.mysql.com/doc/internals/en/client-server-protocol.html>MySQL 客户端/服务器协议</a>等特定于数据库的协议,与外部数据库通信。</p><p>接下来我会再说说 TCP 流量的服务入口。</p><h2 id=service-entries-for-tcp-traffic>TCP 流量的服务入口</h2><p>启用到特定端口的 TCP 流量的服务入口必须指定 <code>TCP</code> 作为端口的协议,此外,对于 <a href=https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/>MongoDB Wire 协议</a>,协议可以指定为 <code>MONGO</code>,而不是 <code>TCP</code>。</p><p>对于服务入口配置的 <code>addresses</code> 字段,必须使用 <a href=https://tools.ietf.org/html/rfc2317>CIDR</a> 表示法中的 IP 块。注意在 TCP 服务入口配置中,<code>host</code> 字段会被忽略。</p><p>要通过其主机名启用到外部服务的 TCP 流量,必须指定主机名的所有 IP,每个 IP 必须由 CIDR 块指定。</p><p>请注意,外部服务的所有 IP 并不总是已知。要往外发送 TCP 流量,只能配置为被应用程序使用的 IP。</p><p>另请注意,外部服务的 IP 并不总是静态的,例如在 <a href=https://en.wikipedia.org/wiki/Content_delivery_network>CDN</a> 的情况下,有时 IP 在大多数情况下是静态的,但可以不时地更改,例如由于基础设施的变化。在这些情况下,如果已知可能 IP 的范围,则应通过 CIDR 块指定范围。如果不知道可能的 IP 的范围,则不能使用 TCP 服务入口,并且<a href=/v1.10/zh/docs/tasks/traffic-management/egress/egress-control/#direct-access-to-external-services>必须直接调用外部服务</a>,绕过 sidecar 代理。</p><h2 id=relation-to-virtual-machines-support>与网格扩展的关系</h2><p>请注意,本文中描述的场景与<a href=/v1.10/zh/docs/examples/virtual-machines/bookinfo/>集成虚拟机</a>示例中描述的网格扩展场景不同。在这种情况下,MySQL 实例在与 Istio 服务网格集成的外部(集群外)机器(裸机或 VM)上运行 ,MySQL 服务成为网格的一等公民,具有 Istio 的所有有益功能,除此之外,服务可以通过本地集群域名寻址,例如通过 <code>mysqldb.vm.svc.cluster.local</code>,并且可以通过<a href=/v1.10/zh/docs/concepts/security/#mutual-TLS-authentication>双向 TLS 身份验证</a>保护与它的通信,无需创建服务入口来访问此服务; 但是,该服务必须在 Istio 注侧,要启用此类集成,必须在计算机上安装 Istio 组件(<em>Envoy proxy</em> ,<em>node-agent</em> ,<code>_istio-agent_</code> ),并且必须可以从中访问 Istio 控制平面(<em>Pilot</em> ,<em>Mixer</em> ,<em>Citadel</em> )。有关详细信息,请参阅 <a href=/v1.10/zh/docs/examples/virtual-machines/>Istio VM 相关</a>。</p><p>在这个的示例中,MySQL 实例可以在任何计算机上运行,也可以由云提供商作为服务进行配置,无需集成机器
|
||
与 Istio ,无需从机器访问 Istio 控制平面,在使用 MySQL 作为服务的情况下,运行 MySQL 的计算机可能无法访问,并且可能无法在其上安装必需的组件。在这个的例子中,MySQL 实例可以通过其全局域名进行寻址,如果消费应用程序希望使用该域名,这可能是有益的,当在消费应用程序的部署配置中无法更改预期的域名时,这尤其重要。</p><h2 id=cleanup>清理</h2><ol><li><p>删除 <code>test</code> 数据库和 <code>bookinfo</code> 用户:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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>或者</strong></em></p><p>对于<code>mysql</code>和本地数据库:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e "drop database test; drop user bookinfo;"
|
||
</code></pre></li><li><p>删除虚拟服务:</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ 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></div></li><li><p>取消部署 <em>ratings v2-mysql</em> :</p><div><a data-skipendnotes=true style=display:none href=https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml>Zip</a><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
|
||
deployment "ratings-v2-mysql" deleted
|
||
</code></pre></div></li><li><p>删除服务入口:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl delete serviceentry mysql-external -n default
|
||
Deleted config: serviceentry mysql-external
|
||
</code></pre></li></ol><h2 id=conclusion>结论</h2><p>在这篇博文中,我演示了 Istio 服务网格中的微服务如何通过 TCP 使用外部服务,默认情况下,Istio 会阻止所有流量(TCP 和 HTTP)到集群外的主机,要为 TCP 启用此类流量,必须为服务网格创建 TCP 网格外部服务入口。</p></div><nav class=pagenav><div class=left><a title=介绍更安全,低风险的部署和发布到生产。 href=/v1.10/zh/blog/2018/traffic-mirroring/ class=next-link><svg class="icon left-arrow"><use xlink:href="/v1.10/img/icons.svg#left-arrow"/></svg>用于在生产环境进行测试的 Istio 流量镜像功能</a></div><div class=right><a title="描述基于 Istio Bookinfo 示例的简单场景。" href=/v1.10/zh/blog/2018/egress-https/ class=next-link>使用外部 Web 服务<svg class="icon right-arrow"><use xlink:href="/v1.10/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="Istio 的代码在 GitHub 上开发" href=https://github.com/istio/community aria-label=GitHub><svg class="icon github"><use xlink:href="/v1.10/img/icons.svg#github"/></svg></a><a class=channel title="如果您想深入了解 Istio 的技术细节,请查看我们日益完善的设计文档" href=https://groups.google.com/forum/#!forum/istio-team-drive-access aria-label="team drive"><svg class="icon drive"><use xlink:href="/v1.10/img/icons.svg#drive"/></svg></a><a class=channel title="在 Slack 上与 Istio 社区交互讨论开发问题(仅限邀请)" href=https://slack.istio.io aria-label=slack><svg class="icon slack"><use xlink:href="/v1.10/img/icons.svg#slack"/></svg></a><a class=channel title="Stack Overflow 中列举了针对实际问题以及部署、配置和使用 Istio 的各项回答" href=https://stackoverflow.com/questions/tagged/istio aria-label="Stack Overflow"><svg class="icon stackoverflow"><use xlink:href="/v1.10/img/icons.svg#stackoverflow"/></svg></a><a class=channel title="关注我们的 Twitter 来获取最新信息" href=https://twitter.com/IstioMesh aria-label=Twitter><svg class="icon twitter"><use xlink:href="/v1.10/img/icons.svg#twitter"/></svg></a></div><hr class=footer-separator role=separator><div class="info footer-info"><a class=logo href=/v1.10/zh/><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.371 7.869 7.869.0 013.066-4.178 9.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 role=menuitem lang=en id=switch-lang-en class=footer-languages-item>English</a>
|
||
<a tabindex=-1 role=menuitem lang=zh id=switch-lang-zh class="footer-languages-item active"><svg class="icon tick"><use xlink:href="/v1.10/img/icons.svg#tick"/></svg>中文</a></div></div><ul class=footer-policies><li class=footer-policies-item><a class=footer-policies-link href=https://policies.google.com/privacy>隐私政策</a> |
|
||
<a class=footer-policies-link href=https://github.com/istio/istio.io/edit/release-1.10/content/zh/blog/2018/egress-tcp/index.md>在 GitHub 上编辑此页</a></li></ul><div class=footer-base><span class=footer-base-copyright>© 2021 Istio Authors.</span>
|
||
<span class=footer-base-version>部分内容可能滞后于英文版本,同步工作正在进行中<br>Version
|
||
Istio 归档
|
||
1.10.3</span><ul class=footer-base-releases><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link role=menuitem onclick="navigateToUrlOrRoot('https://istio.io/blog\/2018\/egress-tcp\/');return false;">当前版本</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link role=menuitem onclick="navigateToUrlOrRoot('https://preliminary.istio.io/blog\/2018\/egress-tcp\/');return false;">下个版本</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link role=menuitem href=https://istio.io/archive>旧版本</a></li></ul></div></div></footer><div id=scroll-to-top-container aria-hidden=true><button id=scroll-to-top title=回到顶部><svg class="icon top"><use xlink:href="/v1.10/img/icons.svg#top"/></svg></button></div></body></html> |