<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kubernetes | Liao Lile</title>
    <link>https://liaolile.com/tag/kubernetes/</link>
      <atom:link href="https://liaolile.com/tag/kubernetes/index.xml" rel="self" type="application/rss+xml" />
    <description>Kubernetes</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>zh-Hans</language><lastBuildDate>Sun, 29 May 2022 12:23:10 +0000</lastBuildDate>
    <image>
      <url>https://liaolile.com/media/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_3.png</url>
      <title>Kubernetes</title>
      <link>https://liaolile.com/tag/kubernetes/</link>
    </image>
    
    <item>
      <title>Kubernetes</title>
      <link>https://liaolile.com/post/tech/cloudnative/kubernetes/</link>
      <pubDate>Sun, 29 May 2022 12:23:10 +0000</pubDate>
      <guid>https://liaolile.com/post/tech/cloudnative/kubernetes/</guid>
      <description>&lt;h3 id=&#34;0-kubernetes是什么&#34;&gt;0. Kubernetes是什么&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Kubernetes(K8s)&lt;/strong&gt; is a portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kubernetes为云原生应用提供了定义规范。&lt;/p&gt;
&lt;p&gt;Kubernetes 已经成为云时代的操作系统。我们可以对比一下经典的 Linux 和 Kubernetes 的概念模型，他们都是定义了开放的、标准化的访问接口；该通用API接口在类Unix下称为POSIX&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;Portable Operating System Interface&lt;/strong&gt; (&lt;strong&gt;POSIX&lt;/strong&gt;) is a family of &lt;a href=&#34;https://en.wikipedia.org/wiki/Standardization&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;standards&lt;/a&gt; specified by the &lt;a href=&#34;https://en.wikipedia.org/wiki/IEEE_Computer_Society&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;IEEE Computer Society&lt;/a&gt; for maintaining compatibility between &lt;a href=&#34;https://en.wikipedia.org/wiki/Operating_system&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;operating systems&lt;/a&gt;.  POSIX defines both the system- and user-level &lt;a href=&#34;https://en.wikipedia.org/wiki/Application_programming_interface&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;application programming interfaces&lt;/a&gt; (API), along with command line &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix_shell&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;shells&lt;/a&gt; and utility interfaces, for software compatibility (portability) with variants of &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Unix&lt;/a&gt; and other operating systems.POSIX is also a &lt;a href=&#34;https://en.wikipedia.org/wiki/Trademark&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;trademark&lt;/a&gt; of the IEEE. POSIX is intended to be used by both application and system developers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kubernetes定义了云的分布式系统的API。如下是linux同kubernetes之间的类比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;Linux&lt;/th&gt;
&lt;th&gt;Kubernetes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;隔离单元&lt;/td&gt;
&lt;td&gt;进程&lt;/td&gt;
&lt;td&gt;Pod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;硬件&lt;/td&gt;
&lt;td&gt;虚拟机/物理机&lt;/td&gt;
&lt;td&gt;数据中心&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并发单元&lt;/td&gt;
&lt;td&gt;线程&lt;/td&gt;
&lt;td&gt;容器进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;资源管理&lt;/td&gt;
&lt;td&gt;进程内存及CPU&lt;/td&gt;
&lt;td&gt;内存、CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;存储&lt;/td&gt;
&lt;td&gt;文件&lt;/td&gt;
&lt;td&gt;ConfigMap，Secrete，Volumn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;网络&lt;/td&gt;
&lt;td&gt;访问端口&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;终端控制台&lt;/td&gt;
&lt;td&gt;shell，bash&lt;/td&gt;
&lt;td&gt;kubectl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;网络安全&lt;/td&gt;
&lt;td&gt;Iptables&lt;/td&gt;
&lt;td&gt;NetworkPolicy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;权限管理&lt;/td&gt;
&lt;td&gt;用户、文件权限&lt;/td&gt;
&lt;td&gt;UserAccount，ServiceAccount，RBAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Linux和kubernetes作为操作系统，体现在向下封装资源，向上支撑应用。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/06/04/s6pCo18ZjVHDt2Y.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;它们都提供了对底层计算、存储、网络、异构计算设备的资源抽象和安全访问模型。可以根据应用需求进行资源调度和编排。Linux 的计算调度单元是进程，调度范围限制在一台计算节点。而 Kubernetes 的调度单位是 Pod，可以在分布式集群中进行资源调度，甚至跨越不同的云环境。其主要业务是调度和管理容器服务。&lt;/p&gt;
&lt;h3 id=&#34;1-kubernetes架构&#34;&gt;1. Kubernetes架构&lt;/h3&gt;
&lt;p&gt;一个高层级的Kubernetes架构图如下：分为控制面Master和数据面Node节点池；集群上可以是一主多从和多主多从的架构；&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/04/2tZKCeJ491qjN5y.jpg&#34; style=&#34;zoom: 33%;&#34; /&gt;
&lt;p&gt;Kubernetes 的控制平面包含四个主要的组件：API Server、Controller、Scheduler 以及 etcd。如下是其与数据面的交互图，均通过API server同kubelet交互实现的。同时数据面提供loadbalancer给到终端用户请求。K8s 可以在 IDC、云端、边缘等不同场景进行统一部署和交付。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/06/04/JTma7KdVspOqSFW.png&#34; alt=&#34;img&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id=&#34;11-容器相关概念&#34;&gt;1.1 容器相关概念&lt;/h4&gt;
&lt;p&gt;如下图介绍了Kubernetes以及docker中最核心的一些概念。&lt;/p&gt;
&lt;p&gt;CRI是kubernetes定义的容器运行时接口，具体的实现由两个，一个是来自于docker的containerd，另一个是来自于RedHat的CRI-O。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Docker，Kubernetes 等工具来运行一个容器时会调用容器运行时（CRI）比如 containerd，CRI-O&lt;/li&gt;
&lt;li&gt;通过容器运行时来完成容器的创建、运行、销毁等实际工作&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Docker 使用的是 containerd 作为其运行时；Kubernetes 支持 containerd，CRI-O 等多种容器运行时&lt;/li&gt;
&lt;li&gt;这些容器运行时都遵循了 OCI 规范，并通过 runc 来实现与操作系统内核交互来完成容器的创建和运行&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;CRI（容器运行时接口）是 Kubernetes 用来控制创建和管理容器的不同运行时的 API，它使 Kubernetes 更容易使用不同的容器运行时。它一个插件接口，这意味着任何符合该标准实现的容器运行时都可以被 Kubernetes 所使用。&lt;/li&gt;
&lt;li&gt;OCI 开放容器倡议，是一个由科技公司组成的团体，其目的是围绕容器镜像和运行时创建开放的行业标准。他们维护容器镜像格式的规范，以及容器应该如何运行。&lt;/li&gt;
&lt;li&gt;runc 是轻量级的通用运行时容器，它遵守 OCI 规范，是实现 OCI 接口的最低级别的组件，它与内核交互创建并运行容器。runc 为容器提供了所有的低级功能，与现有的低级 Linux 功能交互，如命名空间和控制组，它使用这些功能来创建和运行容器进程。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体详细内容参考下述图表&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/04/fNnYTSmP4OhJr7U.jpg&#34; alt=&#34;img&#34; style=&#34;zoom:67%;&#34; /&gt;
&lt;h4 id=&#34;12-kubernetes设计理念&#34;&gt;1.2 Kubernetes设计理念&lt;/h4&gt;
&lt;p&gt;Kubernetes 在容器编排中有几个关键设计理念：&lt;/p&gt;
&lt;p&gt;**容错性：**容错性是保证K8s集群系统稳定性和安全性的基础，确保系统不崩溃，不出现业务错误，不做坏事。&lt;/p&gt;
&lt;p&gt;**易扩展性：**易扩展性是保证K8s友好，后续快速迭代增加新功能的基础，让系统可以在用户看到的时间内做好事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;声明式 API&lt;/strong&gt;：开发者可以关注于应用自身，而非系统执行细节。比如 Deployment（无状态应用）、 StatefulSet（有状态应用）、Job（任务类应用）等不同资源类型，提供了对不同类型工作负载的抽象；对 Kubernetes 实现而言，基于声明式 API 的 “level-triggered” 实现比 “edge-triggered” 方式可以提 供更加健壮的分布式系统实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可扩展性架构：&lt;strong&gt;所有 K8s 组件都是基于一致的、开放的 API 实现和交互；三方开发者也可通过 CRD（Custom Resource Definition）/Operator 等方法提供领域相关的扩展实现，极大提升了 K8s 的能力。Operator 是 Kubernetes 里面的一个核心思想，它代表着我的任何一个应用和它所需要的能力都可以定义成为一个 Kubernetes 的 API 对象，通过一个叫做 Controller 的机制让你去使用云的能力，再让你接入到各种各样的基础设施里面。这个 Operator 化带来的一个直接结果就是，我的应用本身是高度自动化的，包括&lt;/strong&gt;自愈、健壮性、可靠性、运行的确定性&lt;/strong&gt;，这些在今天都可以交给 Kubernetes去解决。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可移植性&lt;/strong&gt;：K8s 通过一系列抽象如 Loadbalance Service（负载均衡服务）、CNI（容器网络接口）、CSI（容器存储接口）、CRI（容器运行时接口），帮助业务应用可以屏蔽底层基础设施的实现差异，实现容器灵活迁移的设计目标。&lt;/p&gt;
&lt;h4 id=&#34;13-kubernetes核心概念&#34;&gt;1.3 Kubernetes核心概念&lt;/h4&gt;
&lt;p&gt;Kubernetes中核心对象类型包括：资源对象、配置对象、存储对象、策略对象，详细的对象类别中包含一些核心概念。&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/04/LypNOxkQGh9tC4H.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;
&lt;p&gt;上述对象均可理解为Kubernetes API Objects，每个对象包含三大类属性：&lt;strong&gt;元数据metadata，规范spec和状态status&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;元数据&lt;/code&gt;用来标识对象，至少包含三个元数据：namespace，name，uid；除此一般还有label，可以用来标识和匹配不同的对象；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;规范&lt;/code&gt;描述了用户期望kubernetes集群中分布式系统达到的理想状态；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;状态&lt;/code&gt;描述了当前系统实际达到的状态&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes中所有的配置都是通过API对象的spec去设置的，也就是用户通过配置系统的理想状态来改变系统，所有的API均是声明式的。&lt;/p&gt;
&lt;h5 id=&#34;131-资源对象&#34;&gt;1.3.1 资源对象&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pod&lt;/strong&gt;，Kubernetes中最小的部署应用或服务单元，可以支持部署多容器；同一个Pod中共享网络地址和共享文件，可以通过进程间通信组合完成服务。目前Kubernetes业务主要包括：long-running、batch、node-deamon、stateful application，分别对应的控制器为Deployment，Job，DeamonSet，StatufulSet。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**Deployment **，表示对集群的Kubernetes的一次更新操作，比RS应用模式更广的API对象，可以是创建一个新的服务，更新一个新的服务，也可以是滚动升级一个服务。滚动升级实际是创建一个新的RS，逐步增加到理想的副本个数，旧的RS逐步减小到0的符合操作；以 Kubernetes 的发展方向，未来对所有长期伺服型的的业务的管理，都会通过 Deployment 来管理。Master 节点的中有一个子系统叫做 Deployment Controller，负责实际执行并使当前状态不断趋向于所需状态。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Replication Controller&lt;/strong&gt;， 副本控制器RC, 用来保证Pod高可用的API对象，通过监控运行中的Pod个数来保证集群中运行指定数目的Pod副本。RC是Kubernetes早期技术概念，只适用于long-running业务类型，目前已经使用RS替代。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Replica Set&lt;/strong&gt;， 副本集 RS，RS是新一代RC，提供同样高可用能力，支持更多种类的匹配模式，副本集对象一般不单独使用，而是作为Deployment的理想状态参数使用。ReplicaSet 是管理 pod 生命周期的组件，监控活动副本，当收到指令时或 pod 离线或意外停止时启动 pod，也会在收到指示时杀死 pod，也许是因为用户负载减少。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Job&lt;/strong&gt;, Job是K8s中用来控制批任务的API对象。Job管理Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不同的spec.completions策略而不同；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deamon Set&lt;/strong&gt;，后台服务集，重点关注K8s中的节点，确保每个节点上均有此类Pod（包括存储、日志、监控等）运行。节点可能是所有集群节点，也可能是通过NodeSelector选定的一些特定节点。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;StatefulSet&lt;/strong&gt;，有状态服务集，RC和RS主要控制的是无状态服务集，其所控制的Pod名字是随机设置的，1个Pod出故障了就被丢弃了，而另个地方重启的Pod名字就变了。对于无状态服务集重要的是数量，而不是名字和在哪。StatefulSet中每个Pod的名字都是事先确定的，不能改变的，用于后续关联Pod的状态。StatefulSet中的Pod每个独立挂载自己的独立存储，Pod出现故障后，还得挂载上原来的存储继续提供有状态服务；StatefuleSet做的事情是将确定的Pod和确定的存储关联起来保证状态的连续性。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;132-配置对象&#34;&gt;1.3.2 配置对象&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Node节点&lt;/strong&gt;, K8s中的计算能力，是所有Pod运行所在的工作主机，可以是物理机也可以是虚拟机，均需要基于kubelet管理节点上的容器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Service服务&lt;/strong&gt;， RC/RS/Deployment只是保证了Pod的数量，没有解决如何访问这些服务的问题。由于Pod的调度机制决定了服务实例不能以确定的IP和端口来提供服务，需要依赖服务端的服务发现和负载均衡能力。在K8s内部，客户端需要访问的服务就是Service对象，每个Service对象都会有一个集群内部的虚拟IP，集群内部通过虚拟IP访问服务；Kube-proxy是K8s中的负载均衡器，在K8s的每个节点上都有一个，这是一个分布式的代理服务，需要访问的节点服务越多，提供负载均衡能力的kube-proxy就越多，高可用节点也越多。 另外，Service 是一组逻辑上的 pod分组，对提供同一个服务的多个Pod进行聚合；它提供了一个单一的虚拟的Cluster IP 地址和 DNS 名称，后端对应1个或多个提供服务的Pod，你可以通过它访问服务内的所有 pod。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secrete 密钥对象&lt;/strong&gt;， 用来保存和传递密码、密钥、认证凭据等敏感信息。在对应的配置文件中通过Secrete对象应用敏感信息。这种方式的好处是：意图明确，避免重复，减少暴露机会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UserAccount用户账户 &amp;amp; ServiceAccount服务庄户&lt;/strong&gt;, 用户账户为个人提供账户标识，服务账户为计算机进程和K8s集群中运行的Pod提供账户标识。用户账户与下述的服务命名空间无关，而服务账号的是运行绑定在某个命名空间下的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Namespace命名空间&lt;/strong&gt;，提供集群虚拟的集群隔离作用，K8s初始由两个命名空间，1个是默认命名空间default，1个是系统命名空间kube-system。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ingress/Egress&lt;/strong&gt;，Kubernetes pod 的流量称为 Ingress，而从 pod 到集群外的出站流量称为 Egress。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom Resource Definition&lt;/strong&gt;, CRD自定义的资源对象，需要满足K8s API定义规范；
&lt;ul&gt;
&lt;li&gt;apiVersion，自定义资源对象的版本号&lt;/li&gt;
&lt;li&gt;Kind，自定义资源对象的名称，用户可以通过kubectl get ${kind_name}来获取对应的资源对象&lt;/li&gt;
&lt;li&gt;Metadata，继承了原生的K8s的metadata，用于添加lable/annotation等元数据&lt;/li&gt;
&lt;li&gt;Spec，可自定义设计的服务配置参数，如镜像版本号，节点数据量等&lt;/li&gt;
&lt;li&gt;Status，定义资源的相关状态&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;133-存储对象&#34;&gt;1.3.3 存储对象&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Volumn存储卷&lt;/strong&gt;, Docker存储卷作用范围为一个容器，而K8s的存储卷作用范围为一个Pod，每个Pod申请的卷由Pod中所有容器共享。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PersistentVolumn&lt;/strong&gt;持久存储卷 &amp;amp; &lt;strong&gt;PersistentVolumnClaim&lt;/strong&gt;持久存储卷声明， PV和PVC使K8s具有存储的逻辑抽象能力，使得配置Pod的存储卷时候可以忽略对应的存储技术配置。PV和PVC的关系类比于计算的Node和Pod，PV和Node是资源提供者，PVC和Pod是资源使用者。&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;134-策略对象&#34;&gt;1.3.4 策略对象&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Federation集群联邦&lt;/strong&gt;， K8s最初的设计是单一集群在同一个地域内，同一个地区的网络性能才能满足K8s调度和计算存储连接要求。Federation就是让K8s有跨Region和跨服务商的能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RBAC访问授权&lt;/strong&gt;，RBAC中引入角色Role和角色绑定RoleBinding，访问策略是可以和某个角色绑定，具体的用户再和1个或多个角色绑定；&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;14-kubernetes和服务网格servicemesh&#34;&gt;1.4 Kubernetes和服务网格ServiceMesh&lt;/h4&gt;
&lt;p&gt;将应用程序的功能划分为单独的进程运行在同一个最小调度单元中（例如 Kubernetes 中的 Pod）可以被视为 &lt;strong&gt;sidecar 模式&lt;/strong&gt;。如下图所示，sidecar 模式允许您在应用程序旁边添加更多功能，而无需额外第三方组件配置或修改应用程序代码。而通过sidecar模式的组网即为服务网格架构形态。Sidecar 应用与主应用程序松散耦合。它可以屏蔽不同编程语言的差异，统一实现微服务的可观测性、监控、日志记录、配置、断路器等功能。&lt;/p&gt;
&lt;p&gt;中间件实际上是大量的通过 Sidecar 方式去被使用到的，所以我的应用本身不需要再去引入一个库，或者引入一个特定的框架来去做很多事情，我甚至都不需要感知。应用跟云的交互，就通过一个叫 Sidecar 的一个旁路容器，让这个容器去代理应用本身所需要的进出流量，所以云就可以非常容易地通过这样一个代理，调节流量、做流量切分、网络管控，这就是非常简单的 Service Mesh 的原理。如下是两种形态的Sidecar模式。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/06/04/izHEBdmqC3rNkZ8.png&#34; alt=&#34;img&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;使用容器作为Service和Sidecar进程的承载；&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/06/04/uHVP5LsACQvYktd.png&#34; alt=&#34;img&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;使用Function作为Servcie和Sidecar逻辑的承载；&lt;/p&gt;
&lt;h3 id=&#34;2-kubernetes原理机制&#34;&gt;2. Kubernetes原理机制&lt;/h3&gt;
&lt;h4 id=&#34;21-kubernetes服务之间通信&#34;&gt;2.1 Kubernetes服务之间通信&lt;/h4&gt;
&lt;h5 id=&#34;211-clusterip&#34;&gt;2.1.1 ClusterIp&lt;/h5&gt;
&lt;p&gt;在K8s中，Service对应提供一个虚拟的ClusterIp，通过ClusterIp即可访问到服务对应的Pod。而负责这一转发的模块是Kube-proxy。在该场景下，ClusterIp和PodId都是K8s集群内部的访问地址；&lt;/p&gt;
&lt;p&gt;Kube-proxy是一个运行在K8s每个节点上的Go应用程序，支持三种工作模式：userspace、iptables、ipvs。后端选择pod进行转发的时候依赖Label Selector。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;userspace&lt;/p&gt;
&lt;p&gt;该模式下kubep-proxy为每个service创建一个监听端口，发向ClusterIp的请求被iptables规则重定向到Kuber-proxy监听的端口上，Kube-proxy依据LB算法选择一个服务的Pod进行请求转发。该模式下，Kube-proxy是4层loadbalancer。但是由于在用户空间，数据拷贝效率较低。后端Pod不可用时，kube-proxy会重试其他的pod。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​		&lt;img src=&#34;https://s2.loli.net/2022/06/13/b9uRs8KvqFeIPUH.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;iptables&lt;/p&gt;
&lt;p&gt;kube-proxy为service后端的每个pod创建对应的iptables规则，直接将发向ClusterIp的请求重定向到一个Pod Ip。该场景下，避免了数据的用户空间和内核空间的拷贝，kube-proxy不充当4层负载均衡，而只负责创建iptables规则。但是当后端pod故障后，无法进行重试；&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/13/XoxSaHyWi4UgmkQ.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ipvs&lt;/p&gt;
&lt;p&gt;kube-proxy监控pod的变化并且创建对应的ipvs rules。ipvs是在kernel模式下通过netfilter实现，采用hash table存储规则，支持更多的loadbalance的算法，依赖在操作系统中安装ipvs内核模块。&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/13/RdfguQyJe6DEFnz.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;212-nodeport&#34;&gt;2.1.2 NodePort&lt;/h5&gt;
&lt;p&gt;NodePort在集群中的主机节点上为Servcie提供一个代理端口，允许从主机网络对Service进行访问。&lt;/p&gt;
&lt;p&gt;在创建NodePort时，kube-proxy也会同时为Service创建Cluster Ip相关的iptables规则，kube-proxy并不不会直接接受主机的端口进入的流量，而是创建相应的iptables规则，通过从该带瘤端口收到的流量直接转发到后端的Pod中。&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/13/OQMLzIygXrJE7da.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;
&lt;h5 id=&#34;213-loadbalancer&#34;&gt;2.1.3 LoadBalancer&lt;/h5&gt;
&lt;p&gt;K8s支持将Service定义为LoadBalancer类型；LoadBalancer类型的Service创建后，Cloud Provider Controller会将配置下发到Cloud Provider网络中的&lt;strong&gt;四层负载均衡器&lt;/strong&gt;，该负载均衡器负责将外部的流量分发到后面多个节点的NodePort端口上。也就是说外部流量需要依赖NodePort端口才能把流量转发到K8s内部。而LoadBalancer需要依赖各个云服务商提供支持。&lt;/p&gt;
&lt;h5 id=&#34;214-ingress&#34;&gt;2.1.4 Ingress&lt;/h5&gt;
&lt;p&gt;当一个应用需要对外提供多个服务时，需要借用Kubernetes Ingress来统一网络入口。其声明了一个应用层的负载均衡器，可以根据HTTP请求的内容将来自同一个TCP端口的请求分发到不同的Kubernetes Service。支持按Http URL进行路由，同时也支持按照请求的Host进行路由。&lt;/p&gt;
&lt;p&gt;Kubernetes使用Ingress Controller来监控Ingress规则，并通过一个七层网关来实现这些要求，一般可以使用Nginx，HAProxy等；由于Ingress是不是在K8s集群中，对外部流量来说，需要配合NodePort和LoadBalancer才能提供对外的流量入口。&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/13/tPm73usSKd21DUp.jpg&#34; style=&#34;zoom:33%;&#34; /&gt;
&lt;p&gt;在NodePort，Ingress，Pod等不同的接入层面都可以对系统进行水平扩展，以应对不同的外部流量要求。详细的局部细节图如下：&lt;/p&gt;
&lt;img src=&#34;https://s2.loli.net/2022/06/13/oAVIRh3PYZHWxpy.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;
&lt;p&gt;&lt;strong&gt;REFERENCE&lt;/strong&gt;:&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/POSIX&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;POSIX - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://zhuanlan.zhihu.com/p/490585683&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker，containerd，CRI，CRI-O，OCI，runc 分不清？看这一篇就够了 - 知乎 (zhihu.com)&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Kubernetes上的分布式系统</title>
      <link>https://liaolile.com/post/tech/distributesystem/kubernetes%E4%B8%8A%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E7%BB%9F/</link>
      <pubDate>Sat, 28 May 2022 16:23:10 +0000</pubDate>
      <guid>https://liaolile.com/post/tech/distributesystem/kubernetes%E4%B8%8A%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E7%BB%9F/</guid>
      <description>&lt;p&gt;分布式系统不仅仅是运行时，还是&lt;strong&gt;开发时、构建时、运维时&lt;/strong&gt;；分布式系统需要4个方面的能力，包括生命周期的管理、网络通讯能力、资源绑定能力以及有状态逻辑的处理。&lt;/p&gt;
&lt;p&gt;系统的生命周期能力，我们需要一个可靠且&lt;strong&gt;全自动化的打包和部署、回滚、健康检查&lt;/strong&gt;。能够实现应用在不同节点的分发，且资源隔离、扩展、配置可管理。这些能力就是第一位的基础。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/09/12/RQO89TrqgJL2C4B.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;网络的连接能力&lt;/strong&gt;是分布式系统的第二要素。可靠韧性的连接到其他的服务，无论集群内还是集群外，分布式系统预期有服务发现、负载均衡等能力。同时由于不同的流量策略，需要具备流量转移的能力。服务的韧性在网络方面体现在超时重试、断路器等。围绕网络还要有安全保障，足够的监控、追踪和可观察性。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/08/03/rDEnmNFXhZcy3Kz.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;分布式系统的有能力与不同的API和端点交互，即&lt;strong&gt;资源绑定与其协议不同的数据格式交互&lt;/strong&gt;，甚至从一种数据格式到另外一种数据格式的转换。对于消息数据的点对点pub/sub交互，以及数据的过滤，数据的路由；&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/08/03/CHJf8shcnWpGUIk.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;关于&lt;strong&gt;依赖状态&lt;/strong&gt;的开发人员抽象，分布式系统需要有工作流的管理能力，管理长进程以及短周期的调度任务，依赖分布式缓存，需要具有幂等性和支持回滚。这些均需要考虑系的同内部的已有状态的处理，依赖于开发人员的抽象。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/09/12/noBu75Wh3dNAxOY.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;技术架构的演进从单体到微服务再到云原生架构；&lt;/p&gt;
&lt;p&gt;按照业务领域进行划分出现了微服务，容器和Kubernetes是管理这些微服务的优秀平台。Readiness和Liveness探测在kubernetes对于容器的生命周期管理至关重要，一个是确定应用在启动期间何时可以接受外部流量，一个是检查服务的健康状况；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LivenessProbe，判断容器是否存活running状态，如果不健康会kill后重启处理；&lt;/li&gt;
&lt;li&gt;ReadinessProbe，判断容器服务是否可用ready状态，ready后的pod才接受来自外部的数据。Service同Pod Endpoint之间的关联关系基于该Pod的Ready状态进行设置；&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&#34;D:\0_leland\blog\blog-image\distributed\distributedSystem-architectrue-history.png&#34; style=&#34;zoom:80%;&#34; /&gt;
&lt;p&gt;Kubernetes 可以启动你的应用；它可以将其关闭，然后在不同的节点上移动它。为此，你必须正确执行平台在应用启动和关闭期间告诉你的事件。围绕声明式部署，声明资源需求，部署策略，应用程序同时需要执行来自环境的事件（健康检查、应用就绪度等）；实现整个部署的资源隔离、配置管理、故障隔离；&lt;/p&gt;
&lt;p&gt;Kubernetes中的Pod有两个约束：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod的部署会确保所有的容器均在同一个节点；各个容器间可以通过localhost进行通信，也可以通过其他的类似文件共享/IPC机制等；&lt;/li&gt;
&lt;li&gt;Pod中的容器生命周期可以不同，分为Init容器和应用容器，Pod启动时，Init容器按顺序一个一个运行，仅前一个成功后一个才运行；应用容器是并行运行的，在整个Pod生命周期中运行；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;K8s内部依赖调谐循环来确保状态和声明一致，将期望的状态驱动到与实际状态。&lt;/p&gt;
&lt;h4 id=&#34;ref&#34;&gt;REF&lt;/h4&gt;
</description>
    </item>
    
  </channel>
</rss>
