容器小师妹 2020-11-26 852浏览量
作者个人介绍
刘晨 Lorraine 坐标Fintech,精通持续集成与发布,曾具有全平台100+应用持续部署持续发布实战经验,现在立志于成为K8S玩家。
大家好,笔者最近学习和整理K8S知识点的时候,一直以多维角度重新K8S,笔者认为应用开发者为了适应云原生趋势,需要掌握必要的K8S基础知识点,详细介绍在https://developer.aliyun.com/article/778441。
笔者做为团队的Devops,承担着管理K8S集群的职责,本篇就从资源管理角度重新认识K8S。
在物理机或虚拟机集群时代,我们管理的资源主要是以主机为单元的集群。单个主机节点,可以是一台物理机,或者是基于Hypervitor虚拟化中间件的VM,资源类型主要包括CPU,内存,磁盘IO,以及网络带宽。
K8S集群一般由至少一个Master节点和若干个Worker节点组成。Master节点包含了调度器Scheduler,控制器Controller,资源对象接口APIServer以及持久化存储Etcd。Worker节点通过Kubelet跟Master节点通信,其资源以及负载Pod受Master的调度以及控制。K8S本身架构是C/S模式,即worker节点的资源管理与调度都由Master节点控制。
认识K8S集群资源时,不再按照传统方式以节点单元切分,笔者选择工作负载,存储以及网络这三个方面介绍资源类型,是基于K8S提供的核心资源对象Pod,PVC/PV以及Service/Ingress实现了最基本的集群资源管理与容器编排。在K8S集群中,CPU以及内存资源定义包含在Pod内,用户无法从K8S直接管理。PVC/PV模式解耦了存储资源与节点资源。Service提供了自动服务发现,使得K8S集群具备自愈能力。Ingress提供了对集群网络流量的控制,使得K8S可以一体化考虑工作负载与网络负载,达到弹性伸缩。
requests定义了工作负载的资源下限,是容器启动时K8S资源分配的默认值。
limits定义了工作负载的资源上限,是容器运行时K8S资源预分配的额度。
Pod部署一般属于研发团队应用部署的子环节,由开发人员控制。PV存储资源定义与分配则多属于devops团队,由集群管理员控制。
Pod和PVC是命名空间访问控制范围内的资源对象,PV则是集群访问控制范围内的资源对象。
K8S做为当前最流行的容器编排平台,提供了平台级别的弹性伸缩以及故障自愈等解决方案。K8S集群基于C/S架构,由Master统一控制管理集群资源与负载均衡。Pod是K8S调度的最小单元,我们要掌握集群资源管理与调度就要从Pod调度与管理开始。
livenessProbe类似进程健康检查,都是对容器进程进行健康检查,当检测到失败时,就重启该进程,以达到自动修复。
不同的是,livenessProbe是通过调用应用服务定义的HTTP GET API来连接Pod的暴露的IP和Port,通过请求的返回码是否属于200~399来判定容器进程运行状态的。
除了HTTP方式,还可以通过TCP Socket是否联通成功判定应用服务运行状态。
这种来自K8S而不是应用服务内部的应用运行状态判定逻辑,使得K8S能够掌握应用服务级别的健康状态。
ReadinessProbe提供的接入方式与livenessProbe一样,可以通过HTTP GET API或TCP Socket Connection方式由Kubelet探针将Pod工作负载的情况上报给K8S管理节点。
当检测到readinessProbe失败,应用服务进程无法正常处理请求时,该Pod不再被重启,而是从Service端点摘除,不再接收Service的请求负载,类似流量降级,已确保该Pod可以正确处理已接收的请求负载。
{
"kind" : "Policy",
"apiVersion" : "v1",
"predicates" : [
{"name" : "PodFitsHostPorts"},
{"name" : "PodFitsResources"},
{"name" : "NoDiskConflict"},
{"name" : "NoVolumeZoneConflict"},
{"name" : "MatchNodeSelector"},
{"name" : "MaxEBSVolumeCount"},
{"name" : "MaxAzureDiskVolumeCount"},
{"name" : "checkServiceAffinity"},
{"name" : "PodToleratesNodeNoExecuteTaints"},
{"name" : "MaxGCEPDVolumeCount"},
{"name" : "MatchInterPodAffinity"},
{"name" : "PodToleratesNodeTaints"},
{"name" : "HostName"}
],
"priorities" : [
{"name" : "LeastRequestedPriority", "weight" : 2},
{"name" : "BalancedResourceAllocation", "weight" : 1},
{"name" : "ServiceSpreadingPriority", "weight" : 1},
{"name" : "EqualPriority", "weight" : 1}
]
}
Scheduler调度流程 From Kubernetes-Patterns
Allocatable Capacity= Node Capacity - Kube-Reserved - System-Reserved
Allocatable Capacity为Scheduler可为应用服务Pod分配的节点资源
Node Capacity为节点资源总量
Kube-Reserved为K8S的后台进程预留资源,例如Kubelet,CRI,CNI等组件
System-Reserved为节点的操作系统后台进程预留资源,例如sshd, udev等
Burstable:Pod设置requests和limits,但是requests小于limits。这种Pod具有最低的资源保证,即当节点资源竞争,不再有Best-Effort这种Pod时,优先销毁或迁移该类Pod。
Guaranteed:Pod设置requests和limits,且requests 等于limits。这种Pod具有最高的资源保证。QOS级别高于Burstable和Best-Effort。所以,建议在定义应用服务的Pod模版时,对于容器资源保证,服务质量要求高的Pod,尽量配置合适的requests和limits。
运行在K8S集群的应用服务多是基于微服务架构的分布式系统。服务与服务之间常常具有互相调用关系。当调度应用服务Pod时,Scheduler会选择最佳的节点进行资源分配创建Pod,在启动容器前,随机分配ClusterIP地址给这个Pod。所以,当另一个应用服务Pod想要与该应用服务Pod通信,很难获取到这个随机分配的ClusterIP信息。
传统的分布式系统,比如ZooKeeper,常常使用的是客户端发现方式,进行服务间自动发现。客户端服务内置了可以发现服务注册中心以及选择其中某个服务实例进行通信的探针Agent。服务端服务实例将自己的状态上报到服务注册中心,客户端服务通过查询服务注册中心信息,选择并唤醒响应的服务实例进行交互。
客户端服务发现ByAgent
服务端发现ByProxy
apiVersion: v1
kind: Service
metadata:
name: index-helm
namespace: bss-dev
spec:
clusterIP: 172.21.7.94
ports:
- name: http
port: 8081 //service对外提供服务的端口号
protocol: TCP
targetPort: 8081 //Pod监听的端口号
selector:
app.kubernetes.io/instance: index //spec->selector绑定了对应的Pod
app.kubernetes.io/name: helm
sessionAffinity: None
type: ClusterIP //ClusterIP 是默认service类型
当Pod被创建后,与之绑定的Service服务对象也随之被创建,并且立即开始监听绑定的端口号。与Service相关的ClusterIP和Port值以环境变量方式自动设置到Pod中,该应用服务就能通过clusterIP和port对外提供服务了。
由于Pod启动以后,无法再将service对应的环境变量注入,所以,基于环境变量绑定clusterIP和port只能发生在Pod启动过程。
DNS查询
K8S提供了一个平台级别的DNS服务,可以配置给所有Pod使用。当一个Service资源对象被创建,DNS服务可以绑定一个DNS访问地址到对应Pod,供访问使用。这个DNS服务管理着应用服务DNS访问地址与Pod启动时分配的ClusterIP和port的对应关系,负责解析从该DNS访问地址过来的流量负载到对应的Pod上。
如果客户端服务已知ServiceName和对应的Namespace,就可以直接通过内部域名地址service-name.namsapce.svc.cluster.local直接访问应用服务Pod。
service-name是service对象定义的名称
namespace是service和pod所在的命名空间名
svc代表这是一个service资源
cluster.local是K8S的coreDNS服务默认集群内部访
问地址域名前缀
笔者最近在整理K8S入门的基础知识点,本篇做为“从应用开发角度认识K8S”的姐妹篇,从资源管理角度重新认识了K8S。K8S平台的用户一般分为应用开发和集群管理员。集群管理员在掌握K8S的时候,更多时候要从集群层面,资源层面,性能层面多维度认识K8S,这时就需要我们掌握和了解最基本的Pod调度与资源管理,存储与网络资源以及服务与流量管理等知识点。
本文介绍的内容算是抛砖引入,如果读者有兴趣继续深入学习相关知识,可以参考学习
https://medium.com/@kumargaurav1247/components-of-kubernetes-architecture-6feea4d5c712
https://developers.redhat.com/blog/2020/05/11/top-10-must-know-kubernetes-design-patterns/
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。