08-Kubernetes冰山揭秘-第七层
Kubernetes就像一座冰山。你学习了基础知识,却发现还有很多东西要学。你学得越多,你看到的就越多。这篇文章解释了Reddit上“Kubernetes冰山”模因中列出的所有概念。
不久前,u/dshurupov published a picture on Reddit上发布了一张我称之为“Kubernetes冰山”的照片。这张照片是由弗兰特的人制作的。
它代表了一座巨大的冰山,在上面你有一些最简单的Kubernetes概念,当你在下面和水下时,你会深入到更先进的Kubernetes主题。这是图片:
Node’s OS configuration
Kubernetes节点是运行OS(通常是Linux)的虚拟或物理机器。
Kubernetes管理节点,并在节点健康的情况下为其分配豆荚。
Kubernetes节点的配置方式与配置任何其他机器的方式相同。
不同的Kubernetes提供程序提供不同的配置方式。
大多数提供程序(GKE、AKS)允许您创建用于创建节点的配置文件。这些配置文件包含各种内容,如CPU限制、文件处理限制、OS阈值等。
Spot instances
Spot实例是云提供商提供的一个具有成本效益的特性。它允许您以较低的价格请求未使用的虚拟机实例。
您可以设置您准备为VM支付的最高价格;如果有,一个将提供给你。如果价格上涨,虚拟机将被停止并分配给其他人。
使用spot实例必须谨慎,因为您随时可能丢失实例。
Spot instances and Kubernetes
虽然对于生产工作负载来说并不完全可靠,但spot实例可以很好地与Kubernetes一起工作。
之所以如此,是因为Kubernetes最适合弹性的、无状态的工作负载,如果一个节点下降或伸缩,这些负载可以很容易地在不同的节点上重新调度。
一些云提供商在spot实例和他们的Kubernetes提供之间提供集成。它允许您在spot实例之上运行Kubernetes集群的某些部分,并在spot实例宕机时重新平衡/重新安排工作负载。
这可能是运行Kubernetes的一种更具成本效益的方式。
Cloud Provider Integration
使用由云提供商管理的Kubernetes,您将默认情况下将该云提供商的许多其他功能集成到Kubernetes中。
这是云提供商的卖点,例如,他们为您提供了更多开箱即用的功能。此外,这是另一种将您锁定在他们系统中的方法(通过在像Kubernetes这样的开放平台上为您提供专有服务)。
云提供商集成的一个例子是负载均衡器服务。首先,创建一个类型为:LoadBalancer的服务,Kubernetes将在集群运行的云中提供一个负载平衡器。对于运行在-prem上的现成Kubernetes来说,这是不可能的,除非您安装并配置了一个知道如何为该环境提供负载均衡器的控制器。
注意:这确实会导致供应商锁定,因为LoadBalancer服务是一个抽象结构,并且在不同的云中创建相同的资源会有相同的结果–将为您提供一个负载均衡器。
Node Rolling Updates
滚动更新意味着拥有一个工作负载的多个实例,并逐一更新它们,以便始终至少有一个工作负载的实例在运行,并且没有停机时间。
这同样适用于更新Kubernetes集群本身。您可以使用最新的Kubernetes组件逐一更新节点,而不会导致集群停机。
CSI
CSI代表容器存储接口。
它的目标是为存储供应商提供一个统一的接口,这些供应商可以编写与每个容器编排器一起工作的插件。
Kubernetes在Kubernetes1.9中作为alpha和Kubernetes1.13中作为GA实现了这个接口。
这使得消费者可以使用每个拥有CSI兼容插件的存储供应商。在Kubernetes实现这一点之前,提供存储的代码是in-tree的,引入新的存储类型甚至修复现有存储类型中的bug都是缓慢和困难的,必须与Kubernetes的发布过程保持一致。
Cluster API
Cluster API是SIG Cluster Lifecycle的一个项目,旨在统一配置和管理集群、虚拟机、负载均衡器和运行Kubernetes所需的其他一切的过程。
有100多个Kubernetes发行版和安装程序,但没有统一的工作方式,这就产生了对这种东西的需求。集群API作为它们之上的抽象。它可以由任何人以他们想要的任何方式来实施。
例如,大多数云提供商都有集群API的实现,它们在各自的云中提供和管理集群。
security sandboxing
安全沙箱是现有隔离之上的另一层隔离。
它是通过附加强化Pods运行时来实现的,比以前更好地将Pods彼此隔离开来。
它是由gVisor和Kata容器等安全运行时启用的。
gVisor
gVisor是一个用Go编写的应用程序内核,它实现了Linux系统调用接口的大部分。它在运行的应用程序和主机操作系统之间提供了额外的隔离层。
gVisor包括一个名为runsc的开放容器计划(OCI)运行时,它使使用现有容器工具变得容易。runsc运行时与Docker和Kubernetes集成,使得运行沙箱容器变得简单。
gVisor拦截应用程序系统调用并充当来宾内核,而不需要通过虚拟化硬件进行转换。gVisor可以被认为是一个合并的来宾内核和VMM,或者是类固醇上的seccomp。这种架构允许它提供灵活的资源占用(即基于线程和内存映射的资源占用,而不是固定的客户物理资源),同时还降低了虚拟化的固定成本。然而,这是以降低应用程序兼容性和更高的每个系统调用开销为代价的。
Kata containers
Kata containers是一个开源项目,旨在构建一个容器运行时,该运行时与轻量级虚拟机一起工作,这种虚拟机感觉像一个容器,但提供了虚拟机的隔离。
Kata容器运行时与CRI兼容,这意味着Kubernetes支持它。
您可以使用containerd或cri-o在Kubernetes中运行Kata容器。
Managing Instance Groups
管理实例组(MIG)是一组被视为单个实体的虚拟机。
这个特性是由云提供商提供的,用于创建和管理大量虚拟机。
在Kubernetes的上下文中,可以有一个MIG,它是一组节点,以相同的方式标记这些节点。这样,您就可以拥有一个运行在多个MIG上的Kubernetes集群,但是不同的工作负载可以通过污染和容忍在不同的MIG上提供。
OS level Node bootstrap
引导Kubernetes节点涉及到以一种能够作为Kubernetes节点运行的方式配置机器。
这包括安装容器运行时、其他Kubernetes相关工具以及配置cgroups和名称空间。
像kubeadm这样的工具对这个过程有很大帮助。您可以在这里找到关于引导Kubernetes节点的完整指南。
Chaos testing/engineering
混沌工程是一门在系统上进行实验的学科,目的是建立对系统在生产中承受湍流条件的能力的信心。
混沌测试是通过破坏系统的随机部分来测试系统。在软件和微服务体系结构的情况下,可能会断开运行软件的一些节点,并确保系统的另一部分仍在工作,或者它已经正常地失败。
这种方法由Netflix公司流行,该公司经营着一系列庞大的微服务。
如果你正在使用Kubernetes,你能想到的最简单的混沌测试就是删除一些豆荚或一些节点。Kubernetes就是为这样的场景设计的,它将自动重新创建吊舱,并尝试在剩余的节点上重新分配它们。
有一些工具,如混沌网格和ChaosToolkit,允许您在Kubernetes集群中执行更复杂的混沌测试场景。
CRI
CRI代表容器运行时接口。
它定义了一个接口,该接口由容器运行时实现,并由Kubernetes调用以管理容器。
这使得Kubernetes可以支持各种容器运行时,并且可以在不重新编译Kubernetes代码的情况下替换这些运行时。它还允许容器运行时开发人员独立开发运行时,而不是树中的Kubernetes,并发布新版本和与Kubernetes发布周期分离的bug修复版本。
另外,请参见https://kubernetes.io/docs/concepts/architecture/cri/。
Advanced scheduling
Kubernetes调度器在大多数情况下工作得很好–它确保在具有足够资源的节点上调度POD,确保复制集/状态集在节点之间平衡,等等。
然而,有时我们希望有更细粒度的控制。例如,在具有某些特定硬件的节点上调度Pod,将节点专用于特定的服务,等等。
这就是高级调度概念的用武之地。其中大部分已经在Kubernetes1.6中引入,并且已经很稳定了。
Node affinity/anti-affinity
节点亲和性意味着Pod对节点具有亲和性。
在节点端,这是通过设置标签来实现的。
在Pod端,这是通过设置spec.affinity.NodeAffinity属性来实现的。
例如,此Pod规范将只在具有kubernetes.is/os:linux标签的节点上调度Pod:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
requiredDuringSchedulingIgnoredDuringExecution意味着Kubernetes在调度Pod时将考虑这种亲和力,但一旦调度Pod就会忽略它,例如,如果节点删除了这个标签,它将不会重新调度Pod。
另一个选项是preferredDuringSchedulingIgnoredDuringExecution,这意味着Kubernetes将尝试找到一个具有此标签的节点来调度Pod,但如果没有,它将在另一个节点上调度Pod。一旦Pod被调度,关联将被忽略,例如,如果节点删除了这个标签,Kubernetes将不会重新调度Pod。
Pod affinity/anti-affinity
Pod亲和力类似于节点亲和力,但它会影响Pod之间的调度方式。例如,出于某种原因,我们可能希望在同一个节点上调度两个豆荚。我们可以用豆荚亲和力做到这一点。
这是通过spec.affinity.podaffinity属性实现的。
例如,此Pod规范将在具有服务:S1标签的Pod的同一节点上调度Pod:
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: service
operator: In
values: [“S1”]
topologyKey: failure-domain.beta.kubernetes.io/zone
同样,我们可以使用requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution,它们的工作方式与节点亲和性相同。
Taints and tolerations
污点和容忍度允许您标记节点(污染它们),并且只在这样的节点上调度对这些污点有容忍度的豆荚。
这样,您就可以在主节点上标记一个污点,这样您就只能在它们上调度系统组件,或者可以标记运行特殊硬件的节点,这样只有需要该硬件的工作负载才在那里调度。
您可以通过Kubectl向节点添加污点:
kubectl taint nodes node1 key=value:NoSchedule
现在在这个节点上,我们只能调度对这种污染有容忍度的豆荚。
公差在吊舱的spec.grounity字段中定义。
对此污点的容忍如下所示:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
custom schedulers
如果这些构造都没有提供调度POD时所需的灵活性,那么您可以编写并部署自己的调度器,该调度器将与默认的Kubernetes调度器一起工作。实际上,您可以根据需要部署任意多个调度器,因为Kubernetes支持运行多个调度器。
为了利用您的自定义计划程序,您需要在创建pod时设置spec.schedulername字段。这将告诉Kubernetes调度器不要调度吊舱。
例如:
spec:
schedulerName: my-custom-scheduler
告诉Kubernetes my-custom-scheduler调度程序将调度此吊舱。
如果这样的调度程序不存在,则此吊舱将永远无法得到调度。
您可以在Bash中找到一个非常简单的调度器实现。
MetalLB
MetalB是一个用于裸机Kubernetes集群的负载平衡器实现,使用标准路由协议。
它旨在缩小裸机集群与云提供商(EKS、AKS、GKE等)中运行的集群之间的差距
裸机集群不具备与云提供商相同的LB供应能力。MetalLB旨在纠正这一点,并在提供和配置负载均衡器时带来相同的用户体验。
Keepalived
MetalB是一个用于裸机Kubernetes集群的负载平衡器实现,使用标准路由协议。
它旨在缩小裸机集群与云提供商(EKS、AKS、GKE等)中运行的集群之间的差距
裸机集群不具备与云提供商相同的LB供应能力。MetalLB旨在纠正这一点,并在提供和配置负载均衡器时带来相同的用户体验。
- 点赞
- 收藏
- 关注作者
评论(0)