istio.io/archive/v1.2/zh/blog/2019/data-plane-setup/index.html

210 lines
40 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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="Istio Sidecar 注入过程解密"><meta name=description content="Istio 将数据面组件注入到现存部署之中的过程。"><meta name=author content="Manish Chugtu"><meta name=keywords content=microservices,services,mesh,kubernetes,sidecar-injection,traffic-management><meta property=og:title content="Istio Sidecar 注入过程解密"><meta property=og:type content=website><meta property=og:description content="Istio 将数据面组件注入到现存部署之中的过程。"><meta property=og:url content=/v1.2/zh/blog/2019/data-plane-setup/><meta property=og:image content=/v1.2/img/istio-whitelogo-bluebackground-framed.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><meta name=twitter:creator content=@chugtum><title>Istioldie 1.2 / Istio Sidecar 注入过程解密</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.2/feed.xml><link rel="shortcut icon" href=/v1.2/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.2/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.2/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.2/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.2/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.2/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.2/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.2/favicons/android-96x96.png sizes=96xW96><link rel=icon type=image/png href=/v1.2/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.2/favicons/android-192x192.png sizes=192x192><link rel=manifest href=/v1.2/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=Work+Sans:400|Chivo:400|Work+Sans:500,300,600,300italic,400italic,500italic,600italic|Chivo:500,300,600,300italic,400italic,500italic,600italic"><link rel=stylesheet href=/v1.2/css/all.css><script src=/v1.2/js/themes_init.min.js></script></head><body class="language-unknown archive-site"><script>const branchName="release-1.2";const docTitle="Istio Sidecar 注入过程解密";const iconFile="\/v1.2/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.2/js/all.min.js data-manual defer></script><header><nav><a id=brand href=/v1.2/zh/><span class=logo><svg viewBox="0 0 300 300"><circle cx="150" cy="150" r="146" stroke-width="2" /><path d="M65 240H225L125 270z"/><path d="M65 230l60-10V110z"/><path d="M135 220l90 10L135 30z"/></svg></span><span class=name>Istioldie 1.2</span></a><div id=hamburger><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#hamburger"/></svg></div><div id=header-links><a title="了解如何部署、使用和运维 Istio。" href=/v1.2/zh/docs/>文档</a>
<span title="关于使用 Istio 的博客文章。">博客</span>
<a title=关于Istio的常见问题。 href=/v1.2/zh/faq/>FAQ</a>
<a title=关于Istio的说明。 href=/v1.2/zh/about/>关于</a><div class=menu><button id=gearDropdownButton class=menu-trigger title=选项和设置 aria-label="Options and Settings" aria-controls=gearDropdownContent><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#gear"/></svg></button><div id=gearDropdownContent class=menu-content aria-labelledby=gearDropdownButton role=menu><a tabindex=-1 role=menuitem lang=en id=switch-lang-en>English</a>
<a tabindex=-1 role=menuitem lang=zh id=switch-lang-zh class=active>中文</a><div role=separator></div><a tabindex=-1 role=menuitem class=active id=light-theme-item>亮主题</a>
<a tabindex=-1 role=menuitem id=dark-theme-item>暗主题</a><div role=separator></div><a tabindex=-1 role=menuitem id=syntax-coloring-item>代码高亮</a><div role=separator></div><h6>本站的其它版本</h6><a tabindex=-1 role=menuitem onclick="navigateToUrlOrRoot('https://istio.io/blog\/2019\/data-plane-setup\/');return false;">当前版本</a>
<a tabindex=-1 role=menuitem onclick="navigateToUrlOrRoot('https://preliminary.istio.io/blog\/2019\/data-plane-setup\/');return false;">下个版本</a>
<a tabindex=-1 role=menuitem href=https://archive.istio.io>旧版本</a></div></div><button id=search-show title=搜索istio.io aria-label=Search><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#magnifier"/></svg></button></div><form id=search-form name=cse 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.2/search.html>
<input id=search-textbox class=form-control name=q type=search aria-label=搜索istio.io>
<button id=search-close title="Cancel search" type=reset aria-label="Cancel search"><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#cancel-x"/></svg></button></form></nav></header><main class=primary><div id=sidebar-container class="sidebar-container sidebar-offcanvas"><nav id=sidebar aria-label="Section Navigation"><div class=directory><div class=card><button class="header dynamic" id=card0 title="2019 年的博客文章。" aria-controls=card0-body><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#blog"/></svg>2019 年的博客文章</button><div class="body default" aria-labelledby=card0 role=region id=card0-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card0><li role=none><a role=treeitem title="Istio 1.1.3。" href=/v1.2/zh/blog/2019/announcing-1.1.3/>安全更新:发布 Istio 1.1.3</a></li><li role=none><a role=treeitem title="Istio 1.0.7 的补丁版本。" href=/v1.2/zh/blog/2019/announcing-1.0.7/>安全更新:发布 Istio 1.0.7</a></li><li role=none><a role=treeitem title="Istio 1.1.2 的补丁版本。" href=/v1.2/zh/blog/2019/announcing-1.1.2/>安全更新:发布 Istio 1.1.2</a></li><li role=none><a role=treeitem title="Istio 1.1 发布声明。" href=/v1.2/zh/blog/2019/announcing-1.1/>宣布 Istio 1.1 发布</a></li><li role=none><a role=treeitem title="Istio 1.1 性能概览." href=/v1.2/zh/blog/2019/istio1.1_perf/>面向性能而架构的 Istio 1.1</a></li><li role=none><a role=treeitem title="Istio 1.0.6 补丁版本。" href=/v1.2/zh/blog/2019/announcing-1.0.6/>Istio 1.0.6 发布</a></li><li role=none><a role=treeitem title="在多集群服务网格环境中配置 Istio 的路由规则。" href=/v1.2/zh/blog/2019/multicluster-version-routing/>多集群服务网格中的分版本路由</a></li><li role=none><a role=treeitem title=宣布新的博客策略。 href=/v1.2/zh/blog/2019/sail-the-blog/>博客策略更新</a></li><li role=none><a role=treeitem title="评估加入 Egress gateway 对性能造成的影响。" href=/v1.2/zh/blog/2019/egress-performance/>Egress gateway 性能测试</a></li><li role=none><span role=treeitem class=current title="Istio 将数据面组件注入到现存部署之中的过程。">Istio Sidecar 注入过程解密</span></li><li role=none><a role=treeitem title="使用 AppSwitch 解决应用程序启动顺序和启动延迟。" href=/v1.2/zh/blog/2019/appswitch/>使用 AppSwitch 进行 Sidestepping 依赖性排序</a></li><li role=none><a role=treeitem title="如何使用 cert-manager 手工部署一个自定义 Ingress 网关。" href=/v1.2/zh/blog/2019/custom-ingress-gateway/>使用 Cert-Manager 部署一个自定义 Ingress 网关</a></li><li role=none><a role=treeitem title="Istio 推出新的讨论板。" href=/v1.2/zh/blog/2019/announcing-discuss.istio.io/>宣布 discuss.istio.io</a></li></ul></div></div><div class=card><button class="header dynamic" id=card1 title="2017 年的博客文章。" aria-controls=card1-body><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#blog"/></svg>2017 年的博客文章</button><div class=body aria-labelledby=card1 role=region id=card1-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card1><li role=none><a role=treeitem title=提高可用,降低延迟。 href=/v1.2/zh/blog/2017/mixer-spof-myth/>Mixer 和 SPOF 神话</a></li><li role=none><a role=treeitem title="概要说明 Mixer 的插件架构。" href=/v1.2/zh/blog/2017/adapter-model/>Mixer 适配器模型</a></li><li role=none><a role=treeitem title="Istio 0.2 公告。" href=/v1.2/zh/blog/2017/0.2-announcement/>宣布 Istio 0.2</a></li><li role=none><a role=treeitem title="Istio 的策略如何关联 Kubernetes 的网络策略 。" href=/v1.2/zh/blog/2017/0.1-using-network-policy/>Istio 使用网络策略</a></li><li role=none><a role=treeitem title="使用 Istio 创建自动缩放的金丝雀部署。" href=/v1.2/zh/blog/2017/0.1-canary/>使用 Istio 进行金丝雀部署</a></li><li role=none><a role=treeitem title="Istio Auth 0.1 公告。" href=/v1.2/zh/blog/2017/0.1-auth/>使用 Istio 增强端到端安全</a></li><li role=none><a role=treeitem title="Istio 0.1 宣布。" href=/v1.2/zh/blog/2017/0.1-announcement/>初次了解 Istio</a></li></ul></div></div><div class=card><button class="header dynamic" id=card2 title="2018 年的博客文章。" aria-controls=card2-body><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#blog"/></svg>2018 年的博客文章</button><div class=body aria-labelledby=card2 role=region id=card2-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card2><li role=none><a role=treeitem title="Istio 1.0.5 补丁版本发布。" href=/v1.2/zh/blog/2018/announcing-1.0.5/>Istio 1.0.5 发布</a></li><li role=none><a role=treeitem title="Istio 1.0.4 补丁版本发布。" href=/v1.2/zh/blog/2018/announcing-1.0.4/>Istio 1.0.4 发布</a></li><li role=none><a role=treeitem title="如何在不部署 Sidecar 代理的情况下使用 Istio 进行流量管理。" href=/v1.2/zh/blog/2018/incremental-traffic-management/>增量式应用 Istio 第一部分,流量管理</a></li><li role=none><a role=treeitem title="描述了一个基于 Istio 的 Bookinfo 示例的简单场景。" href=/v1.2/zh/blog/2018/egress-mongo/>使用外部 MongoDB 服务</a></li><li role=none><a role=treeitem title="Istio 1.0.3 修补版本。" href=/v1.2/zh/blog/2018/announcing-1.0.3/>宣布 Istio 1.0.3</a></li><li role=none><a role=treeitem title="Istio 1.0.2 补丁版本." href=/v1.2/zh/blog/2018/announcing-1.0.2/>Istio 1.0.2 发布</a></li><li role=none><a role=treeitem title="Istio 1.0.1 补丁版本。" href=/v1.2/zh/blog/2018/announcing-1.0.1/>Istio 1.0.1 发布</a></li><li role=none><a role=treeitem title="Istio 在 Twitch 举办了为期一天的直播庆祝 1.0 的发布。" href=/v1.2/zh/blog/2018/istio-twitch-stream/>Istio 在 Twitch 上全天直播</a></li><li role=none><a role=treeitem title="惠普如何在 Istio 上构建其下一代鞋类个性化平台。" href=/v1.2/zh/blog/2018/hp/>Istio 是惠普 FitStation 平台的改变者</a></li><li role=none><a role=treeitem title="Istio 1.0 已生产就绪。" href=/v1.2/zh/blog/2018/announcing-1.0/>宣布 Istio 1.0</a></li><li role=none><a role=treeitem title="使用 AppSwitch 自动接入应用并降低延迟。" href=/v1.2/zh/blog/2018/delayering-istio/>使用 AppSwitch 精简 Istio 层次</a></li><li role=none><a role=treeitem title="描述 Istio 的授权功能以及如何在各种用例中使用它。" href=/v1.2/zh/blog/2018/istio-authorization/>基于 Istio 的 Micro-Segmentation 授权</a></li><li role=none><a role=treeitem title="如何通过 Stackdriver 将 Istio 访问日志导出到 BigQuery、GCS、Pub/Sub 等不同的接收器。" href=/v1.2/zh/blog/2018/export-logs-through-stackdriver/>通过 Stackdriver 将日志导出到 BigQuery、GCS、Pub/Sub</a></li><li role=none><a role=treeitem title="描述如何配置 Istio 进行 HTTP Egress 流量监控和访问策略。" href=/v1.2/zh/blog/2018/egress-monitoring-access-control/>HTTP Egress 流量监控和访问策略</a></li><li role=none><a role=treeitem title="Istio v1alpha3 路由 API 介绍,动机及其设计原则。" href=/v1.2/zh/blog/2018/v1alpha3-routing/>Istio v1aplha3 路由 API 介绍</a></li><li role=none><a role=treeitem title="描述如何在AWS上使用网络负载均衡器配置 Istio Ingress。" href=/v1.2/zh/blog/2018/aws-nlb/>使用AWS NLB 配置 Istio Ingress</a></li><li role=none><a role=treeitem title="使用 Kubernetes 命名空间和 RBAC 为 Istio 构建软性多租户环境。" href=/v1.2/zh/blog/2018/soft-multitenancy/>Istio 的软性多租户支持</a></li><li role=none><a role=treeitem title=介绍更安全,低风险的部署和发布到生产。 href=/v1.2/zh/blog/2018/traffic-mirroring/>用于在生产环境进行测试的 Istio 流量镜像功能</a></li><li role=none><a role=treeitem title="描述基于 Istio 的 Bookinfo 示例的简单场景。" href=/v1.2/zh/blog/2018/egress-tcp/>使用外部 TCP 服务</a></li><li role=none><a role=treeitem title="描述基于 Istio Bookinfo 示例的简单场景。" href=/v1.2/zh/blog/2018/egress-https/>使用外部 Web 服务</a></li></ul></div></div></div></nav></div><div class=article-container><button tabindex=-1 id=sidebar-toggler title=折叠导航栏><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#pull"/></svg></button><nav aria-label=Breadcrumb><ol><li><a href=/v1.2/zh/>Istio</a></li><li><a href=/v1.2/zh/blog/ title="关于使用 Istio 的博客文章。">博客</a></li><li><a href=/v1.2/zh/blog/2019/ title="2019 年的博客文章。">2019 年的博客文章</a></li><li>Istio Sidecar 注入过程解密</li></ol></nav><article aria-labelledby=title><div class=title-area><div><h1 id=title>Istio Sidecar 注入过程解密</h1><p class=byline><span>作者</span>
<span class=attribution>Manish Chugtu</span>(<a href=https://twitter.com/chugtum>@chugtum</a>)<span> | </span><span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#calendar"/></svg><span>&nbsp;</span>2019年1月31日</span><span> | </span><span title="835 字"><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#clock"/></svg><span>&nbsp;</span>阅读大约需要 4 分钟</span></p></div></div><nav class=toc-inlined aria-label="Table of Contents"><div><hr><ol><li role=none aria-label="Sidecar 注入"><a href=#sidecar-%e6%b3%a8%e5%85%a5>Sidecar 注入</a><ol><li role=none aria-label=手工注入><a href=#%e6%89%8b%e5%b7%a5%e6%b3%a8%e5%85%a5>手工注入</a><li role=none aria-label=自动注入><a href=#%e8%87%aa%e5%8a%a8%e6%b3%a8%e5%85%a5>自动注入</a></ol></li><li role=none aria-label="从应用容器到 Sidecar 代理的通信"><a href=#%e4%bb%8e%e5%ba%94%e7%94%a8%e5%ae%b9%e5%99%a8%e5%88%b0-sidecar-%e4%bb%a3%e7%90%86%e7%9a%84%e9%80%9a%e4%bf%a1>从应用容器到 Sidecar 代理的通信</a><li role=none aria-label=相关内容><a href=#see-also>相关内容</a></li></ol><hr></div></nav><p>Istio 服务网格架构的概述,通常都是从对数据面和控制面的叙述开始的。</p><p><a href=/v1.2/zh/docs/concepts/what-is-istio/#架构>来自 Istio 的文档:</a></p><div><aside class="callout quote"><div class=type><svg class="large-icon"><use xlink:href="/v1.2/img/icons.svg#callout-quote"/></svg></div><div class=content><p>Istio 服务网格逻辑上分为数据平面和控制平面。</p><p>数据平面由一组以 sidecar 方式部署的智能代理Envoy组成。这些代理和 Mixer一个通用的策略和遥测中心合作对所有微服务之间的之间所有的网络通信进行控制。</p><p>控制平面负责管理和配置代理来路由流量。此外控制平面配置 Mixer 以实施策略和收集遥测数据。</p></div></aside></div><figure style=width:40%><div class=wrapper-with-intrinsic-ratio style=padding-bottom:80%><a data-skipendnotes=true href=/v1.2/blog/2019/data-plane-setup/./arch-2.svg title="Istio 架构"><img class=element-to-stretch src=/v1.2/blog/2019/data-plane-setup/./arch-2.svg alt="基于 Istio 的应用的总体架构。"></a></div><figcaption>Istio 架构</figcaption></figure><p>Sidecar 注入到应用的过程,可以是自动的,也可以是手动的,了解这一过程是很重要的。应用的流量会被重定向进入或流出 Sidecar开发人员无需关心。应用接入 Istio 服务网格之后,开发者可以开始使用网格功能并从中受益。然而数据平面是如何工作的,以及需要怎样的条件才能完成这种无缝工作?本文中我们会深入到 Sidecar 注入模型中,来更清晰的了解 Sidecar 的注入过程。</p><h2 id=sidecar-注入>Sidecar 注入</h2><p>简单来说,注入 Sidecar 就是把附加的容器配置插入 Pod 模板的过程。Istio 服务网格所需的附加容器是:</p><p><code>istio-init</code></p><p>这个<a href=https://kubernetes.io/docs/concepts/workloads/pods/init-containers/>初始化容器</a>用于设置 <code>iptables</code> 规则,让出入流量都转由 Sidecar 进行处理。和应用容器相比,初始化容器有几点不同:</p><ul><li>它在应用容器之前启动,并且会运行到结束。</li><li>如果有多个初始化容器,只有在前一个初始化容器成功结束之后才会启动下一个。</li></ul><p>不看看出,这种容器是非常适合执行启动或者初始化任务的,并且也无需和实际的应用容器集成到一起。<code>istio-init</code> 只是用来设置 <code>iptables</code> 的规则。</p><p><code>istio-proxy</code></p><p>这个容器是真正的 Sidecar基于 Envoy</p><h3 id=手工注入>手工注入</h3><p>要进行手工注入,只要用 <code>istioctl</code> 把前面提到的两个容器定义加入到 Pod 的模板之中即可。不论是手工注入还是自动注入,都是从 <code>istio-sidecar-injector</code> 以及 <code>istio</code> 两个 Configmap 对象中获取配置的。</p><p>我们先来看看 <code>istio-sidecar-injector</code> Configmap了解一下其中的内容。</p><pre><code class=language-bash data-expandlinks=true data-outputis=yaml>$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39;
部分输出内容:
policy: enabled
template: |-
initContainers:
- name: istio-init
image: docker.io/istio/proxy_init:1.0.2
args:
- &#34;-p&#34;
- [[ .MeshConfig.ProxyListenPort ]]
- &#34;-u&#34;
- 1337
.....
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add:
- NET_ADMIN
restartPolicy: Always
containers:
- name: istio-proxy
image: [[ if (isset .ObjectMeta.Annotations &#34;sidecar.istio.io/proxyImage&#34;) -]]
&#34;[[ index .ObjectMeta.Annotations &#34;sidecar.istio.io/proxyImage&#34; ]]&#34;
[[ else -]]
docker.io/istio/proxyv2:1.0.2
[[ end -]]
args:
- proxy
- sidecar
.....
env:
.....
- name: ISTIO_META_INTERCEPTION_MODE
value: [[ or (index .ObjectMeta.Annotations &#34;sidecar.istio.io/interceptionMode&#34;) .ProxyConfig.InterceptionMode.String ]]
imagePullPolicy: IfNotPresent
securityContext:
readOnlyRootFilesystem: true
[[ if eq (or (index .ObjectMeta.Annotations &#34;sidecar.istio.io/interceptionMode&#34;) .ProxyConfig.InterceptionMode.String) &#34;TPROXY&#34; -]]
capabilities:
add:
- NET_ADMIN
restartPolicy: Always
.....
</code></pre><p>如你所见,这个 Configmap 中包含了前面提到的两个容器的配置内容:<code>istio-init</code> 初始化容器以及 <code>istio-proxy</code> 代理容器。配置中包含了容器镜像名称以及一些参数,例如拦截模式,权限要求等。</p><p>从安全角度看来,要注意 <code>istio-init</code> 需要 <code>NET_ADMIN</code> 权限,以便在 Pod 的命名空间中修改 <code>iptables</code>;如果 <code>istio-proxy</code> 设置为 <code>TPROXY</code> 模式,也会需要这一权限。这一权限是限制在 Pod 的命名空间之内的,这应该没问题。然而我注意到最近的 open-shift 版本好像在这方面有点问题,需要进一步确认。这方面的选项会在文末继续讨论。</p><p>要修改当前的 Pod 模板来进行注入,可以:</p><pre><code class=language-bash data-expandlinks=true>$ istioctl kube-inject -f demo-red.yaml | kubectl apply -f -
</code></pre><p>或者</p><p>想要使用修改过的 Configmap 或者本地 Configmap</p><ul><li><p>从 Configmap 中创建 <code>inject-config.yaml</code> and <code>mesh-config.yaml</code></p><pre><code class=language-bash data-expandlinks=true>$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39; &gt; inject-config.yaml
$ kubectl -n istio-system get configmap istio -o=jsonpath=&#39;{.data.mesh}&#39; &gt; mesh-config.yaml
</code></pre></li><li><p>修改现存的 Pod 模板,这里假设文件名为 <code>demo-red.yaml</code></p><pre><code class=language-bash data-expandlinks=true>$ istioctl kube-inject --injectConfigFile inject-config.yaml --meshConfigFile mesh-config.yaml --filename demo-red.yaml --output demo-red-injected.yaml
</code></pre></li><li><p>提交 <code>demo-red-injected.yaml</code></p><pre><code class=language-bash data-expandlinks=true>$ kubectl apply -f demo-red-injected.yaml
</code></pre></li></ul><p>上面的几个步骤中,我们使用 <code>sidecar-injector</code> 以及 <code>istio</code> 两个 Configmap 的内容修改了 Pod 模板并使用 <code>kubectl</code> 命令进行了提交。如果查看一下注入后的 YAML 文件,会看到前面讨论过的 Istio 的专属容器,提交到集群上之后,会看到两个容器在运行:一个是实际的应用容器,另一个则是 <code>istio-proxy</code> Sidecar。</p><pre><code class=language-bash data-expandlinks=true>$ kubectl get pods | grep demo-red
demo-red-pod-8b5df99cc-pgnl7 2/2 Running 0 3d
</code></pre><p>这里没有 3 个 Pod这是因为 <code>istio-init</code> 容器是一个初始化容器,它完成任务之后就会退出——他的任务就是设置 Pod 内的 <code>iptables</code> 规则。要确认退出的初始化容器,可以看看 <code>kubectl describe</code> 的输出:</p><pre><code class=language-bash data-expandlinks=true data-outputis=yaml>$ kubectl describe pod demo-red-pod-8b5df99cc-pgnl7
SNIPPET from the output:
Name: demo-red-pod-8b5df99cc-pgnl7
Namespace: default
.....
Labels: app=demo-red
pod-template-hash=8b5df99cc
version=version-red
Annotations: sidecar.istio.io/status={&#34;version&#34;:&#34;3c0b8d11844e85232bc77ad85365487638ee3134c91edda28def191c086dc23e&#34;,&#34;initContainers&#34;:[&#34;istio-init&#34;],&#34;containers&#34;:[&#34;istio-proxy&#34;],&#34;volumes&#34;:[&#34;istio-envoy&#34;,&#34;istio-certs...
Status: Running
IP: 10.32.0.6
Controlled By: ReplicaSet/demo-red-pod-8b5df99cc
Init Containers:
istio-init:
Container ID: docker://bef731eae1eb3b6c9d926cacb497bb39a7d9796db49cd14a63014fc1a177d95b
Image: docker.io/istio/proxy_init:1.0.2
Image ID: docker-pullable://docker.io/istio/proxy_init@sha256:e16a0746f46cd45a9f63c27b9e09daff5432e33a2d80c8cc0956d7d63e2f9185
.....
State: Terminated
Reason: Completed
.....
Ready: True
Containers:
demo-red:
Container ID: docker://8cd9957955ff7e534376eb6f28b56462099af6dfb8b9bc37aaf06e516175495e
Image: chugtum/blue-green-image:v3
Image ID: docker-pullable://docker.io/chugtum/blue-green-image@sha256:274756dbc215a6b2bd089c10de24fcece296f4c940067ac1a9b4aea67cf815db
State: Running
Started: Sun, 09 Dec 2018 18:12:31 -0800
Ready: True
istio-proxy:
Container ID: docker://ca5d690be8cd6557419cc19ec4e76163c14aed2336eaad7ebf17dd46ca188b4a
Image: docker.io/istio/proxyv2:1.0.2
Image ID: docker-pullable://docker.io/istio/proxyv2@sha256:54e206530ba6ca9b3820254454e01b7592e9f986d27a5640b6c03704b3b68332
Args:
proxy
sidecar
.....
State: Running
Started: Sun, 09 Dec 2018 18:12:31 -0800
Ready: True
.....
</code></pre><p>从上文的输出可以看出,<code>istio-init</code> 容器的 <code>State</code> 字段值为 <code>Terminated</code><code>Reason</code><code>Completed</code>。正在运行的两个 Pod 是应用容器 <code>demo-red</code> 以及 <code>istio-proxy</code></p><h3 id=自动注入>自动注入</h3><p>多数时候,用户不想在每次部署应用的时候都用 <code>istioctl</code> 命令进行手工注入,这时候就可以使用 Istio 的自动注入功能来应对了。只要给用于部署应用的命名空间打个 <code>istio-injection=enabled</code> 标签就可以了。</p><p>打上标签之后,这个命名空间中新建的任何 Pod 都会被 Istio 注入 Sidecar。下面的例子里<code>istio-dev</code> 命名空间中部署的 Pod 被自动注入了 Sidecar</p><pre><code class=language-bash data-expandlinks=true>$ kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 40d &lt;none&gt;
istio-dev Active 19d istio-injection=enabled
istio-system Active 24d &lt;none&gt;
kube-public Active 40d &lt;none&gt;
kube-system Active 40d &lt;none&gt;
</code></pre><p>这是怎么完成的呢?要回答这一问题,首先要了解一下 Kubernetes 的准入控制器。</p><p><a href=https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/>来自 Kubernetes 文档</a></p><div><aside class="callout tip"><div class=type><svg class="large-icon"><use xlink:href="/v1.2/img/icons.svg#callout-tip"/></svg></div><div class=content>准入控制器是一段代码,会拦截 Kubernetes API Server 收到的请求,拦截发生在认证和鉴权完成之后,对象进行持久化之前。可以定义两种类型的 Admission webhookValidating 和 Mutating。Validating 类型的 Webhook 可以根据自定义的准入策略决定是否拒绝请求Mutating 类型的 Webhook 可以根据自定义配置来对请求进行编辑。</div></aside></div><p>Istio 的自动注入过程中会依赖 Mutating webhook。我们看看 <code>istio-sidecar-injector</code> 中的配置详情:</p><pre><code class=language-bash data-expandlinks=true data-outputis=yaml>$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml
输出内容节选:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{&#34;apiVersion&#34;:&#34;admissionregistration.k8s.io/v1beta1&#34;,&#34;kind&#34;:&#34;MutatingWebhookConfiguration&#34;,&#34;metadata&#34;:{&#34;annotations&#34;:{},&#34;labels&#34;:{&#34;app&#34;:&#34;istio-sidecar-injector&#34;,&#34;chart&#34;:&#34;sidecarInjectorWebhook-1.0.1&#34;,&#34;heritage&#34;:&#34;Tiller&#34;,&#34;release&#34;:&#34;istio-remote&#34;},&#34;name&#34;:&#34;istio-sidecar-injector&#34;,&#34;namespace&#34;:&#34;&#34;},&#34;webhooks&#34;:[{&#34;clientConfig&#34;:{&#34;caBundle&#34;:&#34;&#34;,&#34;service&#34;:{&#34;name&#34;:&#34;istio-sidecar-injector&#34;,&#34;namespace&#34;:&#34;istio-system&#34;,&#34;path&#34;:&#34;/inject&#34;}},&#34;failurePolicy&#34;:&#34;Fail&#34;,&#34;name&#34;:&#34;sidecar-injector.istio.io&#34;,&#34;namespaceSelector&#34;:{&#34;matchLabels&#34;:{&#34;istio-injection&#34;:&#34;enabled&#34;}},&#34;rules&#34;:[{&#34;apiGroups&#34;:[&#34;&#34;],&#34;apiVersions&#34;:[&#34;v1&#34;],&#34;operations&#34;:[&#34;CREATE&#34;],&#34;resources&#34;:[&#34;pods&#34;]}]}]}
creationTimestamp: 2018-12-10T08:40:15Z
generation: 2
labels:
app: istio-sidecar-injector
chart: sidecarInjectorWebhook-1.0.1
heritage: Tiller
release: istio-remote
name: istio-sidecar-injector
.....
webhooks:
- clientConfig:
service:
name: istio-sidecar-injector
namespace: istio-system
path: /inject
name: sidecar-injector.istio.io
namespaceSelector:
matchLabels:
istio-injection: enabled
rules:
- apiGroups:
- &#34;&#34;
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
</code></pre><p>这里可以看到一个 <code>namespaceSelector</code>,其中的定义表明它的工作是针对带有 <code>istio-injection: enabled</code> 标签的命名空间的。这种情况下,你还会看到 Pod 创建期间进行注入时的一些其它工作和相关资源的内容。当 <code>apiserver</code> 收到一个符合规则的请求时,<code>apiserver</code> 会给 Webhook 服务发送一个准入审核的请求Webhook 服务的定义包含在 <code>clientConfig</code> 配置中的 <code>name: istio-sidecar-injector</code> 字段里。我们会看到,这个服务正在 <code>istio-system</code> 命名空间里运行。</p><pre><code class=language-bash data-expandlinks=true>$ kubectl get svc --namespace=istio-system | grep sidecar-injector
istio-sidecar-injector ClusterIP 10.102.70.184 &lt;none&gt; 443/TCP 24d
</code></pre><p>这个配置总体上来说,完成了我们手工注入所需完成的工作。只不过是它是在 Pod 创建的过程中自动完成的,所以你也不会看到 Deployment 对象发生了任何变化。可以用 <code>kubectl describe</code> 命令来查看 Sidecar 和初始化容器。如果想要修改注入逻辑,例如 Istio 自动注入的生效范围,可以编辑 <code>MutatingWebhookConfiguration</code>,然后重启 Sidecar injector Pod。</p><p>Sidecar 的自动注入过程除了根据 <code>namespaceSelector</code> 选择命名空间之外,还受到缺省注入策略以及 Pod 自身注解的影响。</p><p>再看看 <code>istio-sidecar-injector</code> ConfigMap 中的缺省策略定义。可以看到,缺省是启用的。</p><pre><code class=language-bash data-expandlinks=true data-outputis=yaml>$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39;
SNIPPET from the output:
policy: enabled
template: |-
initContainers:
- name: istio-init
image: &#34;gcr.io/istio-release/proxy_init:1.0.2&#34;
args:
- &#34;-p&#34;
- [[ .MeshConfig.ProxyListenPort ]]
</code></pre><p>还可以在 Pod 模板中使用注解 <code>sidecar.istio.io/inject</code> 覆盖缺省策略。下面的例子中的 <code>Deployment</code> 用这种方式禁用了自动注入:</p><pre><code class=language-yaml data-expandlinks=true>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ignored
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: &#34;false&#34;
spec:
containers:
- name: ignored
image: tutum/curl
command: [&#34;/bin/sleep&#34;,&#34;infinity&#34;]
</code></pre><p>这个例子展示了很多可能性可以从命名空间标签、ConfigMap 或者 Pod 中分别进行控制:</p><ul><li>Webhooks 定义中的 <code>namespaceSelector</code><code>istio-injection: enabled</code></li><li>缺省策略(在 ConfigMap <code>istio-sidecar-injector</code> 中定义)</li><li>Pod 注解(<code>sidecar.istio.io/inject</code></li></ul><p><a href=/v1.2/zh/docs/ops/setup/injection/>注入状态表</a>中,根据上面三个因素的不同,可以看到有不同的注入结果。</p><h2 id=从应用容器到-sidecar-代理的通信>从应用容器到 Sidecar 代理的通信</h2><p>现在我们知道了 Sidecar 容器和初始化容器被注入到应用中的过程了Sidecar 代理是如何截获进出容器的流量呢?我们前面提到过,这是通过对 Pod 命名空间中 <code>iptable</code> 规则的设置来完成的,这个设置过程由 <code>istio-init</code> 容器来控制。现在可以看看命名空间中到底更新了些什么。</p><p>进入前面我们部署的应用 Pod 的命名空间,看看配置完成的 iptables。我会使用 <code>nsenter</code>。也可以用特权模式进入容器获得同样的信息。如果无法访问节点,可以用 <code>exec</code> 进入 Sidecar 来执行 <code>iptables</code> 指令。</p><pre><code class=language-bash data-expandlinks=true>$ docker inspect b8de099d3510 --format &#39;{{ .State.Pid }}&#39;
4125
</code></pre><pre><code class=language-bash data-expandlinks=true>$ nsenter -t 4215 -n iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N ISTIO_INBOUND
-N ISTIO_IN_REDIRECT
-N ISTIO_OUTPUT
-N ISTIO_REDIRECT
-A PREROUTING -p tcp -j ISTIO_INBOUND
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_INBOUND -p tcp -m tcp --dport 80 -j ISTIO_IN_REDIRECT
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15001
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ISTIO_REDIRECT
-A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001
</code></pre><p>上面展示的内容中,可以清楚的看到,所有从 80 端口(<code>red-demo</code> 应用监听的端口)进入的流量,被 <code>REDIRECTED</code> 到了端口 <code>15001</code>,这是 <code>istio-proxy</code>Envoy 代理)监听的端口。外发流量也是如此。</p><p>本文进入尾声。希望能够让读者了解到 Istio 将 Sidecar 注入到 Pod 中的过程,以及 Istio 将流量路由到代理服务器的过程。</p><div><aside class="callout idea"><div class=type><svg class="large-icon"><use xlink:href="/v1.2/img/icons.svg#callout-idea"/></svg></div><div class=content>更新:在 <code>istio-init</code> 阶段,现在有了一个新的使用 CNI 的方式,这种方式无需初始化容器的帮助,也不需要对应的权限。<a href=https://github.com/istio/cni><code>istio-cni</code></a> 插件会设置 Pod 的网络来满足这一要求,可以代替 <code>istio-init</code> 来完成任务。</div></aside></div><nav id=see-also><h2>相关内容</h2><div class=see-also><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/docs/setup/kubernetes/additional-setup/requirements/>Istio 对 Pod 和服务的要求</a></p><p class=desc>这里讲述了 Istio 对 Kubernetes 中 Pod 和服务的要求。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/docs/setup/kubernetes/additional-setup/sidecar-injection/>注入 Istio sidecar</a></p><p class=desc>介绍两种将 Istio sidecar 注入应用 Pod 的方法:使用 Sidecar 注入 Webhook 自动完成,或使用 istioctl 客户端工具手工完成。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/blog/2019/multicluster-version-routing/>多集群服务网格中的分版本路由</a></p><p class=desc>在多集群服务网格环境中配置 Istio 的路由规则。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/blog/2019/egress-performance/>Egress gateway 性能测试</a></p><p class=desc>评估加入 Egress gateway 对性能造成的影响。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/blog/2019/custom-ingress-gateway/>使用 Cert-Manager 部署一个自定义 Ingress 网关</a></p><p class=desc>如何使用 cert-manager 手工部署一个自定义 Ingress 网关。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.2/zh/blog/2018/incremental-traffic-management/>增量式应用 Istio 第一部分,流量管理</a></p><p class=desc>如何在不部署 Sidecar 代理的情况下使用 Istio 进行流量管理。</p></div></div></nav></article><nav class=pagenav><div class=left><a title="评估加入 Egress gateway 对性能造成的影响。" href=/v1.2/zh/blog/2019/egress-performance/><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#left-arrow"/></svg>Egress gateway 性能测试</a></div><div class=right><a title="使用 AppSwitch 解决应用程序启动顺序和启动延迟。" href=/v1.2/zh/blog/2019/appswitch/>使用 AppSwitch 进行 Sidestepping 依赖性排序<svg class="icon"><use xlink:href="/v1.2/img/icons.svg#right-arrow"/></svg></a></div></nav><div id=endnotes-container aria-hidden=true><h2>链接</h2><ol id=endnotes></ol></div></div><div class=toc-container><nav class=toc aria-label="Table of Contents"><div id=toc><ol><li role=none aria-label="Sidecar 注入"><a href=#sidecar-%e6%b3%a8%e5%85%a5>Sidecar 注入</a><ol><li role=none aria-label=手工注入><a href=#%e6%89%8b%e5%b7%a5%e6%b3%a8%e5%85%a5>手工注入</a><li role=none aria-label=自动注入><a href=#%e8%87%aa%e5%8a%a8%e6%b3%a8%e5%85%a5>自动注入</a></ol></li><li role=none aria-label="从应用容器到 Sidecar 代理的通信"><a href=#%e4%bb%8e%e5%ba%94%e7%94%a8%e5%ae%b9%e5%99%a8%e5%88%b0-sidecar-%e4%bb%a3%e7%90%86%e7%9a%84%e9%80%9a%e4%bf%a1>从应用容器到 Sidecar 代理的通信</a><li role=none aria-label=相关内容><a href=#see-also>相关内容</a></li></ol></div></nav></div></main><footer><div class=user-links><a class=channel title="Go download Istio 1.2.5 now" href=https://github.com/istio/istio/releases/tag/1.2.5 aria-label="Download Istio"><span>download</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#download"/></svg>
</a><a class=channel title="加入 Istio discussion board 参与讨论获取帮助" href=https://discuss.istio.io aria-label="Istio discussion board"><span>discuss</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#discourse"/></svg></a>
<a class=channel title="Stack Overflow 中列举了针对实际问题以及部署、配置和使用 Istio 的各项回答" href=https://stackoverflow.com/questions/tagged/istio aria-label="Stack Overflow"><span>stack overflow</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#stackoverflow"/></svg></a>
<a class=channel title="在 Slack 上与 Istio 社区交互讨论开发问题(仅限邀请)" href=https://istio.slack.com aria-label=slack><span>slack</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#slack"/></svg></a>
<a class=channel title="关注我们的 Twitter 来获取最新信息" href=https://twitter.com/IstioMesh aria-label=Twitter><span>twitter</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#twitter"/></svg></a><div class=tag>对于用户</div></div><div class=info><p class=copyright>中文内容由 ServiceMesher 社区维护,部分文档可能稍微滞后于英文版本,同步工作持续进行中<br>Istio 归档
1.2.5<br>&copy; 2019 Istio Authors, <a href=https://policies.google.com/privacy>隐私政策</a><br>归档于 2019年9月12日</p></div><div class=dev-links><a class=channel title="Istio 的代码在 GitHub 上开发" href=https://github.com/istio/community aria-label=GitHub><span>github</span><svg class="icon"><use xlink:href="/v1.2/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"><span>drive</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#drive"/></svg></a>
<a class=channel title="如果您想为 Istio 项目做出贡献,请考虑加入我们的工作组" href=https://github.com/istio/community/blob/master/WORKING-GROUPS.md aria-label="working groups"><span>working groups</span><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#working-groups"/></svg></a><div class=tag>对于开发者</div></div></footer><div id=scroll-to-top-container aria-hidden=true><button id=scroll-to-top title=回到顶部><svg class="icon"><use xlink:href="/v1.2/img/icons.svg#top"/></svg></button></div></body></html>