60道重要的Kubernetes面试题
共 21149字,需浏览 43分钟
·
2021-06-02 01:54
点击“程序员面试吧”,选择“星标🔝”
点击文末“阅读原文”解锁资料
简单:支持REST风格的HTTP+JSON API
安全:支持HTTPS方式的访问
快速:支持并发1k/s的写操作
可靠:支持分布式结构,基于Raft的一致性算法,Raft是一套通过选举主节点来实现分布式系统一致性的算法。
服务发现(Service Discovery):服务发现主要解决在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听UDP或TCP端口,并且通过名字就可以查找和连接。
消息发布与订阅:在分布式系统中,最适用的一种组件间通信方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。通过这种方式可以做到分布式系统配置的集中式管理与动态更新。应用中用到的一些配置信息放到etcd上进行集中管理。
负载均衡:在分布式系统中,为了保证服务的高可用以及数据的一致性,通常都会把数据和服务部署多份,以此达到对等服务,即使其中的某一个服务失效了,也不影响使用。etcd本身分布式架构存储的信息访问支持负载均衡。etcd集群化以后,每个etcd的核心节点都可以处理用户的请求。所以,把数据量小但是访问频繁的消息数据直接存储到etcd中也可以实现负载均衡的效果。
分布式通知与协调:与消息发布和订阅类似,都用到了etcd中的Watcher机制,通过注册与异步通知机制,实现分布式环境下不同系统之间的通知与协调,从而对数据变更做到实时处理。
分布式锁:因为etcd使用Raft算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。
集群监控与Leader竞选:通过etcd来进行监控实现起来非常简单并且实时性强。
kubeadm,也是推荐的一种部署方式;
二进制;
minikube,在本地轻松运行一个单节点Kubernetes群集的工具。
容器编排
轻量级
开源
弹性伸缩
负载均衡
快速部署应用
快速扩展应用
无缝对接新的应用功能
节省资源,优化硬件资源的使用
可移植:支持公有云、私有云、混合云、多重云(multi-cloud)。
可扩展: 模块化,、插件化、可挂载、可组合。
自动化: 自动部署、自动重启、自动复制、自动伸缩/扩展。
安装过程和配置相对困难复杂。
管理服务相对繁琐。
运行和编译需要很多时间。
它比其他替代品更昂贵。
对于简单的应用程序来说,可能不需要涉及Kubernetes即可满足。
Master:Kubernetes集群的管理节点,负责管理集群,提供集群的资源数据访问入口。拥有etcd存储服务(可选),运行Api Server进程,Controller Manager服务进程及Scheduler服务进程。
Node(worker):Node(worker)是Kubernetes集群架构中运行Pod的服务节点,是Kubernetes集群操作的单元,用来承载被分配Pod的运行,是Pod运行的宿主机。运行Docker Eninge服务,守护进程kunelet及负载均衡器kube-proxy。
Pod:运行于Node节点上,若干相关容器的组合。Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通信。Pod是Kubernetes进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。
Label:Kubernetes中的Label实质是一系列的Key/Value键值对,其中key与value可自定义。Label可以附加到各种资源对象上,如Node、Pod、Service、RC等。一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。Kubernetes通过Label Selector(标签选择器)查询和筛选资源对象。
Replication Controller:Replication Controller用来管理Pod的副本,保证集群中存在指定数量的Pod副本。集群中副本的数量大于指定数量,则会停止指定数量之外的多余容器数量。反之,则会启动少于指定数量个数的容器,保证数量不变。Replication Controller是实现弹性伸缩、动态扩容和滚动升级的核心。
Deployment:Deployment在内部使用了RS来实现目的,Deployment相当于RC的一次升级,其最大的特色为可以随时获知当前Pod的部署进度。
HPA(Horizontal Pod Autoscaler):Pod的横向自动扩容,也是Kubernetes的一种资源,通过追踪分析RC控制的所有Pod目标的负载变化情况,来确定是否需要针对性的调整Pod副本数量。
Service:Service定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制,关联多个相同Label的Pod,用户不需要了解后台Pod是如何运行。
Volume:Volume是Pod中能够被多个容器访问的共享目录,Kubernetes中的Volume是定义在Pod上,可以被一个或多个Pod中的容器挂载到某个目录下。
Namespace:Namespace用于实现多租户的资源隔离,可将集群内部的资源对象分配到不同的Namespace中,形成逻辑上的不同项目、小组或用户组,便于不同的Namespace在共享使用整个集群的资源的同时还能被分别管理。
Kubernetes API Server:作为Kubernetes系统的入口,其封装了核心对象的增删改查操作,以RESTful API接口方式提供给外部客户和内部组件调用,集群内各个功能模块之间数据交互和通信的中心枢纽。
Kubernetes Scheduler:为新建立的Pod进行节点(Node)选择(即分配机器),负责集群的资源调度。
Kubernetes Controller:负责执行各种控制器,目前已经提供了很多控制器来保证Kubernetes的正常运行。
Replication Controller:管理维护Replication Controller,关联Replication Controller和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。
Node Controller:管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点。
Namespace Controller:管理维护Namespace,定期清理无效的Namespace,包括Namesapce下的API对象,比如Pod、Service等。
Service Controller:管理维护Service,提供负载以及服务代理。
EndPoints Controller:管理维护Endpoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints。
Service Account Controller:管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret。
Persistent Volume Controller:管理维护Persistent Volume和Persistent Volume Claim,为新的Persistent Volume Claim分配Persistent Volume进行绑定,为释放的Persistent Volume执行清理回收。
Daemon Set Controller:管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node上正常的运行Daemon Pod。
Deployment Controller:管理维护Deployment,关联Deployment和Replication Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication Controller和Pod的更新。
Job Controller:管理维护Job,为Jod创建一次性任务Pod,保证完成Job指定完成的任务数目
Pod Autoscaler Controller:实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作。
为大型集群提供了更好的可扩展性和性能;
支持比iptables更复杂的复制均衡算法(最小负载、最少连接、加权等);
支持服务器健康检查和连接重试等功能;
可以动态修改ipset的集合,即使iptables的规则正在使用这个集合。
Pending:API Server已经创建该Pod,且Pod内还有一个或多个容器的镜像没有创建,包括正在下载镜像的过程。
Running:Pod内所有容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态。
Succeeded:Pod内所有容器均成功执行退出,且不会重启。
Failed:Pod内所有容器均已退出,但至少有一个容器退出为失败状态。
Unknown:由于某种原因无法获取该Pod状态,可能由于网络通信不畅导致。
客户端提交Pod的配置信息(可以是yaml文件定义的信息)到kube-apiserver。
Apiserver收到指令后,通知给controller-manager创建一个资源对象。
Controller-manager通过api-server将Pod的配置信息存储到etcd数据中心中。
Kube-scheduler检测到Pod信息会开始调度预选,会先过滤掉不符合Pod资源配置要求的节点,然后开始调度调优,主要是挑选出更适合运行Pod的节点,然后将Pod的资源配置单发送到Node节点上的kubelet组件上。
Kubelet根据scheduler发来的资源配置单运行Pod,运行成功后,将Pod的运行信息返回给scheduler,scheduler将返回的Pod运行状况的信息存储到etcd数据中心。
Always:当容器失效时,由kubelet自动重启该容器;
OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器;
Never:不论容器运行状态如何,kubelet都不会重启该容器。
RC和DaemonSet:必须设置为Always,需要保证该容器持续运行;
Job:OnFailure或Never,确保容器执行完成后不再重启;
kubelet:在Pod失效时重启,不论将RestartPolicy设置为何值,也不会对Pod进行健康检查。
LivenessProbe探针:用于判断容器是否存活(running状态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应处理。若一个容器不包含LivenessProbe探针,kubelet认为该容器的LivenessProbe探针返回值用于是“Success”。
ReadineeProbe探针:用于判断容器是否启动完成(ready状态)。如果ReadinessProbe探针探测到失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Eenpoint。
startupProbe探针:启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被上面两类探针kill掉。
ExecAction:在容器内执行一个命令,若返回码为0,则表明容器健康。
TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,若能建立TCP连接,则表明容器健康。
HTTPGetAction:通过容器的IP地址、端口号及路径调用HTTP Get方法,若响应的状态码大于等于200且小于400,则表明容器健康。
Deployment或RC:该调度策略主要功能就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。
NodeSelector:定向调度,当需要手动指定将Pod调度到特定Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配。
NodeAffinity亲和性调度:亲和性调度机制极大的扩展了Pod的调度能力,目前有两种节点亲和力表达:
requiredDuringSchedulingIgnoredDuringExecution:硬规则,必须满足指定的规则,调度器才可以调度Pod至Node上(类似nodeSelector,语法不同)。
preferredDuringSchedulingIgnoredDuringExecution:软规则,优先调度至满足的Node的节点,但不强求,多个优先级规则还可以设置权重值。
Taints和Tolerations(污点和容忍):
Taint:使Node拒绝特定Pod运行;
Toleration:为Pod的属性,表示Pod能容忍(运行)标注了Taint的Node。
初始创建Deployment时,系统创建了一个ReplicaSet,并按用户的需求创建了对应数量的Pod副本。
当更新Deployment时,系统创建了一个新的ReplicaSet,并将其副本数量扩展到1,然后将旧ReplicaSet缩减为2。
之后,系统继续按照相同的更新策略对新旧两个ReplicaSet进行逐个调整。
最后,新的ReplicaSet运行了对应个新版本Pod副本,旧的ReplicaSet副本数量则缩减为0。
Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新Pod时,会先杀掉所有正在运行的Pod,然后创建新的Pod。
RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更新Pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavailable和maxSurge)来控制滚动更新的过程。
在去做每个节点的日志收集工作。
监控每个节点的的运行状态。
ClusterIP:虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy通过设置的iptables规则进行转发;
NodePort:使用宿主机的端口,使能够访问各Node的外部客户端通过Node的IP地址和端口号就能访问服务;
LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡器的IP地址,通常用于公有云。
RoundRobin:默认为轮询模式,即轮询将请求转发到后端的各个Pod上。
SessionAffinity:基于客户端IP地址进行会话保持的模式,即第1次将某个客户端发起的请求转发到后端的某个Pod上,之后从相同的客户端发起的请求都将被转发到后端相同的Pod上。
映射Pod到物理机:将Pod端口号映射到宿主机,即在Pod中采用hostPort方式,以使客户端应用能够通过物理机访问容器应用。
映射Service到物理机:将Service端口号映射到宿主机,即在Service中采用nodePort方式,以使客户端应用能够通过物理机访问容器应用。
映射Sercie到LoadBalancer:通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置Service的场景。
Always:镜像标签为latest时,总是从指定的仓库中获取镜像。
Never:禁止从仓库中下载镜像,也就是说只能使用本地镜像。
IfNotPresent:仅当本地没有对应镜像时,才从目标仓库中下载。默认的镜像下载策略是:当镜像标签是latest时,默认策略是Always;当镜像标签是自定义时(也就是标签不是latest),那么默认策略是IfNotPresent。
预选(Predicates):输入是所有节点,输出是满足预选条件的节点。kube-scheduler根据预选策略过滤掉不满足策略的Nodes。如果某节点的资源不足或者不满足预选策略的条件则无法通过预选。如“Node的label必须与Pod的Selector一致”。
优选(Priorities):输入是预选阶段筛选出的节点,优选会根据优先策略为通过预选的Nodes进行打分排名,选择得分最高的Node。例如,资源越富裕、负载越小的Node可能具有越高的排名。
基础设施方面:保证容器与其所在宿主机的隔离;
权限方面:
最小权限原则:合理限制所有组件的权限,确保组件只执行它被授权的行为,通过限制单个组件的能力来限制它的权限范围。
用户权限:划分普通用户和管理员的角色。
集群方面:
API Server的认证授权:Kubernetes集群中所有资源的访问和变更都是通过Kubernetes API Server来实现的,因此需要建议采用更安全的HTTPS或Token来识别和认证客户端身份(Authentication),以及随后访问权限的授权(Authorization)环节。
API Server的授权管理:通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,建议采用更安全的RBAC方式来提升集群安全授权。
敏感数据引入Secret机制:对于集群敏感数据建议使用Secret方式进行保护。
AdmissionControl(准入机制):对kubernetes api的请求过程中,顺序为:先经过认证 & 授权,然后执行准入操作,最后对目标对象进行操作。
AlwaysAdmit:允许所有请求
AlwaysDeny:禁止所有请求,多用于测试环境。
ServiceAccount:它将serviceAccounts实现了自动化,它会辅助serviceAccount做一些事情,比如如果pod没有serviceAccount属性,它会自动添加一个default,并确保pod的serviceAccount始终存在。
LimitRanger:观察所有的请求,确保没有违反已经定义好的约束条件,这些条件定义在namespace中LimitRange对象中。
NamespaceExists:观察所有的请求,如果请求尝试创建一个不存在的namespace,则这个请求被拒绝。
对集群中的资源和非资源权限均有完整的覆盖。
整个RBAC完全由几个API对象完成, 同其他API对象一样, 可以用kubectl或API进行操作。
可以在运行时进行调整,无须重新启动API Server。
在创建Pod时,通过为Pod指定Service Account来自动使用该Secret。
通过挂载该Secret到Pod来使用它。
在Docker镜像下载时使用,通过指定Pod的spc.ImagePullSecrets来引用它。
特权模式:privileged是否允许Pod以特权模式运行。
宿主机资源:控制Pod对宿主机资源的控制,如hostPID:是否允许Pod共享宿主机的进程空间。
用户和组:设置运行容器的用户ID(范围)或组(范围)。
提升权限:AllowPrivilegeEscalation:设置容器内的子进程是否可以提升权限,通常在设置非root用户(MustRunAsNonRoot)时进行设置。
SELinux:进行SELinux的相关配置。
容器(Container):是拥有独立Linux网络命名空间的环境,例如使用Docker或rkt创建的容器。容器需要拥有自己的Linux网络命名空间,这是加入网络的必要条件。
网络(Network):表示可以互连的一组实体,这些实体拥有各自独立、唯一的IP地址,可以是容器、物理机或者其他网络设备(比如路由器)等。
它能协助Kubernetes,给每一个Node上的Docker容器都分配互相不冲突的IP地址。
它能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内。
EmptyDir(空目录):没有指定要挂载宿主机上的某个目录,直接由Pod内保部映射到宿主机上。类似于docker中的manager volume。
场景:
只需要临时将数据保存在磁盘上,比如在合并/排序算法中;
作为两个容器的共享存储。
特性:
同个Pod里面的不同容器,共享同一个持久化目录,当Pod节点删除时,Volume的数据也会被删除。
EmptyDir的数据持久化的生命周期和使用的Pod一致,一般是作为临时存储使用。
Hostpath:将宿主机上已存在的目录或文件挂载到容器内部。类似于Docker中的bind mount挂载方式。
特性:增加了Pod与节点之间的耦合。
PersistentVolume(简称PV):如基于NFS服务的PV,也可以基于GFS的PV。它的作用是统一数据持久化目录,方便管理。
Available:可用状态,还未与某个PVC绑定。
Bound:已与某个PVC绑定。
Released:绑定的PVC已经删除,资源已释放,但没有被集群回收。
Failed:自动资源回收失败。
静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。
动态模式:集群管理员无须手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种类型。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。
CSI Controller的主要功能是提供存储服务视角对存储资源和存储卷进行管理和操作。
CSI Node的主要功能是对主机(Node)上的Volume进行管理和操作。
在该Node上安装Docker、kubelet和kube-proxy服务;
然后配置kubelet和kubeproxy的启动参数,将Master URL指定为当前Kubernetes集群Master的地址,最后启动这些服务;
通过kubelet默认的自动注册机制,新的Worker将会自动加入现有的Kubernetes集群中;
Kubernetes Master在接受了新Worker的注册之后,会自动将其纳入当前集群的调度范围。
Elasticsearch:是一个搜索引擎,负责存储日志并提供查询接口;
Fluentd:负责从 Kubernetes 搜集日志,每个Node节点上面的Fluentd监控并收集该节点上面的系统日志,并将处理过后的日志信息发送给Elasticsearch;
Kibana:提供了一个 Web GUI,用户可以浏览和搜索存储在 Elasticsearch 中的日志。
统一管理、配置和更新这些分散的Kubernetes的应用资源文件;
分发和复用一套应用模板;
将应用的一系列资源当做一个软件包管理。
对于应用发布者而言,可以通过 Helm 打包应用、管理应用依赖关系、管理应用版本并发布应用到软件仓库。