<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>translate | 伪架构师</title>
    <link>/categories/translate/</link>
      <atom:link href="/categories/translate/index.xml" rel="self" type="application/rss+xml" />
    <description>translate</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Tue, 14 Aug 2018 11:42:06 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>translate</title>
      <link>/categories/translate/</link>
    </image>
    
    <item>
      <title>Istio 1.0 的实战测试</title>
      <link>/post/battle-testing-istio-1.0/</link>
      <pubDate>Tue, 14 Aug 2018 11:42:06 +0800</pubDate>
      <guid>/post/battle-testing-istio-1.0/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://medium.com/vescloud/battle-testing-istio-1-0-a0248ce68403&#34; target=&#34;_blank&#34;&gt;Battle Testing Istio 1.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;原作者：&lt;a href=&#34;https://medium.com/@pupapaik&#34; target=&#34;_blank&#34;&gt;Jakub Pavlík&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最近 Istio 成功发布了 1.0，并宣称生产就绪。我们的 SRE 团队对 Istio 1.0 生产状态进行了全面分析，最后提出了我们的建议。&lt;/p&gt;

&lt;p&gt;本文结构：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;安装和环境。&lt;/li&gt;
&lt;li&gt;要点和建议。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;安装和环境&#34;&gt;安装和环境&lt;/h2&gt;

&lt;p&gt;Istio 构建在&lt;a href=&#34;https://medium.com/microservices-in-practice/microservices-layered-architecture-88a7fc38d3f1&#34; target=&#34;_blank&#34;&gt;微服务架构&lt;/a&gt;基础之上，其中的应用网络由多个服务构成：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sidecar&lt;/strong&gt;：接收来自 Pilot 的配置信息，以代理服务器的身份处理入站和出站流量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pilot&lt;/strong&gt;：管理代理服务器，并和 Kubernetes 进行交互。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mixer&lt;/strong&gt;：接收来自代理服务器的指标，实施访问控制、配额管理等功能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Citadel&lt;/strong&gt;：为服务和用户提供认证和鉴权、管理凭据和 RBAC。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&#34;images/istio-arch.png&#34; alt=&#34;Istio Architecture&#34; /&gt;&lt;/p&gt;

&lt;p&gt;更多细节可移步浏览&lt;a href=&#34;https://istio.io/docs/zh/concepts/what-is-istio/overview/#architecture&#34; target=&#34;_blank&#34;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;安装过程比较方便。支持不同的环境（例如 Docker），但是 Kubernetes 是最适合我们需要的。&lt;/p&gt;

&lt;p&gt;安装方法支持列表：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;预渲染的 YAML&lt;/strong&gt;：这种方式适合预制环境（演示、评估以及 PoC 等）；这是因为其中的参数调整非常困难。YAML 文件可以进行模板化处理，但是其中有超过 3700 行代码，需要较大投入才能完成定制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Helm&lt;/strong&gt;：这种方式是参数化的，比较适合真实世界中的部署活动。正式的环境部署应该需要这样的定制能力。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;本文只是一次评估，因此使用了第一种方式。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;用静态 YAML 部署的 Istio 1.0&lt;/strong&gt;：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plain&#34;&gt;NAME                              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/grafana                    1         1         1            1           20h
deploy/istio-citadel              1         1         1            1           20h
deploy/istio-egressgateway        1         1         1            1           20h
deploy/istio-galley               1         1         1            1           20h
deploy/istio-ingressgateway       1         1         1            1           20h
deploy/istio-pilot                1         1         1            1           20h
deploy/istio-policy               1         1         1            1           20h
deploy/istio-sidecar-injector     1         1         1            1           20h
deploy/istio-statsd-prom-bridge   1         1         1            1           20h
deploy/istio-telemetry            1         1         1            1           20h
deploy/istio-tracing              1         1         1            1           20h
deploy/prometheus                 1         1         1            1           20h
deploy/servicegraph               1         1         1            1           20h


NAME                       REFERENCE                         TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
hpa/istio-egressgateway    Deployment/istio-egressgateway    &amp;lt;unknown&amp;gt; / 55%   1         5         1          20h
hpa/istio-ingressgateway   Deployment/istio-ingressgateway   &amp;lt;unknown&amp;gt; / 55%   1         5         1          20h

NAME                                DESIRED   SUCCESSFUL   AGE
jobs/istio-cleanup-secrets          1         1            20h
jobs/istio-grafana-post-install     1         1            20h
jobs/istio-mixer-post-install-1.0   1         1            20h

NAME                                           READY     STATUS    RESTARTS   AGE
po/grafana-67b5df5b97-d685n                    1/1       Running   0          20h
po/istio-citadel-65df4cf668-xspff              1/1       Running   0          20h
po/istio-egressgateway-6678667b46-pmfmx        1/1       Running   0          20h
po/istio-galley-7c64c8c948-8npwp               1/1       Running   27         20h
po/istio-ingressgateway-6dfd7fc84-w6snd        1/1       Running   0          3h
po/istio-pilot-6cc9f4f7c6-552h4                2/2       Running   0          20h
po/istio-policy-5476f99674-sqn7h               2/2       Running   0          20h
po/istio-sidecar-injector-5f47598cd7-8qlq6     1/1       Running   0          20h
po/istio-statsd-prom-bridge-5d44ddb7cf-lrc8t   1/1       Running   0          20h
po/istio-telemetry-654bfd8487-bmdwv            2/2       Running   0          20h
po/istio-tracing-5fbd79cc-pnq5n                1/1       Running   0          20h
po/prometheus-7b6f8b9996-t4t92                 1/1       Running   0          20h
po/servicegraph-7d7ccc9b7f-b86c4               1/1       Running   0          20h

NAME                           TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                                                                     AGE
svc/grafana                    ClusterIP      10.0.18.159    &amp;lt;none&amp;gt;          3000/TCP                                                                    20h
svc/istio-citadel              ClusterIP      10.0.228.1     &amp;lt;none&amp;gt;          8060/TCP,9093/TCP                                                           20h
svc/istio-egressgateway        ClusterIP      10.0.217.249   &amp;lt;none&amp;gt;          80/TCP,443/TCP                                                              20h
svc/istio-galley               ClusterIP      10.0.131.153   &amp;lt;none&amp;gt;          443/TCP,9093/TCP                                                            20h
svc/istio-ingressgateway       LoadBalancer   10.0.72.147    13.66.222.246   80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:30223/TCP,8060:31415/TCP   20h
svc/istio-pilot                ClusterIP      10.0.67.90     &amp;lt;none&amp;gt;          15010/TCP,15011/TCP,8080/TCP,9093/TCP                                       20h
svc/istio-policy               ClusterIP      10.0.135.115   &amp;lt;none&amp;gt;          9091/TCP,15004/TCP,9093/TCP                                                 20h
svc/istio-sidecar-injector     ClusterIP      10.0.158.161   &amp;lt;none&amp;gt;          443/TCP                                                                     20h
svc/istio-statsd-prom-bridge   ClusterIP      10.0.17.41     &amp;lt;none&amp;gt;          9102/TCP,9125/UDP                                                           20h
svc/istio-telemetry            ClusterIP      10.0.139.187   &amp;lt;none&amp;gt;          9091/TCP,15004/TCP,9093/TCP,42422/TCP                                       20h
svc/jaeger-agent               ClusterIP      None           &amp;lt;none&amp;gt;          5775/UDP,6831/UDP,6832/UDP                                                  20h
svc/jaeger-collector           ClusterIP      10.0.172.142   &amp;lt;none&amp;gt;          14267/TCP,14268/TCP                                                         20h
svc/jaeger-query               ClusterIP      10.0.51.47     &amp;lt;none&amp;gt;          16686/TCP                                                                   20h
svc/prometheus                 ClusterIP      10.0.156.162   &amp;lt;none&amp;gt;          9090/TCP                                                                    20h
svc/servicegraph               ClusterIP      10.0.163.81    &amp;lt;none&amp;gt;          8088/TCP                                                                    20h
svc/tracing                    ClusterIP      10.0.111.218   &amp;lt;none&amp;gt;          80/TCP                                                                      20h
svc/zipkin ClusterIP 10.0.89.198 &amp;lt;none&amp;gt; 9411/TCP 20h
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;要点和建议&#34;&gt;要点和建议&lt;/h2&gt;

&lt;h3 id=&#34;操作复杂度&#34;&gt;操作复杂度&lt;/h3&gt;

&lt;p&gt;Istio 的功能集随着每次发布逐步增长，运维需求也自然是水涨船高。要运维 Istio，不仅要有对 Istio 组件和配置的基本理解，还需要对 Kubernetes 有深入的认识。Istio 1.0 中包含了 51 个 CRD，比 0.8 版本又多出了 8 个。&lt;/p&gt;

&lt;p&gt;正如 &lt;a href=&#34;https://twitter.com/sebgoa&#34; target=&#34;_blank&#34;&gt;Sebastein Goasguen&lt;/a&gt; 在 &lt;a href=&#34;https://medium.com/vescloud/battle-testing-istio-1-0-a0248ce68403&#34; target=&#34;_blank&#34;&gt;Twitter&lt;/a&gt; 中说的：如果你觉得 Kubernetes 很难，来看看（理解和维护）Istio 和他的 43 个 API 对象吧。&lt;/p&gt;

&lt;p&gt;运维的复杂性，在未来可以用 Galley 对服务和客户端的配置管理来进行简化。Galley 是 1.0 中新引入的组件，在 Istio 中，承担配置的导入、处理和分发任务。这一组件的主要目标是应对现有的配置方面的挑战，例如检测、组件之间的复用、配置错误和验证等问题。这样就可以提供更好的运维体验，同时降低对 Istio 各组件深入理解的需求。Galley 负责把其它 Istio 组件和从底层平台获取用户配置的细节中隔离开来。它其中包含了 Kubernetes 的 CRD 监听器，用来收集配置；还有一个网格配置协议（Mesh Config Protocol-MCP）服务器用于配置分发；以及一个用于验证的 Webhook，使用 &lt;a href=&#34;https://github.com/istio/istio/tree/master/galley&#34; target=&#34;_blank&#34;&gt;Kubernetes API Server&lt;/a&gt; 对配置进行前置检查。&lt;/p&gt;

&lt;p&gt;Galley 在 Istio 1.0 中可以禁用，并且在 AWS EKS 中必须和 Sidecar 的自动注入一起禁用，这是因为 EKS 不支持启用准入控制器，例如这里要用到的修改和验证 Webhook。加入 &lt;a href=&#34;https://groups.google.com/forum/#!forum/istio-dev&#34; target=&#34;_blank&#34;&gt;Google Group&lt;/a&gt; 阅读 &lt;a href=&#34;https://docs.google.com/document/d/1477BlHU0leWA4IKFRwnbNl5MZngf5m2K-JsBIo6dxJE/edit#&#34; target=&#34;_blank&#34;&gt;Galley 概要设计文档&lt;/a&gt; 可以获得更多信息。&lt;/p&gt;

&lt;h3 id=&#34;管理-ingress-gateway&#34;&gt;管理 Ingress Gateway&lt;/h3&gt;

&lt;p&gt;在 &lt;a href=&#34;https://istio.io/docs/reference/config/istio.networking.v1alpha3/&#34; target=&#34;_blank&#34;&gt;v1alpha3&lt;/a&gt; 中， Istio Gateway 和 VirtualService 一起，替换了 Kubernetes 的原生 Ingress。相对于 Kubernetes 的原生 Ingress，这一组合提供了更多高级配置。然而这些资源只是定义，真正的流量管理是由 Ingress Gateway 完成的。&lt;/p&gt;

&lt;p&gt;Ingress Gateway 是一个 Istio proxy（Envoy），它会根据 Gateway 和 VirtualService 定义响应网格外发来的入站流量。缺省的安装只包含一个 &lt;code&gt;ingressgateway&lt;/code&gt; pod 并且只使用 LoadBalancer 服务申请了一个公共 IP。要注意下面的限制：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;多个服务无法同时监听同一个外部端口，例如网格外只能开放一个 3306 端口。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VirtualService&lt;/code&gt; 的路径不可重叠。如果有多个独立团队使用 Istio 的话可能会出现问题。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这两个限制都可以通过部署多个 &lt;code&gt;ingressgateway&lt;/code&gt; pod 来监听多个公共 IP 的方式来解决。遗憾的是，对多个 &lt;code&gt;ingressgateway&lt;/code&gt; 实例的管理不太简单，需要自行定义合适的选择器。&lt;/p&gt;

&lt;h3 id=&#34;配置验证和同步&#34;&gt;配置验证和同步&lt;/h3&gt;

&lt;p&gt;可以使用标准的 &lt;code&gt;kubectl&lt;/code&gt; 命令配置 Istio，也可以选择使用原生的 &lt;code&gt;istioctl&lt;/code&gt; 工具。两种方法会得到同样的结果——在 Kubernetes 中创建 CRD。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;注意：只有 &lt;code&gt;istioctl&lt;/code&gt; 会在把定义文件发送给 Kubernetes API Server 之前对 CRD 进行验证。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kubernetes 中部署的 Istio Webhook 会进行第二次验证，但是他只会对配置的结构进行验证，功能验证目前还没有实现。因为只做语义验证不做功能验证，上面提到的路径叠加问题会很容易遇到。&lt;/p&gt;

&lt;p&gt;Istio 1.0 在 &lt;code&gt;istioctl&lt;/code&gt; 命令中加入很多状态和健康状态方面的改进。&lt;code&gt;istioctl proxy-status&lt;/code&gt; 命令会获取 Pilot 和 Envoy 之间最新发送和接收的 xDS 同步信息，并提供一个状态概览：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plain&#34;&gt;istioctl proxy-status
PROXY                                                 CDS        LDS        EDS               RDS          PILOT                            VERSION
details-v1-7bcdcc4fd6-9p7sr.default                   SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
istio-egressgateway-6678667b46-pmfmx.istio-system     SYNCED     SYNCED     SYNCED (100%)     NOT SENT     istio-pilot-6cc9f4f7c6-552h4     1.0.0
istio-ingressgateway-6dfd7fc84-w6snd.istio-system     SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
kad-5f89bf94fc-b48z2.kad                              SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
productpage-v1-8584c875d8-9mlbr.default               SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
ratings-v1-54cf9dc8f8-hthzx.default                   SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
reviews-v1-59cbdd7959-2ng8m.default                   SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
reviews-v2-dccb4cfc9-rp6rx.default                    SYNCED     SYNCED     SYNCED (100%)     SYNCED       istio-pilot-6cc9f4f7c6-552h4     1.0.0
reviews-v3-5465dc97bc-k9rdb.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;statefulset-和-headless-服务的支持&#34;&gt;StatefulSet 和 Headless 服务的支持&lt;/h3&gt;

&lt;p&gt;Headless 服务是没有 IP 的，服务中的各个实例通常会用点对点的形式进行访问，因此在服务网格中，这种服务是个难于应对的问题。要给这种服务配置 mTLS 认证，流量的检测和处理都可能遇到问题。&lt;/p&gt;

&lt;p&gt;Kubernetes StatefulSet 经常和 Headless 服务一同使用。在服务实例之间进行通信时，我们也发现了问题。我们用 StatefulSet 运行 Cassandra 集群，第二个实例出现了如下问题：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plain&#34;&gt;INFO  13:44:05 Handshaking version with cassandra-0.cassandra.sre.svc.cluster.local/10.244.4.33

INFO  13:44:05 Cannot handshake version with cassandra-0.cassandra.sre.svc.cluster.local/10.244.4.33
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;要解决这个问题，要把 Cassandra 移出网格，或者修改 mTLS 认证策略。这一问题在目前正在跟踪之中。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://github.com/istio/istio/issues/5005&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://github.com/istio/istio/pull/6885&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://github.com/istio/istio/issues/1277&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;pod-检测&#34;&gt;Pod 检测&lt;/h3&gt;

&lt;p&gt;Kubernetes 会进行 Pod 检测，查看 Pod 的存活和就绪状态。检测方法有多种实现方式，TCP 和 HTTP 是最常见的。当 Kubelet 能够通过 HTTP 请求或者 TCP 连接访问到 Pod，就会判定 Pod 检测成功。当服务间的 mTLS 启用时，Kubelet 却并非网格的一部分，因此就无法访问 Pod 了。&lt;/p&gt;

&lt;p&gt;要解决这一问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;推荐方案是为服务检测准备单独的端口，并在这一端口上禁用认证功能。&lt;/li&gt;
&lt;li&gt;禁止 Pod 检测也是一个可选方案。&lt;/li&gt;
&lt;li&gt;在 Pod 内部使用 exec 检测，代替 Kubelet 完成这一任务。然而我们不推荐这种方式，这种检测不够全面，可能会有隐藏问题存在，例如 CNI。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;多集群鸿沟&#34;&gt;多集群鸿沟&lt;/h3&gt;

&lt;p&gt;Istio 从 0.8 开始支持单控制平面下的多集群部署。&lt;a href=&#34;https://medium.com/ibm-cloud/multi-cluster-support-for-service-mesh-with-ibm-cloud-private-d7d791f9b778&#34; target=&#34;_blank&#34;&gt;博客&lt;/a&gt;中提供了 0.8 中运行多集群 Istio 的详细介绍。Google 还在上一次 KubeCon 上做了一次演示（&lt;a href=&#34;https://youtu.be/bLJL53UIcqI?t=14m9s&#34; target=&#34;_blank&#34;&gt;视频&lt;/a&gt;）。1.0 版本中加入了为数众多的安全和性能方面的改进，其中包括远程集群的 Sidecar 自动注入能力。这方面可以参考&lt;a href=&#34;https://docs.google.com/document/d/1cOxPnTpnVWKR0m7a6PYJ-0NSTZ-e2J1IULnfojz7OZ4/edit#&#34; target=&#34;_blank&#34;&gt;详细设计文档&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;不幸的是这一功能在我们的生产环境上也是有问题的，现列举如下：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;集群间的 Pod 网络需要打通——这超出了 Istio 的能力范围，应该由 VPN 来完成这一任务。目前有提案使用 &lt;a href=&#34;https://docs.google.com/document/d/1QLMeycCoj6fbBKoOLiaDCc09Fbi89s5VoBW-eAxKwVs/edit#heading=h.qex63c29z2to&#34; target=&#34;_blank&#34;&gt;Zero VPN&lt;/a&gt; 来解决这一问题。&lt;/li&gt;
&lt;li&gt;远端集群需要能够解析 Pilot、Policy、Telemetry 以及 StatsD 端点——目前远程集群会使用控制面集群的 Pod IP，而 Pod IP 是可能因为 Pod 重启或者 Node 崩溃而发生变化的，这就需要重新部署 Istio。目前已经有 &lt;a href=&#34;https://github.com/istio/istio/pull/6210&#34; target=&#34;_blank&#34;&gt;PR&lt;/a&gt; 在尝试解决这个问题：部署额外的 Istio Ingress Gateway 来负责对 Istio Pilot、Policy 以及 Telemetry 端点的访问。&lt;/li&gt;
&lt;li&gt;Istio 的配置和状态是保存在“主”集群上的，一旦主集群发生了故障，就会出现跨集群的瓶颈。&lt;/li&gt;
&lt;li&gt;Github 上还跟踪了其它 &lt;a href=&#34;https://github.com/istio/istio/issues/4822&#34; target=&#34;_blank&#34;&gt;Issue&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;结论&#34;&gt;结论&lt;/h2&gt;

&lt;p&gt;Istio 是第一个&lt;a href=&#34;https://preliminary.istio.io/about/notes/1.0/&#34; target=&#34;_blank&#34;&gt;生产就绪的版本&lt;/a&gt;，多数核心组件都已稳定，我们对其稳定性基本满意，运维方面还存在一些问题，在生产环境中的应用很有挑战性。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;因为新的操作可能会对既有工作负载造成影响，动态环境中的运维活动颇具危险性。&lt;/li&gt;
&lt;li&gt;必须监控的一些内容：配置变更，Sidecar 日志，Mixer 中的 Kubernetes 适配器。&lt;/li&gt;
&lt;li&gt;部分 Kubernetes 特性并未完整集成，例如 Pod 检测、Headless 服务。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;迄今为止，Istio 获得了巨大成就。如果是对系统缺乏深入理解的用户，要在生产环境中操作 Kubernetes 还是有一定难度的。我们认为，Istio 1.0 的完成度是合乎要求的，目前的用户多数都要归为超级用户的类别。短期之内，需要托管的 Istio 产品来满足消费市场的需要。还需要持续关注性能、伸缩以及策略处理方面的进展。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Kubernetes 中对持久卷进行扩容</title>
      <link>/post/k8s-1.11-resizing-pvc/</link>
      <pubDate>Sun, 15 Jul 2018 00:08:31 +0800</pubDate>
      <guid>/post/k8s-1.11-resizing-pvc/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/&#34; target=&#34;_blank&#34;&gt;Resizing Persistent Volumes using Kubernetes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://www.linkedin.com/in/gnufied&#34; target=&#34;_blank&#34;&gt;Hemant Kumar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes v1.11 中，持久卷扩容能力升级为 Beta 阶段。这个功能让用户可以轻松的通过编辑 PVC 对象的方式修改现有卷的容量。没有这一功能之前，要对卷容量进行修改，需要要和存储后端进行手工交互，或者对 PV 以及 PVC 进行删除重建操作。持久卷不支持缩容操作。&lt;/p&gt;

&lt;p&gt;v1.8 中卷扩展功能就已经进入 Alpha 阶段，v1.11 之前需要在 feature gate 中开启 &lt;code&gt;ExpandPersistentVolumes&lt;/code&gt;，以及 admission 控制器 &lt;code&gt;PersistentVolumeClaimResize&lt;/code&gt;（防止在底层存储不支持扩容的情况下对 PVC 进行扩容）。在 Kubernetes v1.11 中，这两个项目都会被缺省激活。&lt;/p&gt;

&lt;p&gt;虽然功能已经被激活，但是集群管理员还是需要进行操作，让用户能够对自己的卷进行扩容。Kubernetes 1.11 内置了对部分卷插件的扩容支持：AWS-EBS、GCE-PD、Azure Disk、Azure File、Glusterfs、Cinder、Portworx、以及 Ceph RBD。管理员确定底层存储能够支持卷扩展之后，就可以在 &lt;code&gt;StorageClass&lt;/code&gt; 对象中设置 &lt;code&gt;allowVolumeExpansion&lt;/code&gt; 为 &lt;code&gt;true&lt;/code&gt; 来启用这一功能了。只有从 &lt;code&gt;StorageClass&lt;/code&gt; 中创建的 PVC 才允许使用卷扩展：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
parameters:
  type: pd-standard
provisioner: kubernetes.io/gce-pd
allowVolumeExpansion: true
reclaimPolicy: Delete
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;任何从这一 &lt;code&gt;StorageClass&lt;/code&gt; 中创建的 PVC 都能够通过编辑的方式来申请更多空间。Kubernetes 会处理 Storage 字段的变更，据此申请空间，触发卷的扩容。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi #更新这一字段，修改 PVC 容量
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;文件系统扩展&#34;&gt;文件系统扩展&lt;/h2&gt;

&lt;p&gt;GCE-PD、AWS-EBS、Azure Disk、Cinder 以及 Ceph RBD 这些块存储卷通常需要首先进行文件系统的扩展，然后被扩展的卷的额外空间才能为 Pod 所用。引用这些卷的 Pod 重启时，Kubernetes 会自动完成这些任务。&lt;/p&gt;

&lt;p&gt;网络挂载的文件系统，例如 Glusterfs 和 Azure File，因为不需要进行文件系统扩展，因此可以在不重启 Pod 的情况下直接进行扩展。&lt;/p&gt;

&lt;p&gt;只有终止引用卷的 Pod，才会触发对应文件系统的扩展，更确切地说：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;编辑 PVC，申请更多空间。&lt;/li&gt;
&lt;li&gt;底层存储对底层卷进行了扩展之后，PV 对象就会响应这一变化，PVC 会进入 &lt;code&gt;FileSystemResizePending&lt;/code&gt; 状态。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;可以运行 &lt;code&gt;kubectl get pvc &amp;lt;pvc_name&amp;gt; -o yaml&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
  namespace: default
  uid: 02d4aa83-83cd-11e8-909d-42010af00004
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 14Gi
  storageClassName: standard
  volumeName: pvc-xxx
status:
  capacity:
    storage: 9G
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2018-07-11T14:51:10Z
    message: Waiting for user to (re-)start a pod to finish file system resize of
      volume on node.
    status: &amp;quot;True&amp;quot;
    type: FileSystemResizePending
  phase: Bound
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;PVC 进入 &lt;code&gt;FileSystemResizePending&lt;/code&gt; 状态，引用 PVC 的 Pod 就可以重新启动来结束文件系统在 Node 上的扩展过程了。可以通过删除和重建 Pod 的方式进行重启，也可以通过对 Deployment 的伸缩来完成这一过程。&lt;/li&gt;
&lt;li&gt;文件系统的扩展操作完成之后，PVC 会自动更新，设置为新的容量。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;文件系统扩展过程中遇到任何错误，都会在 Pod 中以 Event 的形式表现出来。&lt;/p&gt;

&lt;h2 id=&#34;在线文件系统扩展&#34;&gt;在线文件系统扩展&lt;/h2&gt;

&lt;p&gt;Kubernetes v1.11 还引入了一个 Alpha 功能，叫做在线文件系统扩展。这个功能可以对一个正在被 Pod 使用的卷进行文件系统的扩展。这个功能还处于 Alpha 阶段，因此需要通过 Feature gate 启用 &lt;code&gt;ExpandInUsePersistentVolumes&lt;/code&gt;。目前支持的有 GCE-PD、AWS-EBS、Cinder 以及 Ceph RBD。当激活这个功能后，引用被扩展的卷的 Pod 无需重启。文件系统会随着卷扩展的步骤进行扩展。文件系统的扩展只有在 Pod 引用被扩展的卷的时候才会发生，所以如果没有 Pod 引用这个卷，那么就不会进行文件系统扩展。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Consul vs Istio</title>
      <link>/post/consul-vs-istio/</link>
      <pubDate>Wed, 11 Jul 2018 19:40:12 +0800</pubDate>
      <guid>/post/consul-vs-istio/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.consul.io/intro/vs/istio.html&#34; target=&#34;_blank&#34;&gt;Consul vs Istio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Istio 是一个开源平台，可以为微服务提供连接、管理和加密功能。&lt;/p&gt;

&lt;p&gt;要启用 Istio 的全部功能，必须部署多个服务。控制面包括了 Pilot、Mixer 以及 Citadel 这几个必要组件，数据面的 Envoy Sidecar 也是必不可少的。另外 Istio 需要第三方的服务发现支持，例如 Kubernetes、Consul、Eureka 或者其他别的什么。最后 Istio 需要一个外部系统用来进行存储，通常是 ETCD。换句话说，Istio 需要至少三个独立的服务，以及至少一个分布式系统才算完整。&lt;/p&gt;

&lt;p&gt;Istio 在七层提供了基于路径的路由、流量整形、负载均衡以及遥测功能。Istio 还基于服务认证功能提供了访问控制的支持，能使用七层和四层的属性对访问、路由进行控制。&lt;/p&gt;

&lt;p&gt;Consul 是一个单一的二进制文件，同时提供了服务器和客户端的能力，并自带全部的服务发现、配置、TLS、认证等功能。无需安装额外的系统即可使用，同时还为 Vault 之类的外部系统提供了可选支持，从而进行功能扩展。这一架构让 Consul 能够轻松的安装在任何平台上，也包括物理机。&lt;/p&gt;

&lt;p&gt;Consule 是一个基于 Agent 的模型，集群中的每个节点都需要运行一个 Consul 客户端。客户端软件管理一个本地缓存，缓存的数据来源于服务器。无需任何外部通信，所有的加密服务通信 API 都能在几毫秒的时间内进行响应。这样我们的连接过程发生在边缘，无需和中央服务器进行通信。Istio 将请求流入位于中央的 Mixer 服务，而数据的推送过程又必须由 Pilot 完成。这种机制极大的降低了 Istio 的稳定性，而 Consul 却能够在边缘高效的完成数据更新的分发以及其他工作。&lt;/p&gt;

&lt;p&gt;Consul 的数据面是可插接的。它包含了一个内置的代理服务器，这一服务牺牲了较多性能，换来易用性的提升。用户也可以使用 Envoy 这样的第三方代理。不同的任务会有各自合适的代理，Consul 就提供了这种能力，从而能够支持复杂多样的应用部署。&lt;/p&gt;

&lt;p&gt;除了第三方代理支持，应用可以直接和 Connect 协议进行集成。这样一来，引入 Connect 的开销就可以忽略不计了。任何其他的 Connect 支持的应用，不管使用代理或者 Connect 原生方式，都具备互联互通的能力。&lt;/p&gt;

&lt;p&gt;Consul 只在四层实现了认证和鉴权——TLS 连接是否能够建立。我们认为服务认证应该留在四层，七层要做的事情是路由、遥测等事情。我们鼓励用户借助我们的可插接数据面，为集群所需要的七层功能选择合适的代理服务器。Consul 会在未来加入更多七层特性。&lt;/p&gt;

&lt;p&gt;Consul 实现了自动的 TLS 认证管理，并且提供了完整的轮转支持。即使是一个大型的 Consul 集群中，也能够在无中断的情况下实现自动轮转。认证管理系统也是可插接的，目前通过代码集成在 Consul 中，很快我们会将其剥离成为外部插件。这就 Consul 就有了和任意 PKI 方案协同工作的能力。&lt;/p&gt;

&lt;p&gt;因为 Consul 的服务连接能力（”Connect“）是内置的，他也具备和 Consul 一样的稳定性。2014 年以来，Consule 就在大型企业的生产环境中工作，目前已经有单集群部署 50000 节点的规模。&lt;/p&gt;

&lt;p&gt;这一比较基于我们自己对 Istio 的有限认识，以及和 Istio 用户的交流。如果读者认为其中有不实之处，请点击 &lt;a href=&#34;https://github.com/hashicorp/consul/blob/master/website/source/intro/vs/istio.html.md&#34; target=&#34;_blank&#34;&gt;Edit this page&lt;/a&gt; 提交修改建议。我们会尽快对读者意见进行审核和更新，希望以此来保证本文的准确性。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Draft vs Gitkube vs Helm vs Ksonnet vs Metaparticle vs Skaffold</title>
      <link>/post/draft-vs-gitkube-vs-helm-vs-ksonnet-vs-metaparticle-vs-skaffold/</link>
      <pubDate>Tue, 26 Jun 2018 11:29:18 +0800</pubDate>
      <guid>/post/draft-vs-gitkube-vs-helm-vs-ksonnet-vs-metaparticle-vs-skaffold/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://blog.hasura.io/draft-vs-gitkube-vs-helm-vs-ksonnet-vs-metaparticle-vs-skaffold-f5aa9561f948&#34; target=&#34;_blank&#34;&gt;Draft vs Gitkube vs Helm vs Ksonnet vs Metaparticle vs Skaffold&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://blog.hasura.io/@shahidh&#34; target=&#34;_blank&#34;&gt;Shahidh K Muhammed&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;tl-dr&#34;&gt;TL;DR&lt;/h2&gt;

&lt;h3 id=&#34;draft-https-draft-sh&#34;&gt;&lt;a href=&#34;https://draft.sh/&#34; target=&#34;_blank&#34;&gt;Draft&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;向 K8S 集群部署代码（自动“构建-推送-部署”）。&lt;/li&gt;
&lt;li&gt;使用 &lt;a href=&#34;https://github.com/Azure/draft/tree/master/packs&#34; target=&#34;_blank&#34;&gt;Draft 打包支持的语言&lt;/a&gt; 的代码可以不编写 Dockerfile 或者 K8S 元数据文件直接进行部署。&lt;/li&gt;
&lt;li&gt;需要 draft 以及 helm 客户端，集群要部署 tiller，本地 Docker，Docker 仓库。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;gitkube-https-gitkube-sh&#34;&gt;&lt;a href=&#34;https://gitkube.sh/&#34; target=&#34;_blank&#34;&gt;Gitkube&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;向 K8S 集群部署代码（自动“构建-推送-部署”）。&lt;/li&gt;
&lt;li&gt;Git 推送触发部署，本机无依赖。&lt;/li&gt;
&lt;li&gt;Git 仓库中需要提供 Dockerfile 以及 K8S 元数据文件，集群中需部署 gitkube。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;helm-https-helm-sh&#34;&gt;&lt;a href=&#34;https://helm.sh/&#34; target=&#34;_blank&#34;&gt;Helm&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;在 K8S 集群上对 Chart（其中包含一个应用的所有 K8S 资源定义文件）进行部署和管理。&lt;/li&gt;
&lt;li&gt;提供了很多通用应用（例如 MySQL、Mediawiki 等）的 Chart。&lt;/li&gt;
&lt;li&gt;客户端需要 Helm，服务端需要 Tiller，Chart 定义可以在本地也可以在仓库中保存。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;ksonnet-https-ksonnet-io&#34;&gt;&lt;a href=&#34;https://ksonnet.io/&#34; target=&#34;_blank&#34;&gt;Ksonnet&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;在 jsonnet 上定义 K8S 元数据文件，然后进行部署。&lt;/li&gt;
&lt;li&gt;可以对通用模式（例如 Deployment + Service）和应用栈（例如 Redis）进行复用。&lt;/li&gt;
&lt;li&gt;需要 jsonnet 知识，安装 ksonnet 客户端。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;metaparticle-https-metaparticle-io&#34;&gt;&lt;a href=&#34;https://metaparticle.io/&#34; target=&#34;_blank&#34;&gt;Metaparticle&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用 &lt;a href=&#34;https://metaparticle.io/&#34; target=&#34;_blank&#34;&gt;Metaparticle 支持的语言&lt;/a&gt; 编写代码，然后部署到 K8S 集群（自动“构建-推送-部署”）&lt;/li&gt;
&lt;li&gt;在应用的代码中直接定义容器化和 K8S 相关内容，傻瓜化的编写过程，无需编写 Dockerfile 或者 Yaml。&lt;/li&gt;
&lt;li&gt;需要本地 Docker 部署，需要相关语言的库。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;skaffold-https-github-com-googlecloudplatform-skaffold&#34;&gt;&lt;a href=&#34;https://github.com/GoogleCloudPlatform/skaffold&#34; target=&#34;_blank&#34;&gt;Skaffold&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;向 K8S 集群部署代码（自动“构建-推送-部署”）。&lt;/li&gt;
&lt;li&gt;监控源代码变更，变更发生后就会触发“构建-推送-部署”过程，Pipeline 可配置。&lt;/li&gt;
&lt;li&gt;需要 Skaffold 客户端、Dockerfile、K8S 元数据文件、Skaffold 元数据文件，本地 Docker 以及私库。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;下面进入一点细节。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;img/1*eBG8XpHztwns7GR9qtz0Pg.png&#34; alt=&#34;Brands&#34; /&gt;&lt;/p&gt;

&lt;p&gt;当今的 Kubernetes 炙手可热，用户们寻求更多的方式和流程来进行 Kubernetes 集群上的应用部署。&lt;code&gt;kubectl&lt;/code&gt; 已经成为底层工具，用户需要更易用的流程。Draft、Gitkube、Helm、Ksonnet、MetaParticle 以及 Skaffold 都是用来帮助开发人员在 Kubernetes 上进行应用构建和部署的工具。&lt;/p&gt;

&lt;p&gt;Draft、Gitkube 和 Skaffold 减轻了开发人员的负担，在构建应用的过程中，能够更快的在 Kubernetes 上运行起来。Helm 和 Ksonnet 提供了定义应用、更新版本、选择不同集群等功能，在应用构建完成，进入发布就绪状态之后，这两个工具可以提高部署能力。Metaparticle 是比较独特的一个，他把包含 yaml、dockerfile 这些东西集成到业务代码之中。&lt;/p&gt;

&lt;p&gt;所以用户自身的用例中如何进行选择？&lt;/p&gt;

&lt;h2 id=&#34;正文&#34;&gt;正文&lt;/h2&gt;

&lt;h3 id=&#34;draft-https-draft-sh-1&#34;&gt;&lt;a href=&#34;https://draft.sh/&#34; target=&#34;_blank&#34;&gt;Draft&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;在任何 Kubernetes 集群上简化应用的开发和部署。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;顾名思义，Draft 让面向 Kubernetes 的应用开发变得简单。官方宣称，对于运行在 Kubernetes 上的应用，Draft 这一工具是帮助开发过程而非部署的。Draft 文档中推荐使用 Helm 进行应用部署。&lt;/p&gt;

&lt;p&gt;他的目标是：开发人员还在开发调试之中的本地的代码，不经提交到版本控制系统，直接运行到 Kubernetes 集群上。开发人员对 Draft 发布的应用变更满意之后，才提交给版本控制系统。&lt;/p&gt;

&lt;p&gt;Draft 不是用来在生产环境上进行部署的，他的用意就是在于快速推进面向 Kubernetes 环境的开发过程。他内部使用 Helm 来进行变更，因此他和 Helm 的集成是非常紧密的。&lt;/p&gt;

&lt;h4 id=&#34;架构&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;img/1*kV56ClDz_rrMg5wT4lpQ5Q.png&#34; alt=&#34;Draft architecture&#34; /&gt;&lt;/p&gt;

&lt;p&gt;如上图所示，&lt;code&gt;Draft&lt;/code&gt; 客户端是一个关键组件。它感知代码的变化，然后从 &lt;code&gt;Repo&lt;/code&gt; 中获取对应的 &lt;code&gt;Pack&lt;/code&gt;。&lt;code&gt;Pack&lt;/code&gt; 是一个 Dockerfile 和 Helm chart 的合体，他们一起定义了应用的运行环境。&lt;code&gt;Pack&lt;/code&gt; 定义之后保存在 &lt;code&gt;Repo&lt;/code&gt; 中。用户可以定义自己的 &lt;code&gt;Pack&lt;/code&gt; 和 &lt;code&gt;Repo&lt;/code&gt;，这两个对象可以保存在本地，也可以在 Git 仓库之中。&lt;/p&gt;

&lt;p&gt;只要有对应的 &lt;code&gt;Pack&lt;/code&gt;，任何一个包含源码的目录都可以进行部署。使用 &lt;code&gt;draft create&lt;/code&gt; 处理目录之后，会在目录中添加 Dockerfile、Helm chart 以及 draft.toml 文件，&lt;code&gt;draft up&lt;/code&gt; 能够构建 Docker 镜像，推送到私库，然后使用 Helm Chart 部署应用。每次代码变更之后，再次执行这一命令，就会产生一个新的部署。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;draft connect&lt;/code&gt; 命令能够进行端口转发，以此在本地获取容器的日志。他还能够和 &lt;code&gt;nginx-ingress&lt;/code&gt; 集成，为上面部署的应用提供域名。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;p&gt;下面是一个用 Draft 把 Python 应用运行到 K8S 集群上的步骤。可以从&lt;a href=&#34;https://github.com/Azure/draft/blob/master/docs/getting-started.md&#34; target=&#34;_blank&#34;&gt;官方文档&lt;/a&gt;获得更详细的指导。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;先决条件&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群（包括 kubectl）&lt;/li&gt;
&lt;li&gt;Helm 客户端&lt;/li&gt;
&lt;li&gt;Draft 客户端&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Docker 镜像库&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ helm init
$ draft init
$ draft config set registry docker.io/myusername
$ git clone https://github.com/Azure/draft
$ cd draft/examples/example-python
$ draft create
$ draft up
## 代码修改
$ draft up
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;用例&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;开发运行在 Kubernetes 上的应用。&lt;/li&gt;
&lt;li&gt;用于在提交到版本控制之前的“内部流程”。&lt;/li&gt;
&lt;li&gt;预 CI：应用完成 Draft 过程之后，可以由 CI/CD 接管。&lt;/li&gt;
&lt;li&gt;不应该用在生产环境部署环节。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;gitkube-https-gitkube-sh-1&#34;&gt;&lt;a href=&#34;https://gitkube.sh/&#34; target=&#34;_blank&#34;&gt;Gitkube&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;使用 git push 构建 Docker 镜像并在 Kubernetes 上进行部署。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gitkube 是一个用来构建 Docker 镜像并向 Kubernetes 上部署的工具，他的起点就是 &lt;code&gt;git push&lt;/code&gt;，不像 Draft，他不需要客户端，只需在集群上独立运行。&lt;/p&gt;

&lt;p&gt;任何带有 Dockerfile 的代码仓库，都可以使用 gitkube 进行部署。Gitkube 安装和部署在集群之上，开发人员可以获取一个包含 git URL 的 CRD。开发人员推送到仓库的代码，会触发集群一端的 Docker Build 以及 Kubectl 发布流程。可以使用 kubectl 或 helm 等类似工具给应用创建应用元数据。&lt;/p&gt;

&lt;p&gt;Gitkube 的重点是即插即用的安装过程，以及沿用既有的知名工具（git 以及 kubectl）。对需要部署的仓库没有什么假设。Docker build 的上下文以及 Dockerfile 所在路径，都可以进行配置。Git 连接认证是通过 SSH 公钥进行的。任何时候代码发生变更、提交和推送，都会触发后面的构建和部署过程。&lt;/p&gt;

&lt;h4 id=&#34;架构-1&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;img/1*n9Il4vKaq9gHC5qQyF-9Tg.png&#34; alt=&#34;Gitkube Architecture&#34; /&gt;&lt;/p&gt;

&lt;p&gt;集群侧有三个组件，一个远程 CRD 可以定义针对一个远端 URL 发生 Push 的时候如何应对，&lt;code&gt;gitkubed&lt;/code&gt; 构建 Docker 镜像并更新部署，&lt;code&gt;gitkube-controller&lt;/code&gt; 会监控 CRD，随变化更新 &lt;code&gt;gitkubed&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;在集群上创建这些对象之后，开发者就可以使用 kubectl 来创建应用的定义了。创建一个 &lt;code&gt;remote&lt;/code&gt; 对象，告诉 gitkube，当 git push 发生时该做什么。Gitkube 把远程 url 写回到 &lt;code&gt;remote&lt;/code&gt; 对象的状态字段中。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes-1&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;先决条件

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群（包括 kubectl）。&lt;/li&gt;
&lt;li&gt;git。&lt;/li&gt;
&lt;li&gt;集群上安装好 gitkube （&lt;code&gt;kubectl create&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下面是将应用提交到 Kubernetes 的步骤，也包含了 gitkube 的安装过程。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;已经过时&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ git clone https://github.com/hasura/gitkube-example
$ cd gitkube-example
$ kubectl create -f k8s.yaml
$ cat ~/.ssh/id_rsa.pub | awk &#39;$0=&amp;quot;  - &amp;quot;$0&#39; &amp;gt;&amp;gt; &amp;quot;remote.yaml&amp;quot;
$ kubectl create -f remote.yaml
$ kubectl get remote example -o json | jq -r &#39;.status.remoteUrl&#39;
$ git remote add example [remoteUrl]
$ git push example master
## 编辑代码
## 提交和推送
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;用例-1&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;使用 Git 进行简单的部署，无需 Docker Build。&lt;/li&gt;
&lt;li&gt;在 Kubernetes 上开发应用。&lt;/li&gt;
&lt;li&gt;开发过程中，WIP 分支可以多次提交，迅速反馈。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;helm-https-helm-sh-1&#34;&gt;&lt;a href=&#34;https://helm.sh/&#34; target=&#34;_blank&#34;&gt;Helm&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubernetes 的包管理系统。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Helm 使用一种称为 &lt;code&gt;Chart&lt;/code&gt; 的形式，来管理 Kubernetes 上的应用。Helm 为应用创建 YAML 并进行版本化操作，这样可以对包含 Deployment 在内的所有对象进行回滚。Chart 可以包含 Deployment、Service 以及 Configmap 等。Chart 的模板允许用户方便的修改部署细节，另外还支持带有依赖关系的复杂应用。&lt;/p&gt;

&lt;p&gt;Helm 的主要目标是在生产环境中部署和管理应用程序。对比 Draft 和 Gitkube，Helm 不是用来开发的，而是用来部署的。另外现在有大量的预构建 &lt;code&gt;Chart&lt;/code&gt; 可以供 Helm 使用。&lt;/p&gt;

&lt;h4 id=&#34;架构-2&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;img/1*Nsme583Ut1TY6IDZjKl27w.png&#34; alt=&#34;Helm architecture&#34; /&gt;&lt;/p&gt;

&lt;p&gt;首先看看 Chart。我们之前说过，Chart 之中包含一系列的信息，这些信息是部署应用到 Kubernetes 中的必要条件。其中可能包含 Deployment、Service、Configmap、Secret 以及 Ingress 等。所有的定义都是以 Yaml 文件模板的形式出现，另外还包含嵌套的依赖 Chart。Chart 可以在 Chart 仓库中发布。&lt;/p&gt;

&lt;p&gt;Helm 有两个主要组件，分别是 Helm 客户端和 Tiller 服务器。客户端用于管理 Chart 和仓库，并且和 Tiller 服务器进行通信，来完成对 Chart 的部署和管理。&lt;/p&gt;

&lt;p&gt;Tiller 组件运行在集群上，和 Kubernetes API 服务器打交道，进行对象的实际操作。&lt;/p&gt;

&lt;p&gt;Helm 不处理源码，用户需要使用 CI/CD 系统来构建镜像，然后用 Helm 来部署合适的镜像。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes-2&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;先决条件

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群&lt;/li&gt;
&lt;li&gt;Helm 客户端&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;接下来是一个在 Kubernetes 集群上使用 Helm 部署 Wordpress 博客的例子：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ helm init
$ helm repo update
$ helm install stable/wordpress
## 更新版本
$ helm upgrade [release-name] [chart-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;用例-2&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;打包：包含多个 Kubernetes 对象的复杂应用可以集中在一起。&lt;/li&gt;
&lt;li&gt;可复用的 Chart 仓库。&lt;/li&gt;
&lt;li&gt;可以轻易部署在多个环境上。&lt;/li&gt;
&lt;li&gt;可嵌套的结构，能够解决依赖关系。&lt;/li&gt;
&lt;li&gt;参数化的模板。&lt;/li&gt;
&lt;li&gt;容易复用。&lt;/li&gt;
&lt;li&gt;持续交付的最后一公里。&lt;/li&gt;
&lt;li&gt;只能部署已经构建完成的镜像。&lt;/li&gt;
&lt;li&gt;具备生命周期管理能力，可以管理多个 Kubernetes 对象的升级和回滚。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;ksonnet-https-ksonnet-io-1&#34;&gt;&lt;a href=&#34;https://ksonnet.io/&#34; target=&#34;_blank&#34;&gt;Ksonnet&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;一个支持客户按操作的框架，提供可扩展的 Kubernetes 配置。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ksonnet 是为 Kubernetes 定义应用配置的另一种方法。它并没有使用 Kubernetes 世界中常用的 YAML 语言，改用一种称为 Jsonnet 的 JSON 模板语言。Ksonnet 客户端最终会渲染出 YAML 文件并提交给集群。&lt;/p&gt;

&lt;p&gt;这一系统的主要功能就是定义可复用的组件，并利用该工具渐进式的进行程序构建。&lt;/p&gt;

&lt;h4 id=&#34;架构-3&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;img/1*mvkdIs0QOGp8xoTMOacM9g.png&#34; alt=&#34;Ksonnet 架构&#34; /&gt;&lt;/p&gt;

&lt;p&gt;基础的构建单位被称为 &lt;code&gt;part&lt;/code&gt;，&lt;code&gt;part&lt;/code&gt; 可以协作构成 &lt;code&gt;prototype&lt;/code&gt;。一个 &lt;code&gt;prototype&lt;/code&gt; 配合参数之后，就成为了一个 &lt;code&gt;component&lt;/code&gt;，&lt;code&gt;component&lt;/code&gt; 可以聚合在一起，成为一个 &lt;code&gt;application&lt;/code&gt;。&lt;code&gt;application&lt;/code&gt; 可以部署到多个 &lt;code&gt;environment&lt;/code&gt; 之中。&lt;/p&gt;

&lt;p&gt;最基础的流程就是使用 &lt;code&gt;ks init&lt;/code&gt; 命令创建一个应用目录，使用 &lt;code&gt;ks generate&lt;/code&gt; 生成（或者也可以自行编写）&lt;code&gt;component&lt;/code&gt; 的元数据文件，使用 &lt;code&gt;ks apply &amp;lt;env&amp;gt;&lt;/code&gt; 命令可以把应用部署到集群/环境之中。可以用 &lt;code&gt;ks env&lt;/code&gt; 命令来管理不同的环境。&lt;/p&gt;

&lt;p&gt;简而言之，Ksonnet 帮助用户定义和管理应用，他把应用视作一系列使用 Jsonnet 的组件进行管理，并部署在不同的 Kubernetes 集群上。&lt;/p&gt;

&lt;p&gt;跟 Helm 类似，Ksonnet 不和源码发生关系，他是一个使用 Jsonnet 为 Kubernetes 定义应用的工具。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes-3&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;先决条件

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群&lt;/li&gt;
&lt;li&gt;ksonnet 客户端&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;接下来是一个留言板例子：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ ks init
$ ks generate deployed-service guestbook-ui \
     --image gcr.io/heptio-images/ks-guestbook-demo:0.1 \
     --type ClusterIP
$ ks apply default
## 变更
$ ks apply default
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;用例-3&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;使用 Jsonnet 编写配置很有弹性。&lt;/li&gt;
&lt;li&gt;打包：复杂配置可以用匹配组件的方式集成起来。&lt;/li&gt;
&lt;li&gt;可复用的组件和原型库：避免重复。&lt;/li&gt;
&lt;li&gt;方便的多环境部署。&lt;/li&gt;
&lt;li&gt;CD 的最后一步。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;metaparticle-https-metaparticle-io-1&#34;&gt;&lt;a href=&#34;https://metaparticle.io/&#34; target=&#34;_blank&#34;&gt;Metaparticle&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;为容器和 Kubernetes 而生的云原生标准库。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Metaparticle 将自己定位于云原生应用的标准库，他内置了经过验证的分布式系统模式，而开发人员可以用习惯的编程语言通过原语的方式方便的采用这些先进模式。&lt;/p&gt;

&lt;p&gt;他提供了简易的语言接口，帮助用户构建可以容器化并部署到 Kubernetes 上的应用，这些应用会直接兼容负载均衡等基础设施。无需自行编写 Dockerfile 或者 Kubernetes 元数据文件，所有相关内容都在代码中的用原语来体现。&lt;/p&gt;

&lt;p&gt;例如一个 Python Web 应用，可以给 main 函数加入一个叫做 &lt;code&gt;containerize&lt;/code&gt; 的 Decorator（从 metaparticle 中 import）。当执行这段 Python 代码的时候，会构建 Docker 镜像并部署到 Decorator 参数中提到的 Kubernetes 集群上。缺省集群定义来自 kubectl 上下文。所以切换环境就和切换当前上下文是等价的。&lt;/p&gt;

&lt;p&gt;在 NodeJS、Java 以及 .NET 上也提供了类似的原语。另外还正在开发更多的语言支持。&lt;/p&gt;

&lt;h4 id=&#34;架构-4&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;各种语言的 &lt;code&gt;metaparticle&lt;/code&gt; 库都包含所需的原语，绑定了构建 Docker 镜像、推送到私库、创建 Kubenretes yaml 文件并在集群上部署的代码。&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/metaparticle-io/package&#34; target=&#34;_blank&#34;&gt;Metaparticle 包&lt;/a&gt;中内置了各种语言用来构建容器的支持。而 &lt;a href=&#34;https://github.com/metaparticle-io/sync&#34; target=&#34;_blank&#34;&gt;Metaparticle Sync&lt;/a&gt; 则包含了在不同机器上运行的不同容器进行同步的能力。&lt;/p&gt;

&lt;p&gt;目前支持的语言包括：JavaScript/NodeJS、Python、Java 以及 .NET。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes-4&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;先决条件

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群。&lt;/li&gt;
&lt;li&gt;特定语言的 Metaparticle 库。&lt;/li&gt;
&lt;li&gt;Docker。&lt;/li&gt;
&lt;li&gt;Docker 私库。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;一个只包含相关内容的 Python 例子，可以使用这些代码构建 Docker 镜像，并在 Kubernetes 上进行部署。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;@containerize(
    &#39;docker.io/your-docker-user-goes-here&#39;,
    options={
        &#39;ports&#39;: [8080],
        &#39;replicas&#39;: 4,
        &#39;runner&#39;: &#39;metaparticle&#39;,
        &#39;name&#39;: &#39;my-image&#39;,
        &#39;publish&#39;: True
    })
def main():
    Handler = MyHandler
    httpd = SocketServer.TCPServer((&amp;quot;&amp;quot;, port), Handler)
    httpd.serve_forever()
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;用例-4&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;只想开发应用，不想担心 Kubernetes YAML 或者 Dockerfile。&lt;/li&gt;
&lt;li&gt;不想掌握多种工具和文件格式，又想搭上容器和 Kubernetes 快车的开发人员。&lt;/li&gt;
&lt;li&gt;快速开发可复制可负载均衡的服务。&lt;/li&gt;
&lt;li&gt;在多个分布式副本之间进行同步，例如加锁、或者选举操作。&lt;/li&gt;
&lt;li&gt;简单开发云原生模式的应用，例如分片系统。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;skaffold-https-github-com-googlecloudplatform-skaffold-1&#34;&gt;&lt;a href=&#34;https://github.com/GoogleCloudPlatform/skaffold&#34; target=&#34;_blank&#34;&gt;Skaffold&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;简单可重复的 Kubernetes 开发。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Skaffold 能够处理构建镜像、推送镜像以及在 Kubernetes 上进行部署。跟 Gitkube 类似，任何包含 Dockerfile 的目录都可以用 Skaffold 部署到 kubernetes 集群上。&lt;/p&gt;

&lt;p&gt;Skaffold 会在本地构建 Docker 镜像，推送到私库，然后使用 &lt;code&gt;skaffold&lt;/code&gt; 客户端进行部署。他还会监测目录，如此一来，目录中的代码一旦发生变化，就会触发重新构建和部署。这个过程还会从容器中获取日志。&lt;/p&gt;

&lt;p&gt;可以使用 YAML 文件来构建、推送、部署的 Pipeline，所以开发者可以混合使用合适的工具，例如 Docker build 和 Google Container Builder，Kubectl 和 Helm 等。&lt;/p&gt;

&lt;h4 id=&#34;架构-5&#34;&gt;架构&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;img/1*elRwOUeoOJvGOK9JdHZIrA.png&#34; alt=&#34;Skaffold 概览&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Skaffold 客户端做了所有的工作。他会查找一个叫做 &lt;code&gt;skaffold.yaml&lt;/code&gt; 的文件，其中包含了必须完成的任务。一个典型的例子就是在 &lt;code&gt;skaffold dev&lt;/code&gt; 运行的目录中查找 Dockerfile 构建 Docker 镜像，并使用 sha256 进行标记，推送镜像，把镜像设置到 Kubernetes 元数据文件之中，最后发布到集群上。这一系列动作会被目录中的变更所触发。来自部署容器的日志会出现在同一个 Watch 窗口中。&lt;/p&gt;

&lt;p&gt;Skaffold 和 Draft 和 Gitkube 很像，但是更具弹性，如上图所示，他能管理不同的“构建-推送-部署”流程。&lt;/p&gt;

&lt;h4 id=&#34;从-0-到-kubernetes-5&#34;&gt;从 0 到 Kubernetes&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;先决条件

&lt;ul&gt;
&lt;li&gt;Kubernetes 集群&lt;/li&gt;
&lt;li&gt;Skaffold 客户端&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Docker 镜像库&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下面的步骤，部署一个 Go 编写的 Hello World 应用：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ git clone https://github.com/GoogleCloudPlatform/skaffold
$ cd examples/getting-started
## 编辑 skaffold.yaml，加入 Docker 仓库
$ skaffold dev
## 打开新终端: 编辑代码
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;用例-5&#34;&gt;用例&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;方便部署。&lt;/li&gt;
&lt;li&gt;迭代构建——持续的构建-发布流程。&lt;/li&gt;
&lt;li&gt;为 Kubernetes 开发应用。&lt;/li&gt;
&lt;li&gt;在 CICD 流程中定义“构建-推送-部署”流程。&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
