Kubernetes 面试宝典

创建 Pod的主要流程?

  • 客户端提交 Pod 的配置信息(可以是 yaml 文件定义的信息)到 kube-apiserver.

  • Apiserver 收到指令后,通知 controllr-manager 创建一个资源对象

  • controller-manager 通过 apiserver 将 pod 的配置信息存储到 ETCD 数据中薪心中

  • kube-scheduler 检查到 pod 信息会开始调度预选,会先过滤不符合 Pod 资源配置要求的节点,然后开始调度调优,主要是挑选出更适合运行的 pod 节点,然后将 pod 的资源配置单发送到 node 节点上的 kubelet 组件上

  • kubelet 根据 scheduler 发来的资源配置单运行 pod,运行成功后,将 pod 的运行的信息返回 scheduler, scheduler 将返回的 pod 运行状况的信息存储到 etcd 数据中信

Pod 的重启策略?

  •  Pod 重启策略(RestartPolicy)应用于 Pod 内的所有容器,并且仅再 Pod 所处的 Node 上由 Kubelet 进行判断和重启操作.当某个容器异常退出或健康检查失败时,kubele 将根据 RestartPolicy 的设置来进行相应操作

  •  pod 的重启策略包括 Always,OnFaliure 和 Never,默认值为 Always

    •  Always: 当容器失效时由 kubelet 自动重启该容器

    • OnFailure:当容器终止运行且退出不为 0 时,yo 由 kubelet 自动重启该容器

    • Nerve: 不论容器运行状态如何,kubelet 都不会重启该容器

  •  同时 pod 的容器策略与控制方式关联,当前可用于管理 Pod 的控制器包括 RelicatonController

Pod 的健康检查方式?

  •  LivenessProbe探针:用于判断容器是否存活(running状态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应处理。若一个容器不包含LivenessProbe探针,kubelet认为该容器的LivenessProbe探针返回值用于是“Success”。

  •  ReadineeProbe探针:用于判断容器是否启动完成(ready状态)。如果ReadinessProbe探针探测到失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Eenpoint。

  •  startupProbe探针:启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被上面两类探针kill掉。

Pod 探针常见方式?

  •  ExecAction:在容器内执行一个命令,若返回码为0,则表明容器健康。

  •  TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,若能建立TCP连接,则表明容器健康。

  •  HTTPGetAction:通过容器的IP地址、端口号及路径调用HTTP Get方法,若响应的状态码大于等于200且小于400,则表明容器健康。

Pod 常见的调度方式?

  •  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升级策略?

  •  在Deployment的定义中,可以通过spec.strategy指定Pod更新的策略,目前支持两种策略:Recreate(重建)和RollingUpdate(滚动更新),默认值为RollingUpdate。

  •  Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新Pod时,会先杀掉所有正在运行的Pod,然后创建新的Pod。

  •  RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更新Pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavailable和maxSurge)来控制滚动更新的过程

Kubernetes Service类型?

通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。其主要类型有:

  •  ClusterIP:虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy通过设置的iptables规则进行转发;

  •  NodePort:使用宿主机的端口,使能够访问各Node的外部客户端通过Node的IP地址和端口号就能访问服务;

  •  LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡器的IP地址,通常用于公有云。

Service分发后端的策略?

Service负载分发的策略有:RoundRobin和SessionAffinity

  •  RoundRobin:默认为轮询模式,即轮询将请求转发到后端的各个Pod上。

  •  SessionAffinity:基于客户端IP地址进行会话保持的模式,即第1次将某个客户端发起的请求转发到后端的某个Pod上,之后从相同的客户端发起的请求都将被转发到后端相同的Pod上。

Kubernetes外部如何访问集群内的服务?

  •  映射Pod到物理机:将Pod端口号映射到宿主机,即在Pod中采用hostPort方式,以使客户端应用能够通过物理机访问容器应用。

  •  映射Service到物理机:将Service端口号映射到宿主机,即在Service中采用nodePort方式,以使客户端应用能够通过物理机访问容器应用。

  • 映射Sercie到LoadBalancer:通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置Service的场景。

Kubernetes ingress?

  •  Kubernetes的Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。

  •  Kubernetes使用了Ingress策略和Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器。使用Ingress进行负载分发时,Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(Pod)上,从而跳过kube-proxy的转发功能,kube-proxy不再起作用,全过程为:ingress controller + ingress 规则 ----> services。

  • 同时当Ingress Controller提供的是对外服务,则实际上实现的是边缘路由器的功能。

Kubernetes镜像的下载策略?

K8s的镜像下载策略有三种:Always、Never、IFNotPresent。

  •  Always:镜像标签为latest时,总是从指定的仓库中获取镜像。

  •  Never:禁止从仓库中下载镜像,也就是说只能使用本地镜像。

  •  IfNotPresent:仅当本地没有对应镜像时,才从目标仓库中下载。

默认的镜像下载策略是:当镜像标签是latest时,默认策略是Always;当镜像标签是自定义时(也就是标签不是latest),那么默认策略是IfNotPresent。

Kubernetes kubelet的作用?

  • 在Kubernetes集群中,在每个Node(又称Worker)上都会启动一个kubelet服务进程。该进程用于处理Master下发到本节点的任务,管理Pod及Pod中的容器。每个kubelet进程都会在API Server上注册节点自身的信息,定期向Master汇报节点资源的使用情况,并通过cAdvisor监控容器和节点资源。

Secret有哪些使用方式?

  • 创建完secret之后,可通过如下三种方式使用:

  • 在创建Pod时,通过为Pod指定Service Account来自动使用该Secret。

  • 通过挂载该Secret到Pod来使用它。

  • 在Docker镜像下载时使用,通过指定Pod的spc.ImagePullSecrets来引用它。

Kubernetes CNI模型?

  • CNI提供了一种应用容器的插件化网络解决方案,定义对容器网络进行操作和配置的规范,通过插件的形式对CNI接口进行实现。CNI仅关注在创建容器时分配网络资源,和在销毁容器时删除网络资源。在CNI模型中只涉及两个概念:容器和网络。

  • 容器(Container):是拥有独立Linux网络命名空间的环境,例如使用Docker或rkt创建的容器。容器需要拥有自己的Linux网络命名空间,这是加入网络的必要条件。

  • 网络(Network):表示可以互连的一组实体,这些实体拥有各自独立、唯一的IP地址,可以是容器、物理机或者其他网络设备(比如路由器)等。

  • 对容器网络的设置和操作都通过插件(Plugin)进行具体实现,CNI插件包括两种类型:CNI Plugin和IPAM(IP Address Management)Plugin。CNI Plugin负责为容器配置网络资源,IPAM Plugin负责对容器的IP地址进行分配和管理。IPAM Plugin作为CNI Plugin的一部分,与CNI Plugin协同工作。

Kubernetes PV和PVC?

  • PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”。

  • PVC则是用户对存储资源的一个“申请”。

PV生命周期内的阶段?

某个PV在生命周期中可能处于以下4个阶段(Phaes)之一。

  • Available:可用状态,还未与某个PVC绑定。

  • Bound:已与某个PVC绑定。

  • Released:绑定的PVC已经删除,资源已释放,但没有被集群回收。

  • Failed:自动资源回收失败。

calico 网络模式

模式 数据包封包 优点 缺点
vxlan 封包, 在vxlan设备上将pod发来的数据包源、目的mac替换为本机vxlan网卡和对端节点vxlan网卡的mac。外层udp目的ip地址根据路由和对端vxlan的mac查fdb表获取 只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。各个node节点通过vxlan设备实现基于三层的”二层”互通, 三层即vxlan包封装在udp数据包中, 要求udp在k8s节点间三层可达;二层即vxlan封包的源mac地址和目的mac地址是自己的vxlan设备mac和对端vxlan设备mac。 需要进行vxlan的数据包封包和解包会存在一定的性能损耗
ipip 封包,在tunl0设备上将pod发来的数据包的mac层去掉,留下ip层封包。 外层数据包目的ip地址根据路由得到。 只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。 需要进行ipip的数据包封包和解包会存在一定的性能损耗
bgp 不需要进行数据包封包 不用封包解包,通过bgp协议可实现pod网络在主机间的三层可达, k8s节点不跨网段时和flannel的host-gw相似;
支持跨网段, 满足复杂的网络架构 跨网段时,需要主机网关路由也充当BGP Speaker能够学习到pod子网路由并实现pod子网路由的转发

fannel三种模式

fannel三种模式 效率 calico 模式
UDP 性能较差,封包解包涉及到多次用户态和内核态交互 类似 IPIP
VXLAN 性能较好,封包解包在内核态实现,内核转发数据,flanneld负责动态配置ARP和FDB(转发数据库)表项更新 类似VXLAN
host-gw 性能最好,不需要再次封包,正常发包,目的容器所在的主机充当网关
flanneld 负责主机上路由表的刷新 类似 BGP

你知道的几种CNI网络插件,并详述其工作原理。K8s常用的CNI网络插件 (calico && flannel),简述一下它们的工作原理和区别。

  • calico根据iptables规则进行路由转发,并没有进行封包,解包的过程,这和flannel比起来效率就会快多 calico包括如下重要组件:Felix,etcd,BGP Client,BGP Route Reflector。下面分别说明一下这些组件。

Felix:主要负责路由配置以及ACLS规则的配置以及下发,它存在在每个node节点上。 etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用; BGPClient(BIRD), 主要负责把 Felix写入 kernel的路由信息分发到当前 Calico网络,确保 workload间的通信的有效性; BGPRoute Reflector(BIRD), 大规模部署时使用,摒弃所有节点互联的mesh模式,通过一个或者多个 BGPRoute Reflector 来完成集中式的路由分发 通过将整个互联网的可扩展 IP网络原则压缩到数据中心级别,Calico在每一个计算节点利用 Linuxkernel 实现了一个高效的 vRouter来负责数据转发,而每个vRouter通过 BGP协议负责把自己上运行的 workload的路由信息向整个Calico网络内传播,小规模部署可以直接互联,大规模下可通过指定的BGProute reflector 来完成。这样保证最终所有的workload之间的数据流量都是通过 IP包的方式完成互联的。

  • Flannel的工作原理: Flannel实质上是一种“覆盖网络(overlay network)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。

默认的节点间数据通信方式是UDP转发。 工作原理: 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡(先可以不经过docker0网卡,使用cni模式),这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。 Flannel通过Etcd服务维护了一张节点间的路由表,详细记录了各节点子网网段 。 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。 flannel在进行路由转发的基础上进行了封包解包的操作,这样浪费了CPU的计算资源。

Worker节点宕机,简述Pods驱逐流程。

  • 在 Kubernetes 集群中,当节点由于某些原因(网络、宕机等)不能正常工作时会被认定为不可用状态(Unknown 或者 False 状态),当时间超过了 pod-eviction-timeout 值时,那么节点上的所有 Pod 都会被节点控制器计划删除。

  • Kubernetes 集群中有一个节点生命周期控制器:node_lifecycle_controller.go。它会与每一个节点上的 kubelet 进行通信,以收集各个节点已经节点上容器的相关状态信息。当超出一定时间后不能与 kubelet 通信,那么就会标记该节点为 Unknown 状态。并且节点生命周期控制器会自动创建代表状况的污点,用于防止调度器调度 pod 到该节点。

  • 那么 Unknown 状态的节点上已经运行的 pod 会怎么处理呢?节点上的所有 Pod 都会被污点管理器(taint_manager.go)计划删除。而在节点被认定为不可用状态到删除节点上的 Pod 之间是有一段时间的,这段时间被称为容忍度。如果在不配置的情况下,Kubernetes 会自动给 Pod 添加一个 key 为 node.kubernetes.io/not-ready 的容忍度 并配置 tolerationSeconds=300,同样,Kubernetes 会给 Pod 添加一个 key 为 node.kubernetes.io/unreachable 的容忍度 并配置 tolerationSeconds=300。

  • 当到了删除 Pod 时,污点管理器会创建污点标记事件,然后驱逐 pod 。这里需要注意的是由于已经不能与 kubelet 通信,所以该节点上的 Pod 在管理后台看到的是处于灰色标记,但是此时如果去获取 pod 的状态其实还是处于 Running 状态。每种类型的资源都有相应的资源控制器(Controller),例如:deployment_controller.go、stateful_set_control.go。每种控制器都在监听资源变化,从而做出相应的动作执行。deployment 控制器在监听到 Pod 被驱逐后会创建一个新的 Pod 出来,但是 Statefulset 控制器并不会创建出新的 Pod,原因是因为它可能会违反 StatefulSet 固有的至多一个的语义,可能出现具有相同身份的多个成员,这将可能是灾难性的,并且可能导致数据丢失。

你知道的K8s中几种Controller控制器,并详述其工作原理

  • deployment:适合无状态的服务部署 适合部署无状态的应用服务,用来管理pod和replicaset,具有上线部署、副本设定、滚动更新、回滚等功能,还可提供声明式更新,例如只更新一个新的Image

  • 编写yaml文件,并创建nginx服务pod资源。

  •  StatefullSet:适合有状态的服务部署 适合部署有状态应用,解决Pod的独立生命周期,保持Pod启动顺序和唯一性。

  • 稳定,唯一的网络标识符,持久存储(例如:etcd配置文件,节点地址发生变化,将无法使用)

  • 有序,优雅的部署和扩展、删除和终止(例如:mysql主从关系,先启动主,再启动从)有序,滚动更新

  • 应用场景:例如数据库

无状态服务的特点:

  •  deployment 认为所有的pod都是一样的

  •  不用考虑顺序的要求

  •  不用考虑在哪个node节点上运行

  •  可以随意扩容和缩容

有状态服务的特点:

  •  实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper

  •  实例之间不对等的关系,以及依靠外部存储的应用

  •  常规的service服务和无头服务的区别

  •  service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现

  •  Headless service 无头服务,不需要cluster-IP,直接绑定具体的Pod的IP,无头服务经常用于statefulset的有状态部署

  •  创建无头服务的service资源和dns资源,由于有状态服务的IP地址是动态的,所以使用无头服务的时候要绑定dns服务

  •  DaemonSet:一次部署,所有的node节点都会部署,例如一些典型的应用场景: 运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph

  • • 在每个Node上运行日志收集 daemon,例如 fluentd、 logstash

  • • 在每个Node上运行监控 daemon,例如 Prometheus Node Exporter

  • • 在每一个Node上运行一个Pod

  • • 新加入的Node也同样会自动运行一个Pod

  • • 应用场景:监控,分布式存储,日志收集等

  • Job:一次性的执行任务

  • • 一次性执行任务,类似Linux中的job

  • • 应用场景:如离线数据处理,视频解码等业务

  •  Cronjob:周期性的执行任务

  • • 周期性任务,像Linux的Crontab一样

  • • 应用场景:如通知,备份等

  • • 使用cronjob要慎重,用完之后要删掉,不然会占用很多资源

ingress-controller的工作机制

通常情况下,service和pod的IP仅可在集群内部访问

  • • k8s提供了service方式:NodePort 来提供对外的服务,外部的服务可以通过访问Node节点ip+NodePort端口来访问集群内部的资源,外部的请求先到达service所选中的节点上,然后负载均衡到每一个节点上。

NodePort虽然提供了对外的方式但也有很大弊端:

  • • 由于service的实现方式:user_space 、iptebles、 3 ipvs、方式这三种方式只支持在4层协议通信,不支持7层协议,因此NodePort不能代理https服务。

  • • NodePort 需要暴露service所属每个node节点上端口,当需求越来越多,端口数量过多,导致维护成本过高,并且集群不好管理。

原理

  • • Ingress也是Kubernetes API的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发到指定的Service资源的规则。用于将集群外部的请求流量转发到集群内部完成的服务发布。我们需要明白的是,Ingress资源自身不能进行“流量穿透”,仅仅是一组规则的集合,这些集合规则还需要其他功能的辅助,比如监听某套接字,然后根据这些规则的匹配进行路由转发,这些能够为Ingress资源监听套接字并将流量转发的组件就是Ingress Controller。

  • • Ingress 控制器不同于Deployment 等pod控制器的是,Ingress控制器不直接运行为kube-controller-manager的一部分,它仅仅是Kubernetes集群的一个附件,类似于CoreDNS,需要在集群上单独部署。

  • • ingress controller通过监视api server获取相关ingress、service、endpoint、secret、node、configmap对象,并在程序内部不断循环监视相关service是否有新的endpoints变化,一旦发生变化则自动更新nginx.conf模板配置并产生新的配置文件进行reload

k8s的调度机制

Scheduler工作原理: 请求及Scheduler调度步骤:

  • • 节点预选(Predicate):排除完全不满足条件的节点,如内存大小,端口等条件不满足。

  • • 节点优先级排序(Priority):根据优先级选出最佳节点

  • • 节点择优(Select):根据优先级选定节点

具体步骤:

  • • 首先用户通过 Kubernetes 客户端 Kubectl 提交创建 Pod 的 Yaml 的文件,向Kubernetes 系统发起资源请求,该资源请求被提交到

  • • Kubernetes 系统中,用户通过命令行工具 Kubectl 向 Kubernetes 集群即 APIServer 用 的方式发送“POST”请求,即创建 Pod 的请求。

  • • APIServer 接收到请求后把创建 Pod 的信息存储到 Etcd 中,从集群运行那一刻起,资源调度系统 Scheduler 就会定时去监控 APIServer

  • • 通过 APIServer 得到创建 Pod 的信息,Scheduler 采用 watch 机制,一旦 Etcd 存储 Pod 信息成功便会立即通知APIServer,

  • • APIServer会立即把Pod创建的消息通知Scheduler,Scheduler发现 Pod 的属性中 Dest Node 为空时(Dest Node=””)便会立即触发调度流程进行调度。

  • • 而这一个创建Pod对象,在调度的过程当中有3个阶段:节点预选、节点优选、节点选定,从而筛选出最佳的节点

    • • 节点预选:基于一系列的预选规则对每个节点进行检查,将那些不符合条件的节点过滤,从而完成节点的预选

    • • 节点优选:对预选出的节点进行优先级排序,以便选出最合适运行Pod对象的节点

    • • 节点选定:从优先级排序结果中挑选出优先级最高的节点运行Pod,当这类节点多于1个时,则进行随机选择

k8s的调用工作方式

  • • Kubernetes调度器作为集群的大脑,在如何提高集群的资源利用率、保证集群中服务的稳定运行中也会变得越来越重要Kubernetes的资源分为两种属性。

    • • 可压缩资源(例如CPU循环,Disk I/O带宽)都是可以被限制和被回收的,对于一个Pod来说可以降低这些资源的使用量而不去杀掉Pod。

    • • 不可压缩资源(例如内存、硬盘空间)一般来说不杀掉Pod就没法回收。未来Kubernetes会加入更多资源,如网络带宽,存储IOPS的支持。

kube-proxy的三种工作模式和原理

userspace 模式

  • • 该模式下kube-proxy会为每一个Service创建一个监听端口。发向Cluster IP的请求被Iptables规则重定向到Kube-proxy监听的端口上,Kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。

  • • 该模式下,Kube-proxy充当了一个四层Load balancer的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加两次内核和用户空间之间的数据拷贝,效率较另外两种模式低一些;好处是当后端的Pod不可用时,kube-proxy可以重试其他Pod。

iptables 模式

  • • 为了避免增加内核和用户空间的数据拷贝操作,提高转发效率,Kube-proxy提供了iptables模式。在该模式下,Kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。

  • • 该模式下Kube-proxy不承担四层代理的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

该模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs rules。ipvs也是在kernel模式下通过netfilter实现的,但采用了hash table来存储规则,因此在规则较多的情况下,Ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。如果要设置kube-proxy为ipvs模式,必须在操作系统中安装IPVS内核模块。

你可能感兴趣的:(系统运维,面试技巧,Kubernetes,kubernetes,k8s,Secret,Pod,容器,k8s自动化,Kubernetes面试)