<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>sidecar | 伪架构师</title>
    <link>/tags/sidecar/</link>
      <atom:link href="/tags/sidecar/index.xml" rel="self" type="application/rss+xml" />
    <description>sidecar</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 10 Apr 2019 01:18:07 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>sidecar</title>
      <link>/tags/sidecar/</link>
    </image>
    
    <item>
      <title>Istio 1.1 中的 Sidecar 资源</title>
      <link>/post/istio-sidecar-resource/</link>
      <pubDate>Wed, 10 Apr 2019 01:18:07 +0800</pubDate>
      <guid>/post/istio-sidecar-resource/</guid>
      <description>

&lt;p&gt;缺省情况下，Istio 在 Pod 创建之前将 &lt;code&gt;istio-init&lt;/code&gt; 和 &lt;code&gt;istio-proxy&lt;/code&gt; 注入到 Pod 之中，使用 &lt;code&gt;istio-init&lt;/code&gt; 对 iptables 进行初始化，将业务容器的流量拦截到 &lt;code&gt;istio-proxy&lt;/code&gt;，从而完成通信控制权的移交工作——应用容器的自发 Ingress 和 Egress 通信，都从 Envoy 中留过，Envoy 作为数据平面，需要接受来自控制面的 xDS 指令，据此作出通信决策。&lt;/p&gt;

&lt;p&gt;在 Istio 1.1 中引入了 Sidecar 资源对象，为这一拦截转发过程加入了一定的控制能力，可能给 Istio 的生产应用带来很好的效率提升。&lt;/p&gt;

&lt;h2 id=&#34;基本结构&#34;&gt;基本结构&lt;/h2&gt;

&lt;p&gt;Sidecar 资源的一级结构很简单，由三个成员构成：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;workloadSelector&lt;/code&gt;：标签选择器，用来对 Pod 进行选择。这一字段是可选字段，如果忽略这一字段，则会对命名空间内的所有 Pod 生效。需要注意的是，一个命名空间之内，只允许存在一个不设置此字段的 Sidecar 对象。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;ingress&lt;/code&gt;：一个数组，用于处理进入 Pod 的流量，如果省略这一字段，Istio 会根据业务应用的工作负载定义来设置监听过程。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt;：必要字段，监听的端口，如果使用 Unix domain socket，则设置为 0。

&lt;ul&gt;
&lt;li&gt;number&lt;/li&gt;
&lt;li&gt;protocal&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bind&lt;/code&gt;：监听器的绑定设置，可以是 &lt;code&gt;ip&lt;/code&gt;，也可以是 &lt;code&gt;unix:///path/to/uds&lt;/code&gt;，如果省略这一字段，Istio 会根据工作负载服务来自动填充。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;captureMode&lt;/code&gt;：如果 &lt;code&gt;bind&lt;/code&gt; 指定的是 IP 地址，这个字段可以指定是否拦截通信，如果绑定到 Unix domain socket，这一字段必须是 &lt;code&gt;DEFAULT&lt;/code&gt; 或者 &lt;code&gt;NONE&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;defaultEndpoint&lt;/code&gt;：必要字段，Envoy 接收进入 Pod 的流量之后的转发目标。目标可以是 &lt;code&gt;127.0.0.1:PORT&lt;/code&gt; 或者 &lt;code&gt;unix:///path/to/socket&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;egress&lt;/code&gt;：一个处理 Egress 流量的定义数组。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt;：监听器的端口，如果使用 Unix domain socket，则设为 0。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bind&lt;/code&gt;：绑定到地址或 socket。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;captureMode&lt;/code&gt;：同 &lt;code&gt;ingress&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hosts&lt;/code&gt;：必要字段，用 &lt;code&gt;命名空间/服务 FQDN&lt;/code&gt; 组合而成，可以是 VirtualService 或者 ServiceEntry 或者原始 Kubernetes 服务的名称，支持通配符。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;开始之前&#34;&gt;开始之前&lt;/h2&gt;

&lt;p&gt;安装 Kubernetes 集群和 Istio，这里采用 1.1.2 的 demo-auth 配置。创建新命名空间 &lt;code&gt;other&lt;/code&gt;，并打标签开启自动注入：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ helm template install/kubernetes/helm/istio-init \
    --name istio-init --namespace istio-system | kubectl apply -f -
...
$ helm template install/kubernetes/helm/istio \
    --name istio --namespace istio-system \
    --values install/kubernetes/helm/istio/values-istio-demo-auth.yaml | kubectl apply -f -
...
$ kubectl create ns other
namespace/other created

$ kubectl label namespaces other istio-injection=enabled --overwrite
namespace/other labeled

$ kubectl label namespaces default istio-injection=enabled --overwrite
namespace/default labeled
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;分别在 &lt;code&gt;default&lt;/code&gt; 和 &lt;code&gt;other&lt;/code&gt; 中启动 &lt;code&gt;flaskapp&lt;/code&gt; 和 &lt;code&gt;sleep&lt;/code&gt; 应用。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl apply -f sleep/sleep.yaml -n default
service/sleep created
deployment.extensions/sleep created
$ kubectl apply -f sleep/sleep.yaml -n other
service/sleep created
deployment.extensions/sleep created
$ kubectl apply -f httpbin/httpbin.yaml -n default
service/httpbin created
deployment.extensions/httpbin created
$ kubectl apply -f httpbin/httpbin.yaml -n other
service/httpbin created
deployment.extensions/httpbin created
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;检查一下调用关系：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin:8000/ip
{
  &amp;quot;origin&amp;quot;: &amp;quot;127.0.0.1&amp;quot;
}

$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin.other:8000/ip
{
  &amp;quot;origin&amp;quot;: &amp;quot;127.0.0.1&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;服务的可见性&#34;&gt;服务的可见性&lt;/h2&gt;

&lt;p&gt;缺省情况下，注入了 Istio 的工作负载会进行全网格的传播，假设 &lt;code&gt;default&lt;/code&gt; 和 &lt;code&gt;other&lt;/code&gt; 两个不相干的命名空间，&lt;code&gt;other&lt;/code&gt; 中有大量的服务，而 &lt;code&gt;default&lt;/code&gt; 中只有几个，因为路由传播的关系，&lt;code&gt;default&lt;/code&gt; 命名空间中的工作负载，其 Sidecar 也会带上 &lt;code&gt;other&lt;/code&gt; 命名空间中的路由信息。例如：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ istioctl proxy-config clusters sleep-69bd44b5bb-vwpzf | grep other
httpbin.other.svc.cluster.local 8000    -   outbound    &amp;amp;{EDS}
sleep.other.svc.cluster.local   80      -   outbound    &amp;amp;{EDS}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可以看到，在 &lt;code&gt;default&lt;/code&gt; 命名空间中的 Pod，保存了其它命名空间中的路由信息。这不管是对内存消耗还是路由控制来说，都会造成一定浪费，我们可以定义一个 Sidecar 资源，限制 sleep 服务只访问同一命名空间的其他服务：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: sleep
spec:
  workloadSelector:
    labels:
      app: sleep  
  egress:
  - hosts:
    - &amp;quot;default/*&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;提交到集群，看看效果：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl apply -f sleep-egress.yaml
sidecar.networking.istio.io/sleep created

$ istioctl proxy-config clusters sleep-69bd44b5bb-vwpzf | grep httpbin
httpbin.default.svc.cluster.local   8000    -   outbound    &amp;amp;{EDS}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可以看到，httpbin 的路由只剩下了本命名空间之内的服务。再次尝试访问：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin:8000/ip
{
  &amp;quot;origin&amp;quot;: &amp;quot;127.0.0.1&amp;quot;
}

$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl -v http://httpbin.other:8000/ip
*   Trying 10.245.156.252...
* TCP_NODELAY set
* Connected to httpbin.other (10.245.156.252) port 8000 (#0)
&amp;gt; GET /ip HTTP/1.1
&amp;gt; Host: httpbin.other:8000
&amp;gt; User-Agent: curl/7.61.1
&amp;gt; Accept: */*
&amp;gt;
&amp;lt; HTTP/1.1 404 Not Found
&amp;lt; date: Wed, 10 Apr 2019 04:50:15 GMT
&amp;lt; server: envoy
&amp;lt; content-length: 0
&amp;lt;
* Connection #0 to host httpbin.other left intact
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这样一来，已经无法访问 &lt;code&gt;httpbin.other&lt;/code&gt; 的服务了，但是如果尝试从 &lt;code&gt;other&lt;/code&gt; 到 &lt;code&gt;default&lt;/code&gt; 访问的话，还是可以继续的。&lt;/p&gt;

&lt;h2 id=&#34;sidecar-的-ingress-和-egress&#34;&gt;Sidecar 的 Ingress 和 Egress&lt;/h2&gt;

&lt;p&gt;除了上面的小功能之外，Sidecar 的 &lt;code&gt;IstioEgressListener&lt;/code&gt; 和 &lt;code&gt;IstioIngressListener&lt;/code&gt; 都提供了很强大的功能，例如：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Envoy 可以为应用容器所监听的 Unix socket 提供反向代理服务。&lt;/li&gt;
&lt;li&gt;在没有 iptables 支持的情况下，可以使用 &lt;code&gt;bind&lt;/code&gt; 结合 &lt;code&gt;port&lt;/code&gt; 的方式，直接指定代理方案。&lt;/li&gt;
&lt;li&gt;可以在容器内部为 egress 服务提供基于 Unix socket 的反向代理。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;详情可以参考官方参考文档：&lt;a href=&#34;https://istio.io/docs/reference/config/networking/v1alpha3/sidecar/#IstioIngressListener&#34; target=&#34;_blank&#34;&gt;https://istio.io/docs/reference/config/networking/v1alpha3/sidecar/#IstioIngressListener&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;中文版：&lt;a href=&#34;https://skyao.io/learning-istio/crd/network/sidecar.html&#34; target=&#34;_blank&#34;&gt;https://skyao.io/learning-istio/crd/network/sidecar.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这些功能都非常有用，上面的文档中都提供了很好的应用场景，&lt;strong&gt;但是这些特性我只有可见性部分测试成功了(╬￣皿￣)=○&lt;/strong&gt;，目前正在讨说法，非常希望是我错了。。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
