mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-11-18 23:23:44 +08:00
fix img
This commit is contained in:
@@ -179,7 +179,7 @@ function hide_canvas() {
|
||||
<li>cri-o,容器运行时管理进程,类似 Docker 管理工具 containerd,国内业界普遍使用 containerd。</li>
|
||||
</ul>
|
||||
<p>我们可以用如下一张架构设计图更能深刻理解和快速掌握 Kubernetes 的核心组件的布局:</p>
|
||||
<p><img src="assets/95b9e530-d605-11ea-855e-35d62ffd230b.jpg" alt="1-1-k8s-arch" /></p>
|
||||
<p><img src="assets/95b9e530-d605-11ea-855e-35d62ffd230b.jpg" alt="png" /></p>
|
||||
<p>通过以上的介绍,核心组件的基本知识就这么多。从最近几年落地 Kubernetes 云原生技术的用户反馈来看,大家仍然觉得这套系统太复杂,不太好管理,并且随时担心系统给业务带来致命性的影响。</p>
|
||||
<p>那么 Kubernetes 的组件是为分布式系统设计的,为什么大家还是担心它会影响业务系统的稳定性呢?从笔者接触到的用户来讲,业界并没有统一的可以直接参考的解决方案。大家在落地过程中,只能去摸石头过河,一点一点总结经验并在迭代中不断地改进实施方案。因为业务规模的不同,Kubernetes 实施的架构也完全不同,你很难让基础设施的一致性在全部的商业企业 IT 环境中保持一致性。业务传播的都是最佳实践,在 A 用户这里可以行的通,不代表在 B 用户可以实施下去。</p>
|
||||
<p>当然,除了客观的限制因素之外,我们应用 Kubernetes 的初衷是尽量的保持企业的 IT 基础设施的一致性,并随着企业业务需求的增长而弹性扩展。毕竟 Kubernetes 是谷歌基于内部 Borg 应用管理系统成功经验的基础之上开源的容器编排系统,它的发展积累了整个业界的经验精华,所以目前企业在做数字转型的阶段,都在无脑的切换到这套新的环境中,生怕技术落后影响了业务的发展。</p>
|
||||
@@ -210,23 +210,23 @@ function hide_canvas() {
|
||||
<p>但是往往这种潜在的小问题,就是让你很烦恼并对长时间无法重现感到烦恼。那么对于系统进程,Linux 是有对应的系统维护工具 Systemd 来维护的。它的生态足够完善,并能在多种 Linux 环境中保持行为一致。当出现问题的时候,运维可以直接登录主机快速排查系统日志来定位排错。根据这样的经验积累,笔者推荐生产环境还是采用原生进程的方式来维护 Kubernetes 的组件,让运维可以集中精力在集群架构上多做冗余优化。</p>
|
||||
<p>接下来我们重新理解 etcd 集群的架构。根据 Kubernetes 官方文档的参考资料介绍,通常按照 etcd 集群的拓扑模型可以分为两类生产级别的 Kubernetes 集群。</p>
|
||||
<p>栈式 etcd 集群拓扑:</p>
|
||||
<p><img src="assets/9c01f2f0-d607-11ea-8ff5-1f2baade933b.jpg" alt="kubeadm-ha-topology-stacked-etcd" /></p>
|
||||
<p><img src="assets/9c01f2f0-d607-11ea-8ff5-1f2baade933b.jpg" alt="png" /></p>
|
||||
<p>独立式 etcd 集群拓扑:</p>
|
||||
<p><img src="assets/639579f0-d611-11ea-8e3d-27a3708e9ea4.jpg" alt="kubeadm-ha-topology-external-etcd" /></p>
|
||||
<p><img src="assets/639579f0-d611-11ea-8e3d-27a3708e9ea4.jpg" alt="png" /></p>
|
||||
<p>参考上面的架构图,我们可以看到 etcd 集群的部署方式影响着 Kubernetes 集群的规模。在落地实践中因为采购的机器都是高性能大内存的刀片服务器,业务部门的期望是能充分的把这些资源利用上,并不期望用这些机器来跑集群控制管理组件。</p>
|
||||
<p>当遇到这种情况,很多部署方案会采用第一种方案,是把主机节点、工作节点和 etcd 集群都放在一起复用资源。从高可用架构来讲,高度的应用密度集合并不能给用户带来无限制的好处。试想当出现节点宕机后这种架构的隐患是业务应用会受到极大的影响。所以通常的高可用架构经验是工作节点一定要和主控节点分开部署。在虚拟化混合环境下,主控节点可以使用小型的虚拟机来部署最为合适。当你的基础设施完全采用物理机的时候,直接使用物理机来部署主控节点是很浪费的,建议在现有物理机集群中先使用虚拟化软件虚拟化一批中小型虚拟机来提供管理节点的管理资源。开源的管理系统有 OpenStack,商业的方案是 VMware vSphere,按需求丰俭由人即可。</p>
|
||||
<p>除了以上标准的部署解决方案,社区还提供了单机模式部署的 K3s 集群模式。把核心组件直接绑定为一个单体二进制文件,这样的好处就是这个系统进程只有一个,非常容易管理和恢复集群。在纯物理机环境,使用这种单点集群架构来部署应用,我们可以通过冗余部署多套集群的方式来支持应用的高可用和容灾。下图就是 K3s 的具体架构图:</p>
|
||||
<p><img src="assets/814b8660-d611-11ea-8a86-ed86f9ad27de.jpg" alt="k3s-arch" /></p>
|
||||
<p><img src="assets/814b8660-d611-11ea-8a86-ed86f9ad27de.jpg" alt="png" /></p>
|
||||
<p>K3s 本来是为嵌入式环境提供的精简 Kubernetes 集群,但是这个不妨碍我们在生产实践中灵活运用。K3s 提供的是原生 Kubernetes 的所有稳定版本 API 接口,在 x86 集群下可以发挥同样的编排容器业务的能力。</p>
|
||||
<h3>工作节点组件的使用策略</h3>
|
||||
<p>在工作节点上默认安装的组件是 kubelet 和 kube-proxy。在实际部署的过程中,kubelet 是有很多配置项需要调优的,这些参数会根据业务需求来调整,并不具备完全一样的配置方案。让我们再次认识一下 kubelet 组件,对于 kubelet,它是用来启动 Pod 的控制管理进程。虽然 kubelet 总体启动容器的工作流程,但是具体的操作它是依赖主机层面的容器引擎来管理的。对于依赖的容器引擎,我们可以选择的组件有 containerd、ori-o 等。Kubernetes 默认配置的组件是 cri-o。但是业界实际落地部署最多的还是 containerd,因为它的部署量巨大,很多潜在的问题都会被第一时间解决。containerd 是从 docker 引擎抽离出来的容器管理工具,用户具备长期的使用经验,这些经验对于运维和管理容器会带来很多潜在的使用信心。</p>
|
||||
<p><img src="assets/9da05520-d611-11ea-8ff5-1f2baade933b.jpg" alt="containerd-plugin" /></p>
|
||||
<p><img src="assets/9da05520-d611-11ea-8ff5-1f2baade933b.jpg" alt="png" /></p>
|
||||
<p>对于容器实例的维护,我们常用的命令行工具是 Docker,在切换到 containerd 之后,命令行工具就切换为 ctr 和 crictl。很多时候用户无法搞清楚这两个工具的用处,并和 Docker 混为一谈。</p>
|
||||
<p>Docker 可以理解为单机上运行容器的最全面的开发管理工具,这个不用多介绍,大家都了解。ctr 是 containerd 的客户端级别的命令行工具,主要的能力是管理运行中的容器。crictl 这个工具是管理 CRI 运行时环境的,在上图中是操作 cri-containerd 的组件。它的功能主要聚焦在 Pod 层面的镜像加载和运行。</p>
|
||||
<p>还请大家注意下 Docker、ctr、crictl 三者细节实现上的差别。举个例子,Docker 和 ctr 确实都是管理主机层面的镜像和容器的,但是他们都有自己独立的管理目录,所以你即使是同样的加载镜像的操作,在主机存储的文件位置也是不同的,他们的镜像层无法复用。而 crictl 是操作 Pod 的,它并不是直接操作镜像的进程,一般把命令发送给对应的镜像管理程序,比如 containerd 进程。</p>
|
||||
<p>另外一个组件是 kube-proxy,它是面向 Service 对象概念的南北向反向代理服务。通过对接 Endpoint 对象,可以按照均衡策略来负载流量。另外为了实现集群全局的服务发现机制,每一个服务都会定义全局唯一的名字,也就是 Service 的名字。这个名字可以通过附加的组件 coredns 来实现集群内的名字解析,也就是服务发现。对于流量的负载,Kubernetes 是通过 iptables 或 IPVS(IP Virtual Server)来实现。</p>
|
||||
<p>在正常的集群规模下,Service 并不会超过 500 个,但是华为容器技术团队做了一个极限压测,发现了 iptables 在实现反向代理的时候出现的性能瓶颈。试验验证了,当 Service 增加到足够大的时候,Service 规则增加对于 iptables 是 O(n) 的复杂度,而切换到 IPVS 却是 O(1)。压测结果如下:</p>
|
||||
<p><img src="assets/0885a380-d613-11ea-8ff5-1f2baade933b.jpg" alt="ipvs-iptables-perf" /></p>
|
||||
<p><img src="assets/0885a380-d613-11ea-8ff5-1f2baade933b.jpg" alt="png" /></p>
|
||||
<p>目前 Kubernetes 默认反向代理激活模块为 IPVS 模式,iptables 和 IPVS 都是基于 Linux 的子模块 netfilter,他们的相同点就是做反向代理,但是还是有以下 3 点区别需要知道:</p>
|
||||
<ul>
|
||||
<li>IPVS 提供大规模集群扩展性和高性能</li>
|
||||
|
||||
Reference in New Issue
Block a user