本文发布于Cylon的收藏册,转载请著名原文链接~
Kubernetes概念
Ingress和LoadBalancer的区别
- Ingress通常用于将HTTP(S)流量路由到Kubernetes群集内部的服务,支持复杂路径路由和负载均衡算法
- LB则是通过提供商提供一种外部流量引入到集群内的组件,通常为2 3层
- Ingress本身是基于service的,引入流量时依赖 kube-proxy
- LB则是独立的组件,最小接入单元也是service,而通过2 3层的广播等功能可以提供多节点的引入
- 功能:Ingress是一个规范,LB则是一种实现
- 实现方式:ingress通过扩展Kubernetes API+controller, 而LB除此外还需要外部设备提供(软硬件,云组件)
kubernetes之最小单元
- Pod最小可调度单元,最小部署单元
- 容器:容器是最小的执行单元
- Namespace:最小隔离单元
- Service:最小接入单元
etcd用的什么算法,简单解释一下
raft算法 强一致性 同一时间只能有一个leader,所有的操作都在leader上。
Pod 的生命周期
Pod 状态始终处于一下几个状态之一:
- Pending: 部署 Pod 事务已被集群受理,但当前容器镜像还未下载完或现有资源无法满足 Pod 的资源需求
- Running: 所有容器已被创建,并被部署到节点上
- Successed: Pod 成功退出,并不会被重启
- Failed: Pod 中有容器被终止
- Unknown: 未知原因,如 kube-apiserver 无法与 Pod 进行通讯
Kubernetes有哪些不同类型的服务?
- cluster ip
- Node Port
- Load Balancer
- Extrenal Name
什么是ETCD?
Etcd是用Go编程语言编写的,是一个分布式键值存储,用于协调分布式工作。因此,Etcd存储Kubernetes集群的配置数据,表示在任何给定时间点的集群状态。
什么是Ingress网络,它是如何工作的?
Ingress网络是一组规则,充当Kubernetes集群的入口点。这允许入站连接,可以将其配置为通过可访问的URL,负载平衡流量或通过提供基于名称的虚拟主机从外部提供服务。因此,Ingress是一个API对象,通常通过HTTP管理集群中服务的外部访问,是暴露服务的最有效方式。
什么是Headless Service?
Headless Service类似于“普通”服务,但没有群集IP。此服务使您可以直接访问pod,而无需通过代理访问它。
什么是集群联邦?
在联邦集群的帮助下,可以将多个Kubernetes集群作为单个集群进行管理。因此,您可以在数据中心/云中创建多个Kubernetes集群,并使用联邦来在一个位置控制/管理它们。
联合集群可以通过执行以下两项操作来实现此目的。请参考下图。
kube-proxy的作用
kube-proxy运行在所有节点上,它监听apiserver中service和endpoint的变化情况,创建路由规则以提供服务IP和负载均衡功能。简单理解此进程是Service的透明代理兼负载均衡器,其核心功能是将到某个Service的访问请求转发到后端的多个Pod实例上。
kube-proxy iptables的原理
Kubernetes从1.2版本开始,将iptables作为kube-proxy的默认模式。iptables模式下的kube-proxy不再起到Proxy的作用,其核心功能:通过API Server的Watch接口实时跟踪Service与Endpoint的变更信息,并更新对应的iptables规则,Client的请求流量则通过iptables的NAT机制“直接路由”到目标Pod。
kube-proxy ipvs的原理
IPVS在Kubernetes1.11中升级为GA稳定版。IPVS则专门用于高性能负载均衡,并使用更高效的数据结构(Hash表),允许几乎无限的规模扩张,因此被kube-proxy采纳为最新模式。
在IPVS模式下,使用iptables的扩展ipset,而不是直接调用iptables来生成规则链。iptables规则链是一个线性的数据结构,ipset则引入了带索引的数据结构,因此当规则很多时,也可以很高效地查找和匹配。
可以将ipset简单理解为一个IP(段)的集合,这个集合的内容可以是IP地址、IP网段、端口等,iptables可以直接添加规则对这个“可变的集合”进行操作,这样做的好处在于可以大大减少iptables规则的数量,从而减少性能损耗。
kube-proxy ipvs和iptables的异同
iptables与IPVS都是基于Netfilter实现的,但因为定位不同,二者有着本质的差别:iptables是为防火墙而设计的;IPVS则专门用于高性能负载均衡,并使用更高效的数据结构(Hash表),允许几乎无限的规模扩张。
与iptables相比,IPVS拥有以下明显优势:
- 为大型集群提供了更好的可扩展性和性能;
- 支持比iptables更复杂的复制均衡算法(最小负载、最少连接、加权等);
- 支持服务器健康检查和连接重试等功能;
- 可以动态修改ipset的集合,即使iptables的规则正在使用这个集合。
Kubernetes镜像的下载策略
Kubernetes的镜像下载策略有三种:Always、Never、IFNotPresent。
- Always:镜像标签为latest时,总是从指定的仓库中获取镜像。
- Never:禁止从仓库中下载镜像,也就是说只能使用本地镜像。
- IfNotPresent:仅当本地没有对应镜像时,才从目标仓库中下载。默认的镜像下载策略是:当镜像标签是latest时,默认策略是Always;当镜像标签是自定义时(也就是标签不是latest),那么默认策略是IfNotPresent。
简述Kubernetes Scheduler使用哪两种算法将Pod绑定到worker节点
Kubernetes Scheduler根据如下两种调度算法将 Pod 绑定到最合适的工作节点:
- 预选(Predicates):输入是所有节点,输出是满足预选条件的节点。kube-scheduler根据预选策略过滤掉不满足策略的Nodes。如果某节点的资源不足或者不满足预选策略的条件则无法通过预选。如“Node的label必须与Pod的Selector一致”。
- 优选(Priorities):输入是预选阶段筛选出的节点,优选会根据优先策略为通过预选的Nodes进行打分排名,选择得分最高的Node。例如,资源越富裕、负载越小的Node可能具有越高的排名。
有了解过qos吗? 怎么实现的?
服务质量 Quality of Service有三种 Guaranteed, Burstable, and Best-Effort,它们的QoS级别依次递减。
- Guaranteed:确保的,只设置
limits
或者requests
与limits
为相同时则为该等级 - Burstable:可突发的,只设置
requests
或requests
低于limits
的场景 - Best-effort: 默认值,如果不设置则为这个等级
node资源不足时会按qos级别驱逐pod。 最先驱逐的是Best-Effort ,重要组件一定要设置limit和request.
驱逐顺序根据 BestEffort ==》Burstable ==》Guaranteed 进行驱逐
Kubernetes 开发
资源和类型
Kind:实体的类型
resources:resources是,restful中的资源,标识一组HTTP端点(paths),可以理解为kind的实例化。
例如:Pod是etcd中的数据,而resources对应的 path上的resources
Resources和kinds区别
- Resources与HTTP paths关联,
- Resources始终是API Group和Version的一部分。
- kind是这些endpoint返回并接收的objects的类型,并持久存在于etcd中。
Kubernetes | OOP |
---|---|
Kind | Class |
Resource | Object |
Kind 其实就是一个类,用于描述对象的;而 Resource 就是具体的 Kind,可以理解成类已经实例化成对象了。
GVR与GVK有什么区别?
- GVR = Group Version Resources
- GVK = Group Version Kind
每个kind都属于一个Group和Version中,通过GVK标识,GVR是GVK对外提供服务的入口,GVK与GVR之间的映射过程交 REST mapping
client-go 客户端类型有哪些?
- RestClient:是最基础的客户端,其作用是将http client进行封装成rest api格式。位于rest目录
- ClientSet:基于RestClient进行封装对 Resource 与 version 管理集合,
- DiscoverySet:RestClient进行封装,可动态发现kube-apiserver所支持的GVR(Group Version Resource)。
- :基于RestClient,包含动态的客户端,可以对Kubernetes所支持的 API对象进行操作,包括CRD。
kubernetes 调度过程
kubernetes调度过程就是调度上下文,而调度上下文就是执行 scheduleOne 这个函数中线性执行的。
调度上下文的过程分为两阶段,调度和绑定
调度:指的是SchedulePod -> findNodesThatFitPod 这是 prefilter 阶段,如果通过 prefilter
-
prefilter 做预检查动作,如获取node列表,检查提名node是否满足,满足则评估,不满足则从PreFilterPlugins获取node list,满足所有条件执行 filter plugin;PreFilterPlugins返回的是一组Node name
-
filter 做过滤操作,满足的条件是至少配置了一个filter plugin,filter是线性的,如一个扩展不满足则标记为不可用
-
postFilter 是抢占的触发条件,即filter阶段没有FN时被触发,满足条件是需要配置至少一个该类型plugin
- 这里存在 Unschedulable 不可调用则执行postfilter,否则都不可调用
-
preScore, score 会在 prioritizeNodes 中执行对应的 插件
-
接下来是 Reserve, 为了避免Pod在绑定到节点前时,调度一个新的Pod,使节点使用资源超过可用资源情况。
-
Premit ,阻止或延迟 Pod 的绑定
绑定:绑定操作时异步进行的,即通过了打分阶段,基本上等于调度成功
- 这个异步线程会从延迟队列中拿到调度的pod,即Premit 的延迟
- 这里关联的上面的reserve 与 premit,如果不可调用则调用unreserved回滚,否则会调用 bind
- prebind 与 bind 的失败都会放入到回滚队列中
- bind 当 执行了unreserve 则忘记这个pod 否则成功的绑定了node
client-go的架构
-
Reflector deltafifo的生产者 就是将 (监控)Etcd 里面的数据反射到本地存储(DeltaFIFO)中
-
deltaFIFO, Delta 表示的是变化的资源对象存储 先进先出的队列
-
workqueue kubernetes中使用的队列,即每次触发的事件都被塞入到queue中进行处理
- 去重
- delay:如 cronjob 依赖延迟队列实现定时功能
- 限速:
-
Indexer deltaFIFO消费者,是Informer的本地存储。
workqueue算法实现
已知workqueue主要作用是为了去重,延迟,限速,那么他是通过什么算法实现的呢?
- 延迟主要使用了 Binary Heap 数据类型实现的延迟,而这种queue称为优先级队列
- Heap是一个二叉树数据结构,即每个节点包含的元素大于或等于该节点子节点的元素,如果新元素的值大于父元素,将新元素与父元素交换,直到达到新元素到根,这个过程叫向上调整
- 元素被放置在结构中时,按照优先级排列
- 优先级最高的元素最先离开
- 限速队列时在延迟队列的基础上扩展的,使用的令牌桶和漏桶算法实现的
kube-proxy作用
kube-proxy作用是位于工作节点上,通过ipvs提供service功能,本质上来说是一个controller,通过监听 node, endpoints, service等资源的变动从而生成proixer的规则
什么是endpointslice
- Endpoints 与 EndpointSlices 均是为service提供端点的
- Service规模越大,那么Endpoints中的 Pod 数量越大,传输的 EndPoints 对象就越大。集群中 Pod 更改的频率越高,也意味着传输在网络中发生的频率就越高
- Endpoints 对象在大规模集群场景下存在下列问题:
- 增加网络流量(etcd最大请求大小为 1.5 MiB),隐性增加对控制平面的影响,service的可扩展性将降低
- 超大规模的 service 理论上会无法存储 该 Endpoints
- 处理Endpoints资源的 worker 会消耗更多的计算资源
- Endpointslices 解决了:
- 部分更新,更少的网络流量
- Worker 处理 Endpoints 更新所需的资源更少
- 减少对控制平面的影响,提升的性能和 service 规模
本文发布于Cylon的收藏册,转载请著名原文链接~
链接:https://www.oomkill.com/2021/10/interview-kubernetes/
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。