← 返回文章列表

K8s运维面试实录(二):七年工程师核心技术问答

完整还原K8s运维工程师面试,涵盖跨地域迁移、CICD改造、Pod创建流程、Flannel网络、GPU运维、Operator开发等核心技术。

35 分钟阅读
字号

K8s运维面试实录(二):七年工程师核心技术问答

前言

这是某候选人第二场K8s运维面试记录,与第一场侧重点有所不同。本场面试更深入考察了架构设计、问题排查和开发能力。以下为技术问题完整还原。


1. 跨地域集群迁移

面试官问:之前做过业务系统跨地域迁移,具体介绍一下?

背景

是这样的,我们原来的集群是在舟山那边。然后要做活动的时候,因为我们会做周期性的活动,然后就要进行扩容。然后发现那个MySQL数据扩不了了。然后联系阿里云那边的话,它后续也不会去增加这个该区域的MySQL资源了。所以的话我们就公司就决定将这个舟山的集群迁移到杭州那边。

网络打通

然后迁移的话,我主要是用那个阿里云VPN的VPC的话去打通那个中央集群跟杭州集群的对等连接,使其可以进行跨地域的访问。然后对舟山对杭州集群的话做好那个网络的一个规划,然后搭建起杭州一个新的集群,然后做好测试的工作。

数据同步

测试运营没有问题之后,然后我用那个DTS的话去做MySQL的话就是双向的同步件,以及Redis也是做这个双线的一个同步。然后RDS的话我是使用单线的同步。就是舟山集群的一个RDS的消息的话是迁移到杭州集群。并且还舟山集群的一个生产者跟消费者的地址都同时指向杭州的地址。这样子的话切流的话都是以杭州为唯一的一个消息源。

ES迁移

然后我们ES的话,我们主要是做业务的一个指标的一个查询。所以的话我是起了一个定时job,去向新的集群去拉取这个指标。然后CDN的话是已经脱离集群了,所以我就是不用做这个迁移。

流量切换

最后的话一切都准备好的时候,我是用那个我们前面是有搭一个DNS,然后去修改这个DNS的新neck的一个解析,然后进行了一个流量的切换。并且通过阿里云的一个监控去关注这个流量的一个变化。如果一旦有发生问题的话,再通过DNS切回,切到舟山的一个集群。


2. CICD技术栈选型

面试官问:CICD工作内容具体介绍一下,包括技术选型?

原来架构

我们原来的话是GitLab加上Harbor,然后再加上Jenkins。然后后面的话我是引入了ArgoCD。

主要的一个原因是因为我们之前的Jenkins的话是直接部署到那个K8S集群当中,然后就缺乏那个清单文件的一个管理,以及回滚也比较困难,只能在那个流水线上面进行一个回滚。

所以我引入了ArgoCD,然后用GitLab去管理这个清单。然后ArgoCD的话只要监听到GitLab清单的一个资源的一个变化,它就可以做一个自动的一个部署。

流程

开发提交代码到GitLab仓库,然后就会触发那个web hook去让Jenkins去拉那个流水线代代码跟那个文件进行一个构建。然后会进行一个单元的测试,然后产品以及那个代码质量的一个检测,还有镜像的一个扫描,然后编译,然后编译完然后再构建这个镜像,然后到提交到Harbor仓库。

然后我引入了ArgoCD之后,就是推送到的Harbor仓库之后,它是会修改GitLab当中的一个清单的一个进馆。那给ArgoCD的话,它就会监听到那个GitLab清单的一个变化的话,那么它就会去拉取这个样本清单,然后再部署到这个K8S集群当中。

为什么保留Jenkins

CI的话现在还是用的Jenkins。其实GitLab它也是能做的。只是我们原先的话它都是用的是Jenkins,所以它就没有进行一个这样子的一个迁移改造。


3. Jenkins vs ArgoCD

面试官追问:Jenkins具体有什么问题?GitLab CI也有配置管理和历史版本功能。

嗯,主要问题是缺乏那个清单文件的一个管理。

因为Jenkins的话它原来的话它是直接推送到K8S集群当中的。我们部署完了之后,通过这个人工的一个审核,点击确认之后,它是直接部署到那个K8S集群。它就只要么前就只有存到那个ETCD数据库。如果要回滚的话,也是通过流水线这样进行一键的一个回滚。如果后续想再继续回滚,就会比较困难的。

那现在如果是引入ArgoCD的话,那我们就可以把样本清单的话去存储到那个GitLab当中。一旦构建完的话,去修改GitLab清单的一个进馆就可以了。然后ArgoCD它就能监听到,监听到的话再进行部署到一个K8S集群当中,然后回滚的话也可以通过ArgoCD的话一键回滚。


4. Pod创建流程

面试官问:介绍一下Pod创建后的流程和组件交互?

完整流程

首先的话是客户端它是会提交一个请求,到那个叫做Kubectl,然后到K8S的API Server。然后API Server的话就会收到这个请求,进行一个认证授权准入控制。然后这里准入控制的话就是可以通过web hook去做一个Mutating Webhook跟Validating Webhook,然后一个修改跟一个验证。然后再存到ETCD数据库当中。

然后把这个事件然后各个组件的话,它是基于list watch机制进行一个监听这个事件。然后API Server的话就会上报创建这个请求的一个事件。然后Controller Manager的话,它就会监听到这个事件之后,然后进行一个调谐的一个过程。然后就会提交创建Pod的请求。然后创建Pod请求之后,API Server就会存到ETCD数据库,并且上报这个事件给到Schedule。

然后Schedule的话就会监听到进行一个预选跟优选。预选的话主要是会根据清和返青和然后拓普浴,还有污点跟容忍,还有以及你申请的一个资源的一个情况,然后进行一个预选。然后再进行一个优选。优选完了之后,他就会把这个选出来的一个机器的结果给到那个叫API Server,存到ETCD数据库,然后再进行一个上报。那么对应节点的那个Kubelet它就能监听到这个事件,然后进行一个调用容器引擎进行一个创建容器。

创建容器过程

创建容器已经创建Pod的过程的话,首先它是会因为在1.24版本之前的话,它直接对接docker多docker守护进程的那1.24之后的话是直接对接containerd这个容器引擎的。

然后就会创建出那个container,需要是作为容器的一号进程。然后再可能会调用的就是会创建出那个容器的一个容器的进程。

以及的话首先Pod的话它是会先创造出那个叫做pause容器,也就是网络容器。然后调用那个网络插件将这个容器base容器的网络进行一个打通。打通完了之后,然后再创建这个业务容器。以及业务容器跟这个base容器是共享网络名称空间的。

生命周期

然后生命周期上的话就是刚才说它是先创造出贝斯容器之后,它是会先进行一个Init,就是创新Init容器,先进行一个初始化。然后初始化完了之后的话,那么它在一个会运再运行一个主业务进程。同时的话,它会先执行那个叫做preStop钩子函数。然后并且的话运行那个readinessProbe就是启动探针进行检测这个容器是否启动。

完成了这个探针的话,它是会一般设置时间的话会比较长一点的,以防这个容器运行启动的过程比较长期,以免这个误杀。然后这个探针检测通过之后,才会再运行那个live就是就绪探针跟那个存活探针的一个周期性的一个检测。

然后如果容器结束之前的话,是Kubelet会调用那个preStop构成函数给它发送执行这个就是结束的一个钩子函数。然后对这个容器先进行一个优雅的退出,然后再进才会就是容器才会结束。

然后结束之后,Kubelet就会上报,把pod的信息上报给API server,那ETCD就会更新这个pod的一个信息。


5. K8S与Docker关系

面试官追问:K8S和Docker是什么关系?

K8S它是管理容器的一个平台。我可以这么理解。

然后如果是因为K8S的话,它就可以。如果是单单只有部署那个Docker的话,它是故障现K8S它是有那个控制器,它是可以进行。如果pod挂掉的话,像它就可以根据他的一定的副本数,然后进行一个重建这个pod。然后还有schedule的话,它是可以通过,它是可以进行一个预选优选。

如果是没有这个的话,那那只能我根据我们去判断这个容器一个资源的判情况,然后进行再拿一个机器起那个容器。


6. Flannel跨主机通信原理

面试官问:K8S中如何实现跨主机容器通信?

Flannel模式

我们用的是flannel微插链模式。

首先如果是pod如果是访问另一个pod如果是同节点进行一个通信的话,那pod是会从eth0网卡出来,然后通过外设对,它是会连接那个cni0就是网桥的。然后如果是,然后再进行一个路由判决。如果是同节点的话,那cni0网桥就会进行一个广播到同节点的一个pod。

跨节点通信

如果是跨节点的话,那么flannel它是有一个微插链设备,它是会进行一个分包封装的那个过程。

分包这个流程的话它是会涉及到三张表,分别是路由表、ARP表、还有FDB表。

首先路由判决是会判决到快捷点的话,就会给到那个flannel.1进行处理。然后还有两张表的话分别是ARP表。ARP表的话是会根据目标IP的一个网段。然后会得到目标IP的那个flannel的mac地址。然后会分装到那个内存包里面。然后再通过这个mac地址,然后通过FDB表会得到那个叫做对应目标网段的那个主机的一个IP。会也是分装到那个外层包里面。然后再通过然后再进行一个路由判决。

路由判决完了之后,从那个叫做主机的那个eth0网卡出来,然后到达对端的那个eth0网卡。然后根据这个mac地址,flannel的mac地址,然后就会交给那个对端的那个进行一个处理,进行一个解包的处理。解包完了之后,再通过路由判决再给到cni0网桥进行一个广播发送,就可以发送到那个pod,进行一个跨节点点的通信。

Host-GW模式

然后还有个flannel GW模式,flannel GW模式它是同节点的话,跟那个微插链模式是一样的。也是通过cni0网桥的话,是可以进行那个通信点通信的。

跨节点通信的话,它是通过路由判决去进行一个跨节点通信的。也就是说会把那个目标节点的话作为一个路由网关,就是下一个下一跳的话是只限目标地址。然后作为一个网关就给到目标节点。然后目标节点的话再通过路由判决给到cni0网桥进行一个处理。

但是这个的话像这种flannel的host-gw模式,它只能进行一个二层的通信,它不能进行跨三层通信。像微差量的话就能跨三层,而且一般的话也不会用这个flannel的这个host-gw模式。

因为那个首先第一点的话是因为flannel host-gw模式的话,它是它比那个calico的话多了一个cni0网桥。然后第二个的话它是它的那个叫所有的路由的话,路由信息就是都是存到那个ETCD数据库的。一般ET数据库它的压力还是比较大的。所以的话如果都存到ETCD库的话,会增加了这个数据库的一个压力。

Calico

Calico的话它是每个节点的话都是会运行一个BIBD,那个也是一个进行破的。它是会将每个节点的一个每个节点的一个路由信息进行一个共享。然后再通过那个BGP建立这个路由条目的。

然后Calico的话它也是进行可以主要是进行一个它主要是也可以进行一个二层通信。它也是跟host-gw模式一样,也是把下一条的通过路由判决,把下一跳的目标主机的话当成一个网关,进行一个跨节点通信。但是如果是如果要要进行那个叫做三层通信的话,Calico也是可以做到的。也是就是将沿途的这个叫做交换机的话配上这个路由条目,它就可以进行一个三层的一个通信。

然后Calico的话它是因为它是不需要分包解包的,所以的话它是比较适合大规模的一个集群来使用的,效率也会比较高一点。


7. 集群规模和架构

面试官问:维护的K8S集群是基于公有云还是自建?规模多大?

上一家公司的话是阿里云IDC机房。第二家公司的话是自己建的机房。

规模

我们可以,我们就是我们是有SaaS自己的SaaS平台,还有那个叫高校的话,一般是会私有化部署。

那像我们自己的那个SaaS平台的话,是有五十多台机器。然后pod的话大概是有四百多个pod。像客户那边的话,因为只有上部分的微服务,所以的话他的那个机器的话只有十多台一个情况。

功能

自己的这种SaaS平台都有什么功能的?这里面是参与到开发还是用手?

您说我就是这个SaaS平台的话,我主要是负责哪一些内容吗?

就是我们这个K8S集群的话,它一个是主要是有一个AI的一个视觉分析,还有教务教学系统,还有那个叫做人脸识别。然后这上面用户用的比较多的就是K12的一个学校,因为他们没有进行一个私有化。


8. 多集群管理平台

面试官问:有集群管理PaaS平台吗?

集群管理的一个PaaS平台集群。您是说多集群管理还是就单机群也可以,有没有这样的一平台吗?

哦哦哦明白了,我们用的是Kuboard。

Kuboard它是通过是不是K8S它是通过那个它上面是K8S它不是有那个凭证的,然后我们只要是把这个凭证上传到这个管理这个工具当中,它就可以进行一个远程的管理,就会得到。然后我们部署,查看,都是可以通过这个平台。然后它也可以也可以进行那个RBAC权限的一个管理。

选型

那你们是怎么选定的这个?这种的话管理平台应该有很多。

是怎么选型选择这个?

选型选择我们公司之前就是用这个。我觉得应该是它偏轻量级,有一些公司也是也会自研,但是这个好像比更好用一点。

Kuboard的话它是一个免费的还是收费的?

就是开源免费的。


9. K8S集群优化

面试官问:K8S集群做过什么优化?

K8S集群的一个优化说我有做过虚拟化的一个优化,就是引入那个哈密。还有什么优化?也有引入那个灰度发布Istio,还有也有用过那个扩容,你们应该也会用吧,就是HPA进行一个扩容。然后本身的一个特性,对对本身一个对本身一个特性。

对,这个不算优化。只是因为那个GPU的话,它是因为它本身的话只是那个服务的话,只是扩充中只是基于那个CPU跟那个内存磁盘这些的,然后就没有支持那个GPU的。所以我们所以我刚才想说的是这一点。

vGPU虚拟化

对,然后你们什么场景的话,就是说这个虚拟化是需要一个哈密的。

主要是因为他那个英伟达它只是显存切分的话,它没有没有那么细颗粒度。所以我们引入的这个哈密的话就是可以根据定制化的进行一个显存的一个选择。


10. GPU运维经验

面试官问:AI相关业务,GPU接触怎么样?

之前有过像这种AI的应用,或者说对于GPU接触的同样的GPU的话。

首先的话像GPU,像是AI视觉分析师,分析学生上课的一个情况。所以的话我主要是负责这个集群的一个管理。也会遇到一些问题。然后也就是引入刚才您刚开始问的那个GPU的一些问题。

然后也用那个python的话,不对普罗米修斯的话去做那个叫做一个监控。


11. GPU XID错误排查

面试官问:GPU XID错误遇到过吗?

大概介绍一下就好了。

XID我倒是有遇到过一个XID就是您说这个问题,我是遇到了一个XID94,主要是因为它一个调款的一个问题。

我可以跟您说一下。

大概介绍就是他是他调款之后,不是叫GPU利用率,它是持续为零,pod也没有挂掉。然后他是叫用那个describe去看一下这个节点情况的话,他那个总资源的话只有六张卡,但是可利用的就四张卡。那说明Kubelet的话他认为四张卡可以用的。然后我用那个英伟达snm去看了一下,就发现没它的都是能显示出六张卡的,是那个叫做驱动层面是没有问题的。

所以我就是是后面的话我就是显示不是那个哈密驱动插件上报有问题吗?然后我去看了一下,这个日志的一个报错,它就显示一个叫做驱动层面,健康检查有错误,就是XID的这个错误。然后我去看了,我去查了一下这个错误。他主要这个错误是毫秒级去叫做触发一次的。

然后如果被那个Kubelet要去捕获到的话,那么他就会它就就会就会被那个哈密驱动插件的话认为这张卡它是不健康的,然后就会被上报给那个Kubelet,Kubelet的话就会把这个allocatable,从把这张卡从那个节点中剔除掉,就不可以去进行一个调度了。

然后进一步的去看了一下这个XID错误出现,它是驱动层面的一个错误。然后就现在这次。


12. 进程状态与问题处理

面试官问:介绍一下D进程、僵尸进程、孤儿进程?

监视进程、守护进程跟孤儿进程对吗?

好,首先我我说一下那个D进程的进程的话,如果就平均负载比较高的话,那么就可以去看一下到底是是CPU大进程多还是D进程多。如果是D进程多的话,很可能就是IO这个磁盘堵死是有问题的。然后它是不可中断睡眠。所以的话也是kill不掉的。

它的监视进程的话也就是它的那个父进程是没有进行及时的一个回收。它其实其间有发生监视进程,其实也不是不是特别大的问题。但是如果持续的一个有监视进程的一个产生的话,他可能会把PID给那个资源给用完。

所以的话如果出现这个监视进程的话,是可以在发送信号给到父进程进行一个回收。如果父进程没有回收的话,那么如果父进程死掉,然后就会给那个init进程进行一个接管。然后init它是可以进行回收的。

然后现在我们比如我们去构建这个镜像的时候,尽量不要使用这个多进程。一般建议使用一个进程就够了。如果一定要引入多进程的话,就用那个supervisor的那个进行一个管理,能够正确的处理这个监视进程和信号。

然后还有孤儿进程,孤儿进程的话它主要是就是父进程,已经掉了。但是但是他的子进程还是存在的。如果有孤儿进程的话,那么他就是会被init进行一个接管。大概就是这样,我不知道有没有说全。


13. MySQL Operator开发

面试官问:开发经验具体介绍一下?

开发方面的话,我主要是用那个叫做python写过那个web hook,以及用那个go写过Operator控制器。然后我可以跟你先说一下这个Operator控制器。

这个Operator控制器主要是我们有有一些客户不是私有化。然后如果按照之前的那个,我们是之前的话,我们公司的话是有部署的RDS,这样性能也会比较好一点。但是如果这个MySQL它挂掉的话,那么它就会我们需要去现场进行一个处理。

因为我们学校都是内网的,所以我们决定去开发这个MySQL Operator,这样子的话就可以减少一些运维的一个成本。

然后我整体的设计的话是一主多从,然后用那个Operator SDK去引入这个,做了这个Operator。然后实现的主要是实现组装,高可用切换,还有自动调节以及读写分离。

然后整体的话我是参考了那个RDS架构。但是这个RDS架构它主要是用的是Raft的协议,它就是主观判断加客观判断,然后会有一定的延迟,而且它必须三个节点以上,而且如果一半的节点挂掉了,它就是不可以用了,所以我这一方面是没有参考。

然后是用的是K8S的一个原生特性,然后是用的endpoint加上那个就绪探针的检测,进行判断这个主库是不是你。


14. 中间件使用

面试官问:中间件这块用什么比较多?

中间件的话我主要是有用MySQL、Redis,还有那个安全LVS,然后还有那个叫做Kafka这几块的。

还有就是四层负载均衡LVS,还有engine ingress主要是做七层的。


15. 脑裂问题

面试官问:介绍一下脑裂以及如何避免?

然后脑裂问题的话,就是我有遇到过脑裂问题。主要是用那个Keepalived,就是给到LVS做高可用的时候,它是会发生脑裂问题的。

主要是他那个叫做因为网络分区的一个原因,就是造成他们就是通不是蓝图问题,他是那个网络他就是抖动,然后造成那个网络不通了。然后他他就是有了两个VIP,然后就造成了脑裂,然后同时有两个VIP的话去接收外部的一个请求。


16. 服务发现和DNS

面试官问:Pod之间怎么发现彼此?

无头Service

无头Service它是是这样子,如果要使用无头Service的话,首先要满足经验,就是要先设置clusterIP为none。然后它并且的话这个pod的编号它必须是固定的。

所以它这个无头模式的话是必须是使用这个有状态的一个服务。然后它进行一个靠DNS进行解析的时候,它就不会去解析到那个叫做Service的那个IP。它只会解析到那个pod的IP,然后自己再去配置这个负载均衡策略。

Service类型

然后Service的4种模式的话,它是有ClusterIP,NodePort,LoadBalancer,还有ExternalName。

ClusterIP它是进行一个矩形内的一个访问。然后NodePort可能IP设置为none的话就是可以进行一个无头Service。然后无头Service它是必须配置跟这个有状态服务进行搭配使用的。

然后LoadBalancer的话这个类型的话只是云服务上是可以使用这个类型的。然后它是在那个叫做主机上是可以进行一个映射的。然后ExternalName它是设置这个模式的话,它是会建这个叫做解析成那个外部域名的。如果要访问外部域名的话,就可以设置成这个模式。


17. 网络策略

面试官问:如何隔离不同团队的Pod?

QoS等级

QoS等级有三种。

首先最低等级的话是不是BestEffort,它是比较不靠谱的。然后不是很靠谱它是通过limits跟request。如果都是在那个样本清单,如果提交的时候都是没有设置的话,那么它就是就会变这个等级。

然后如果提交样本清单,如果都有设置limits跟request的话,那么就是Guaranteed。然后如果介于这两者中间的话,就是Burstable。

优先级

然后优先驱逐的话,一般优先驱逐的就是不是Guaranteed的,就是BestEffort。


总结

本文完整还原了K8s运维工程师的技术面试,涵盖:

  • 架构设计:跨地域集群迁移、CICD改造
  • 核心原理:Pod创建流程、Flannel网络
  • 运维实践:GPU运维、进程问题处理
  • 开发能力:MySQL Operator开发
  • 网络:服务发现、NetworkPolicy
  • 高可用:脑裂问题处理

希望对准备K8s运维面试的读者有所帮助。

分享

// RELATED_POSTS

0%