k8s的学习思考
2024-04-25 11:31:24 4 举报
AI智能生成
登录查看完整内容
具体内容主要描述了k8s master里面中的主要组件 和service的简单描述
作者其他创作
大纲/内容
主要作用:kubernetes为Pod分配的、固定的、基于iptables(或者IPVS)的访问入口。而这些访问入口代理的Pod信息,来自于Etcd,由kube-proxy通过控制循环来维护。
给Service分配一个VIP,然后增加iptables规则将该IP的请求转发到后续的iptables链
KUBE-SEP-(hash) 规则对应的 DNAT 链,这些规则应该与 Endpoints 一一对应;
KUBE-SVC-(hash) 规则对应的负载均衡链,这些规则的数目应该与 Endpoints 数目一致;
iptables链实际上是一个集合,包含了各个PodIP(这些称之Service的Endpoints),使用Round Robin方式的负载均衡。
这些Endpoints对应的iptables规则,正式kube-proxy通过监听Pod变化事件,在宿主机上生成并维护。
原理
因为要维护iptables,在大量的pod的情况下,性能不佳,于是出现了IPVS模式。以创建虚拟网卡,并分配虚拟IP的形式,直接使用Linux的IPVS模块,由于讲转发逻辑放到了Linux内核中执行,性能有所提升。
IPVS模式
通过集群的内部IP暴露服务,只能够在内部访问
ClusterIP
通过每个节点上的IP和静态端口,暴露服务。NodePort服务会路由到自动创建的ClusterIP服务。通过请求 节点IP:节点端口,你可以从寄存的外部访问一个NodePort服务
NodePort
使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
LoadBalancer
通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。 (简单理解为域名访问)
ExternalName
Service的访问模式
Service
api层: 主要提供对外的 rest api
etcd 数据库: 用于持久化存储资源对象.在比较小的项目过程中就使用的是内部etcd模式大项目可以使用外部etcd集群模式
核心功能是提供kuberrnetes各类资源对象(Pod、RC、service等)的增删改查以及watch等HTTPRest接口。
kubelet每隔一个时间周期都会调用一次APIServer的REST接口报告自身的状态apiserver接收到这些信息后,将节点信息更新到etcd中。kubelet通过apiserver的watch接口舰艇pod信息,比如创建pod副本绑定到本节点,则执行pod对应的容器创建和启动操作。
kube-controller-manager中的node controller模块通过apiserver模块提供watch接口,监控弄的信息。
scheduler通过APIservr的Watch接口监听新建Pod副本的信息后,它会检索所有符合该Pod要求的Node列表,开始执行Pod调度逻辑,调度成功后将Pod绑定到目标节点上。
apiserver作为统一入口,任何对数据的操作都必须经过apiserver。apiserver负责个模块之间的通信,集群里的功能模块通过apiserver将信息存入etcd中,etcd存储集群的数据信息,其他模块通过apiserver读取这些信息,来实现模块之间的交互。(会导致apiserver压力太大 所以使用了 list-wathch机制 本地缓存机制)
ListAPI维持的是Http短链接 获取全量的数据,watchAPI维持http长连接,来获取增量的数据
消息可靠性
list-watch机制下,每个apiserver的资源产生的状态变更,都会将事件推送给客户端,从而保证信息的实时性。kubernetes服务器只会保证一定时间内变化的变更列表。
消息实时性
k8s在每个资源的事件都带一个resourceVersion的标签,这个标签是递增的数字,可以通过比较version来确定信息是否一致。
消息顺序性
watch作为异步消息通知机制,服用一条http长连接,保证实时性与高性能。
高性能
List-watch机制满足异步消息系统
informer 主要用于在 Kubernetes 集群中对资源对象进行监视和管理主要作用是:Informer 是 Kubernetes 中用于从 Kubernetes API Server 获取对象列表(List)或单个对象(Get)的一种机制。Informer 是 Kubernetes 中的一种控制器,它会定期向 API Server 发送请求,获取特定类型的资源对象的列表或单个对象的详细信息,并将这些信息保存在本地的缓存中。
informer 本地缓存与索引机制
主要作用:每个controller都有一个工作队列。从eventHandler触发事件会先放入队列中,然后由controller中的processltem函数取出来。workqueue是一个去重队列,内部除了item列表外还带有一个processing和dirty set记录,用来实现同一个资源对象多次时间出发,入队列后去重,不会被多个work同时处理,解决了并发处理问题。
workqueue
list Watch机制
APIServer
资源需求
资源限额
选择标准
(podFistResources :资源要求)判断资源是否满足条件
(podSelectorMatches:标签匹配) pod 没有制定spec.nodeSelector标签选择器,则返回ture如果获得被选节点的标签信息,判断节点是否包含被选pod的标签选择器所指的标签,包含:ture or false
podFitsHost,判断被选pod的spec.nodeName域所指定的节点名称和被选节点的名称是否一致,如果一致返回true,否则返回false。
podFitsPorts,判断被选pod所用的端口列表的端口是否在被选节点中被占用,如果被占用,则返回false,否则返回ture。
podFitsHostPorts,节点上已经使用的port是否和pod申请的port冲突
GeneralPredicates
noDiskconflict 磁盘冲突 :步骤,读取被选pod的volume信息,再读取备选node上所有的pod的每一个volume进行比较,如果有冲突返回false知道找到合适的NODE。
maxPDVlumeCountPredicate:查看一个节点上某中类型的持久化volume是不是超过一定数量了,超过了则不会调度到这个node上。
volumeZonePredicate:检查持久化volume的Zone标签,是否与待考察节点的Zone标签匹配。
Volume
考察调度pod是否满足node本身的某些机制,比如node的“污点”机制。只有当pod的toleration字段与Node的taint字段能够匹配的时候,这个pod才能背调度到该节点上。
宿主机
predicate(预选择)
通过对预选择的节点进行评分,选出最高分数的节点(最高分数节点可能不止一个)
计算出所有备选节点上运行的pod和备选pod的CPU占用量
计算出所有备选节点上运行的pod和备选pod的memory占用量
计算方式如下:score = (cpu((capacity-sum(requested))10/capacity) + memory((capacity-sum(requested))10/capacity))/2
leatRequestedPriority (打分机制)
与leatRequestedPriority不同的是 此计算方法所算出来的是资源分配最均衡的节点
BalancedResourceAllocation
priority(优选择)
主要作用:经过优选择评分机制可能会有多台分数一样,一样的话就在其中最终选择一台。
select (最终选择)
步骤
kubectl label nodesnode-01 disktype=ssd 首先给Node打上标签
然后在daemonset中指定nodeSelector为disktype=ssd:spec: nodeSelector: disktype: ssd更具默认调度器PodSelectorMatches策略选出合适的节点,然后打分进行分配。
nodeSelector:只调度到指定label的node上
requiredDuringSchedulingIgnoredDuringExecution(必选条件),preferredDuringSchedulingIgnoredDuringExecution(优选条件)
nodeAffinity:功能更丰富的Node选择器,比如支持集合操作
podAffinity(调度到含有某一标签且在运行的pod对应的Node上)
podAntiAffinity(不调度到含有某一标签的pod对应的Node上)
podAffinity:调度到满足条件的Pod所在的Node上
node affinity 在deployment的调度的时候说明过亲和性调度的使用,主要是两个策略:强制和优先。调度到符合条件的node上去。
pod affinity 用于调度pod可以和哪些pod部署在同拓扑结构之下。
podAntiAffinity相反 用于规定pod不可以和哪些pod部署在同一拓扑结构下。AntiAffinity同样有两个策略:强制和优先。
总结
可以指定Node节点调度
taints和tolerations用于保证pod不被调度到不合适的Node哈桑,其中taint应用于Node上,二toleration则应用于pod上。
NoSchedule:新的Pod不调度到该Node上,不影响正在运行的Pod
PreferNoSchedule:soft版的NoSchedule,尽量不调度到该Node上
NoExecute:新的Pod不调度到该Node上,并且删除已经在运行的Pod。Pod可以增加一个时间(tolerationSeconds)
taints的三种类型
屏蔽Node节点调度
scheduler调度策略(创建的POD为什么都会在同一节点上)
informer主要作用用于监听 Etcd有关于pod、node、service的调度变化并将调度资源放到对了中,将调度信息放到scheduler cache中
Scheduling Path主要作用 从Queue中Pop需要调度的资源,从SchedulerCache获取对应的信息,(Predicates,Priorities)用于打分算法和匹配调度,最后进行绑定操作(调度算法执行完成后,调度器就需要将 Pod 对象的 nodeName 字段的值,修改为上述 Node 的名字 称之为Bind)。值得注意的是:所有的信息都是从cache中获得的(这大大提高了执行的效率)事实上,Kubernetes 调度部分进行性能优化的一个最根本原则,就是尽最大可能将集群信息 Cache 化,以便从根本上提高 Predicate 和 Priority 调度算法的执行效率。并且:在predicates于priorities的并发于并行操作时才用了无锁的操作(原因:调度器会避免设置任何全局的竞争资源,从而免去加锁产生的性能损耗)。在整个过程中,只有对cache更新缓存才会有加锁的行为。
Bind操作更新的信息只会更新Scheduler Cache里面的Pod和Node的信息 (避免在关键路径中远程访问APIServer 减少关键路径中的消耗)。这种基于“乐观”假设的 API 对象更新方式,在 Kubernetes 里被称作 Assume。Assume 之后 调度器会创建一个Goroutine来异步的向APIServer发起更新请求。
Scheduling主要分为两条路 和一个中间层:
Scheduling 原理
scheduler
是控制器的控制者,使用集群管理控制中心
副本控制器。副本控制器的核心作用是确保任何使用集群中的一个RC所关联的Pod副本数量保持设定的阈值。
Replication Controller控制器
主要作用:nodestatusmap中状态,对于状态不对的node节点加入一个队列,等待确认node是否有问题,有问题就进行信息同步,并且删除节点。
如果controller manager在启动时设置了–cluster-cidr,那么为每一个没有设置spec.PodCIDR的节点生成一个CIDR地址,并用该地址设置节点的spec.PodCIDR属性。
逐个读取节点信息,此时node controller中有一个nodestatusMap,里面存储了信息,与新发送过来的节点信息做比较,并更新nodestatusMap中的节点信息。Kubelet发送过来的节点信息,有三种情况:未发送、发送但节点信息未变化、发送并且节点信息变化。此时node controller根据发送的节点信息,更新nodestatusMap,如果判断出在某段时间内没有接受到某个节点的信息,则设置节点状态为“未知”。
最后,将未就绪状态的节点加入到待删除队列中,待删除后,通过API Server将etcd中该节点的信息删除。如果节点为就绪状态,那么就向etcd中同步该节点信息。
nodeController管理的主要过程
node controller 节点管理
作用:它确保任何对象任何时候都不回超量占用资源,确保了系统的稳定性。支持三层资源配置:容器级别 可以限制cpu和memorypod级别 对pod内所有容器的可用资源进行限制namespaces级别 pod数量,rc数量 service数量,rq数量,secret数量,presistenVolume数量(RQ ResourceQuota:设置命名空间的资源配额,限制这些资源的总使用量)(secret:用于存储敏感数据,例如密码和 API 密钥)
实现资源配置机制:准入机制(admission control),admission control当前提供了两种方式的配额约束分别是limitRange、resouceQuota。limitRange作用与pod和容器上。ResourceQuota作用于namespace上,用于限定一个namespace里的各种资源的使用总额。
当用户给pod定义了limitRange的时候 会通过API创建或者修改对象,admission control会计算当前的资源配合的使用情况,如果不符合约束条件而创建或者修改失败。
ResourceQuotaController会定期读取ResourceQuota信息,统计后在写入etcd中
对于定义了resource Quota的namespace,resourceQuota controller会定期统计和生成该namespace下的各类对象资源使用总量,统计结果包括:pod、service、RC、secret和PV等对象的实例个数,以及该namespace下所有的container实例所使用的资源量(CPU,memory),然后会将这些结果写入到etcd中,写入的内容为资源对象名称、配额制、使用值,然后admission control会根据统计结果判断是否超额,以确保相关namespace下的资源配置总量不会超过resource Quota的限定值。
拒绝请求
修改请求
动态调整
记录和通知
如果资源请求超额,admission 控制器通常会根据定义的策略
通过流程图可以看到三条线路,这三条线路对于resourceQuota Controller很重要
resourceQuota controller资源配置
namespace controller
Service Controller 的主要作用监听Service的变化endPoints Controller的作用:监测新的Service创建或者修改后,则根据该service的信息获取到相关的pid列表,然后创建或更新service对应的endpoint对象,如果service被删除,则删除该servide同名的endpoints对象
service 和endpoint与pod的关系,endpoints表示一个service对应的所有pod副本的访问地址,而endpoints controller就是负责生成和维护所有的endpoints对象的控制器,service和pod通过label关联之后,我们访问service的clusterIP对应的服务,就能通过kube-proxy将路由转发到对应的后端的endpoint(pod IP +port)上,最终访问到容器中的服务,实现了service的负载均衡功能
service controller 和endpoint controller
ServiceAccountController和TokenController主要作用都是身份认证和授权机制的组成部分,他们却暴露集群中个个组件的安全通信,并管理ServiceAccount的身份验证和授权所需的凭据。
每个 ServiceAccount 都有一个关联的 Secret,其中包含用于身份验证的 Token。Token Controller 负责为每个 ServiceAccount 创建、更新和删除相应的 Token。
Token Controller 为集群中的各个组件提供了一种安全的身份验证机制,它们可以使用 ServiceAccount Token 与 API Server 进行通信,并执行权限相对应的操作。
TokenController
ServiceAccount 是 Kubernetes 中的一种身份认证机制,用于识别 Pod 运行时所使用的身份。ServiceAccount Controller 负责创建、更新和删除 ServiceAccount 对象,并确保它们与命名空间中的相关资源一致。
ServiceAccount Controller 确保 Pod 使用的 ServiceAccount 具有适当的访问权限,以访问其需要的其他 Kubernetes 资源,如 Secrets 和 ConfigMaps。
ServiceAccount Controller
ServiceAccountController和TokenController
Controller Manager
k8s学习思考
0 条评论
回复 删除
下一页