大家好,我是秋意零。今天分享一篇小米运维面经。
小米K8s运维-云原生方向
一面
2024年4月3日 | 10点 | 一面 | 40 min 左右
1)自我介绍
2)你熟悉Python多一点吗?还熟悉其它语言吗,拿出来写过的?
3)你是软件工程专业,为啥JAVA用的不多呢,没写过对应项目?
4)运维是自己学到吗?
5)运维通过什么样子方式学习?
视频、官方文档、比赛
6)我们坦诚的说,去参加过培训班吗?
7)OpenStack是你自己搭建的吗?
8)OpenStack有几个关键组件?
keystone、glance、neutron、nova、cinder、swift、dashboard
9)搭建过程中有遇到什么问题吗?
OpenStack组件之间的关联性比较强,开始接触是特别容易不好理解和搭建错误
10)OpenStack的版本是根据什么排的?你用的那个版本?
A、B、C... 字母排序。用的 Q 版
11)实习经历:优化云资源是做的什么?
资源下线
12)资源的线下,如何判断他的资源上下游关系呢?如果查看进程的话,如何判断是咱们自己写的应用?
查看服务器进程相关性、查看服务端口是否建立了连接
13)K8s的东西了解的很多吗?
14)镜像跟容器的关系
镜像是容器的静态表现形式,也是一个容器模板,具有打包解决项目的依赖问题
容器是镜像的动态表现形式,容器本质是一个进程,通过Linux NameSpace技术镜像隔离
15)我们想制作一个镜像,大概有几种方式?
Dockerfile、docker commit
16)使用过Dockerfile打包过镜像吗?
17)Dockerfile里面的CMD什么意思?
CMD是容器的启动命令。注意:docker run 时可以替换掉CMD指定的命令。如果指定ENTRYPOINT,这个启动时不能替换(除非用户使用
--entrypoint
选项明确覆盖)。
18)K8s还了解什么?有创建过Deployment、StafulSet,有使用过吗?
19)K8s集群中将服务暴露出去,不区分是集群内还是集群外,有几种方式(加分项)
- NodePort方式 :
- NodePort方式通过在每个节点上绑定一个端口,将服务暴露到集群外部。当外部流量通过该端口访问时,流量将被转发到对应的服务。
- 优点:简单易用,无需额外的网络组件。
- 缺点:需要公开节点上的端口,不适用于大规模集群和安全性要求较高的场景。
- LoadBalancer方式 :
- LoadBalancer方式通过云服务提供商(如AWS、Azure、GCP)提供的负载均衡器将服务暴露到集群外部。负载均衡器会自动分配一个外部IP地址,并将流量转发到对应的服务。
- 优点:适用于公有云环境,自动管理负载均衡器。
- 缺点:依赖云服务提供商的负载均衡器,可能会带来额外的费用。
- Ingress方式 :
- Ingress方式通过Ingress资源定义来将服务暴露到集群外部,通过将流量路由到不同的后端服务来实现应用程序级别的路由和负载均衡。
- 优点:支持应用程序级别的路由和负载均衡,可以根据域名和URL路径进行流量路由。
- 缺点:需要额外的Ingress控制器来管理Ingress资源,并且在一些场景下性能可能不如NodePort或LoadBalancer方式。
- ExternalName方式 :
- ExternalName方式通过创建一个Service,并指定外部服务的域名,将外部服务映射为Kubernetes内部的一个Service。这样,其他服务可以通过该Service来访问外部服务。
- 优点:简单易用,适用于访问外部服务的场景。
- 缺点:只能用于访问外部服务,无法提供给外部服务访问。
- 使用Service Mesh (加分项):
- 使用Service Mesh(如Istio、Linkerd)可以实现更灵活和可靠的服务暴露方式。Service Mesh通过Sidecar代理来管理服务之间的通信,可以提供服务发现、负载均衡、流量控制等功能,并支持灵活的流量路由和安全策略。
- 优点:提供更丰富的功能和更灵活的流量控制,支持多种部署环境。
- 缺点:部署和管理较复杂,需要学习和配置Service Mesh的相关组件。
20)开发题目:两数求和,数组 nums = [2,7,11,8] target = 9。输出 [0,1] 因为 nums 数组里面 2 + 7 等于 9,取出下标。
python
def two_sum(nums, target):
# 获取数组的长度
length = len(nums)
# 遍历数组中的每个元素
for i in range(length):
# 对于当前元素,遍历其后面的元素,与其相加判断是否等于目标值
for j in range(i+1, length):
if nums[i] + nums[j] == target:
# 如果相等,返回两个元素的索引
return [i, j]
# 如果没有找到符合条件的两个数,则返回空列表
return []
# 测试
nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target)) # 输出 [0, 1]
反问:
1)该岗位一天的工作情况是怎样的?
答:维护小米K8s集群,集群规模80个左右,node节点10000个左右。集群维护和自动化(如:自动巡检,自动缩放容)工作55开
2)该岗位对应届生更偏向看重什么技能?
算法、代码能力
二面(他人)
1)栈和堆的区别?哪个需要手动释放?(√)
栈是静态数据。
大小固定,因为编译器字符都是确定好的。
占用的内存是在代码编译前存在的。
堆是动态数据。大小不固定,因为我们程序某一刻的操作是不一样的,有点占用少,有的占用多。
占用的内存是在代码运行是存在的。而堆内存是可以手动释放的(调用某个函数,如:free() )
2)closewait是在哪?(√)
Close Wait(关闭等待)是指在TCP连接的一端发送了关闭连接的请求后,等待另一端发送关闭连接的确认。这种状态发生在TCP连接的关闭过程中。
意义就是,等待对方确认收到信息后才正式关闭。
3)Https为什么要用对称加密,一直非对称加密不可以吗?(不知道怎样才对)
对称加密:对称加密算法相对于非对称加密算法来说,加解密的速度更快、效率更高,因为它使用相同的密钥进行加解密。这使得对称加密在传输大量数据时更加高效。
非对称加密:非对称加密算法具有更高的安全性,因为它使用了公钥和私钥两种密钥 ,能够实现安全的密钥交换和数字签名等功能。使用公钥加密,使用私钥解密
4)配置证书需要在客户端和服务端都配置吗?(不知道怎样才对)
配置证书通常是在服务器端完成的,而不是在客户端。在HTTPS通信中,服务器需要配置SSL/TLS证书,而客户端则会验证服务器提供的证书。
5)怎么确保K8S集群的稳定性?(监控,容量,二进制部署)
版本管理和升级:
- 定期进行Kubernetes版本的升级,以获取最新的功能、性能优化和安全修复。
- 在进行版本升级前,先在测试环境中进行充分测试,确保新版本的稳定性和兼容性。
故障恢复和自愈:
- 配置和监控 Kubernetes集群的自愈机制 ,如自动重启、自动扩容等,以保证集群在面临故障时能够快速恢复。
- 使用故障域和多可用区部署来提高集群的容错性,确保集群在部分节点或区域故障时仍能正常运行。
监控和警报:
- 配置监控系统,监控集群的健康状态、资源利用率、性能指标等。
- 设置警报规则,及时发现集群中的异常情况,并采取相应的措施进行处理。
配置管理和自动化:
- 使用配置管理工具(如Ansible、Terraform等)来管理Kubernetes集群的配置,确保集群的一致性和可重现性。
- 自动化部署、扩容、缩容等操作,减少人工干预和人为错误。
安全性:
- 实施安全最佳实践,包括访问控制、身份认证、加密通信等,保护集群免受恶意攻击和数据泄露。
- 定期审计集群的安全配置,及时修复潜在的安全漏洞和风险。
持续优化:
- 定期评估集群的性能和资源利用情况,对集群进行调优和优化,以提高性能和资源利用率。
- 分析和解决集群中的瓶颈和性能问题,持续改进集群的稳定性和可靠性。
6)那你觉得你列出的这些指标哪个最重要?(gg)
略
7)那你觉得监控需要监控啥?(gg)
- 节点健康状态 :
- 节点的在线状态:监控节点是否处于正常的在线状态,避免因节点故障导致服务中断。
- 节点资源利用率:监控节点的CPU、内存、磁盘等资源利用率,避免资源不足导致性能下降或故障。
- 容器健康状态 :
- 容器运行状态:监控容器的运行状态,包括运行中、已停止、异常等。
- 容器资源利用率:监控容器的CPU、内存、网络等资源利用率,避免资源竞争和过度分配。
- 服务可用性和性能 :
- 服务运行状态:监控服务的运行状态,包括可用性、响应时间、错误率等。
- 服务负载均衡:监控服务的负载均衡情况,避免单个节点或Pod负载过重。
- 集群组件状态 :
- API服务器状态:监控Kubernetes API服务器的健康状态,确保集群API的可用性。
- 控制器管理器状态:监控控制器管理器的运行状态,确保集群控制器的正常工作。
- 存储和网络 :
- 存储状态:监控存储卷和持久化存储的状态,确保存储服务的可靠性和性能。
- 网络连接和流量:监控网络连接数、流量情况等,确保网络的稳定性和安全性。
- 安全性 :
- 审计日志:监控集群的审计日志,跟踪操作和事件,发现异常行为和潜在安全威胁。
- 安全配置:监控集群的安全配置,确保符合安全最佳实践,防止安全漏洞和攻击。
8)K8s的Pod的创建过程?K8s调度器是怎么知道要调度的?(√)
- Pod的创建过程 :
- Step 1: 定义Pod配置文件:用户定义Pod的配置文件,包括Pod的名称、容器镜像、端口映射、资源需求等信息。
- Step 2: 提交Pod配置:用户通过kubectl等工具将Pod的配置文件提交到Kubernetes集群的kube-apiserver。
- Step 3: 配置验证:kube-apiserver验证Pod配置文件的合法性,包括配置的格式、内容等。
- Step 4: 创建Pod对象:验证通过后,kube-apiserver将Pod配置保存到etcd中,并创建Pod对象。
- Step 5: 分配Pod IP:kube-controller-manager监控到新创建的Pod对象后,通知kubelet为Pod分配IP地址。
- Step 6: 调度Pod:kube-scheduler根据Pod的资源需求、节点资源情况等信息,选择合适的节点进行调度。
- Step 7: 在节点上创建容器:kubelet接收到调度器的调度请求后,在选定的节点上创建Pod中定义的容器。
- 调度器的工作原理 :
- 获取Pod信息:kube-scheduler通过kube-apiserver获取集群中所有未调度的Pod信息。
- 评分算法:kube-scheduler对每个未调度的Pod进行评分,根据Pod的资源需求、节点资源情况、节点亲和性、亲和性和拓扑约束等因素,为每个节点打分。
- 选择最佳节点:kube-scheduler选择评分最高的节点作为Pod的调度目标。如果多个节点的评分相同,调度器可能会随机选择其中一个节点。
- 调度结果通知:调度器将调度结果写回kube-apiserver,并通知kubelet在选定的节点上创建Pod中的容器。
9)K8s创建容器的原理?(√)
- 用户提交Pod配置 :
- 用户通过kubectl或其他方式提交Pod的配置文件到kube-apiserver。
- 验证配置 :
- kube-apiserver接收到Pod配置后,会验证配置的合法性,包括格式、内容等。
- 调度Pod :
- kube-scheduler根据Pod的资源需求、节点资源情况等信息,选择合适的节点进行调度。
- 通知kubelet :
- 调度器将调度结果写回kube-apiserver,并通知相应节点的kubelet。
- 拉取镜像 :
- kubelet接收到调度器的通知后,开始从镜像仓库中拉取Pod配置中定义的容器镜像。
- 创建容器 :
- kubelet使用容器运行时(如Docker、containerd等)在节点上创建Pod中定义的容器。
- 容器运行时根据容器镜像的元数据创建容器实例,包括设置容器的网络、文件系统、进程等环境。
- 监控和报告 :
- kubelet监控容器的运行状态,并定期向kube-apiserver报告Pod和容器的状态。
- 更新状态 :
- kube-apiserver接收到kubelet的状态报告后,更新集群中对应Pod和容器的状态信息。
10)K8s的informer机制知道吗?写过Operator和Controller吗?他们俩的区别?Operator只用来部署的吗?(gg)
Informer是Kubernetes中的一种机制,用于实时监控和跟踪集群中对象(如Pod、Service、Deployment等)的变化,并将这些变化通知给客户端。它通过与kube-apiserver交互,监听资源对象的变化,然后将这些变化通过回调函数等方式通知客户端。
关于operator和controller,它们都是Kubernetes中的控制器,用于实现自动化管理和操作集群中的资源对象。它们之间的主要区别在于目标和功能:
- Controller :
- Controller是Kubernetes中的一种核心组件,用于监控和管理集群中的资源对象,确保资源对象处于所需的状态。
- Controller通常是通过编写自定义的控制器逻辑来实现特定的管理功能,如ReplicaSet、Deployment等控制器。
- Controller负责监控集群中的资源对象,根据预设的规则和策略,自动进行资源的创建、删除、伸缩等操作,以实现应用的自动化部署和管理。
- Operator :
- Operator是Kubernetes中的一种特殊类型的控制器,它通过自定义资源(Custom Resource)和控制器逻辑来扩展Kubernetes的功能。
- Operator不仅可以监控和管理Kubernetes核心资源对象,还可以监控和管理自定义的资源对象,以实现更加灵活和定制化的操作。
- Operator通常用于自动化管理复杂应用的生命周期,如数据库、消息队列、监控系统等,它们可以实现诸如自动扩容、故障恢复、配置管理等功能。
11)进程和线程的区别?(还行)PCB里有什么?线程共享的(g)
- 定义 :
- 进程(Process)是程序的一次执行过程,是资源分配的基本单位,包括程序、数据集、内存空间、文件和设备等。
- 线程(Thread)是进程中的一个执行单元,是CPU调度的基本单位,共享进程的资源,包括内存、文件和设备等。
- 拥有资源 :
- 进程是独立的执行环境,拥有独立的内存空间、文件描述符和其他系统资源。
- 线程共享所属进程的内存空间、文件描述符等资源,线程之间可以方便地进行通信和共享数据。
- 切换开销 :
- 进程之间的切换开销较大,需要保存和恢复较多的上下文信息,如CPU寄存器、内存页表等。
- 线程之间的切换开销较小,因为它们共享同一个地址空间和其他资源,切换时只需保存和恢复少量的上下文信息。
- 创建和销毁 :
- 创建和销毁进程的开销较大,包括分配和释放内存空间、建立和销毁进程控制块(PCB)等。
- 创建和销毁线程的开销较小,因为它们共享进程的资源,创建和销毁时只需分配和释放线程的控制块即可。
- 并发性 :
- 进程之间是相互独立的,各自拥有独立的执行环境,因此进程可以并发执行。
- 线程共享进程的资源,可以在同一个进程内并发执行,共同完成任务。
PCB(Process Control Block)是操作系统中用于管理进程的数据结构,存储了进程的状态、优先级、程序计数器、CPU寄存器、内存分配情况、打开文件等信息。PCB中存储了进程的上下文信息,操作系统通过PCB来管理和调度进程。
12)进程通信的方式?里面哪些涉及内核?(半gg)
- 管道(Pipe) :
- 管道是一种半双工的通信方式,通常用于具有亲缘关系的父子进程之间进行通信。
- 管道可以是匿名管道(由pipe系统调用创建)或有名管道(由mkfifo系统调用创建)。
- 命名管道(Named Pipe) :
- 命名管道是一种特殊类型的文件,可用于任意两个进程之间的通信,即使它们没有亲缘关系。
- 命名管道通过mkfifo系统调用创建,可以在文件系统中以文件的形式存在。
- 信号(Signal) :
- 信号是一种异步的通信方式,用于通知进程发生了特定的事件,如中断、异常等。
- 进程可以通过系统调用kill向另一个进程发送信号,也可以通过signal系统调用设置信号处理函数。
- 消息队列(Message Queue) :
- 消息队列是一种消息传递机制,允许一个或多个进程向队列发送消息,并从队列中接收消息。
- 消息队列由消息队列标识符标识,进程可以使用系统调用msgget、msgsnd和msgrcv来创建、发送和接收消息。
- 共享内存(Shared Memory) :
- 共享内存是一种高效的进程通信方式,允许多个进程共享同一块物理内存区域。
- 进程可以通过系统调用shmget、shmat和shmdt来创建、附加和分离共享内存区域,实现共享数据的读写。
- 信号量(Semaphore) :
- 信号量是一种用于进程同步和互斥的同步原语,常用于解决资源竞争和临界区问题。
- 进程可以通过系统调用semget、semop和semctl来创建、操作和删除信号量。
13)客户网页访问不通,如果无法登录机器如何排查?(√)
- 首先通过监控了解资源(网络、CPU、内存、磁盘读写)占用情况,如果是资源占用过高,可通过监控看到是否为某个时间节点突然增长,如果是就接着判断是访问量突然增长还是执行了某个程序导致的。
- 浏览器访问到问题的网页,F12查看网络接口请求情况,是所有接口还是部分接口,根据返回的信息和状态码进行分析。
14)如果发现服务很慢,进机子后怎么排查?那如果发现cpu不高还是卡怎么办?(io、内存、cpu、网络)
- 查看服务器资源占用和网络情况
- 浏览器访问服务,按F12根据接口排查
- 是否为查询数据库时慢
- web页面程序设计逻辑的问题的,程序存在死循环导致
15)监控的直方图了解吗?几种数据类型知道吗?P95、P90知道是什么吗?(gg)
监控的直方图是一种用于可视化数据分布情况的图表形式,它将数据按照一定的区间划分,并统计每个区间内数据的频数或频率,然后将这些数据以直方图的形式展示出来。通过直方图可以直观地了解数据的分布情况,包括数据的集中程度、波动程度等。
在监控系统中,常见的数据类型包括:
- 计数器(Counter) :
- 计数器用于记录某个事件发生的次数,如请求数、错误数等。计数器的值只会单调递增,不会减少。
- 计时器(Timer) :
- 计时器用于记录某个事件的耗时,如请求处理时间、接口响应时间等。计时器通常会记录每次事件的耗时,并计算出平均耗时、最大耗时、最小耗时等统计信息。
- 测量值(Gauge) :
- 测量值用于记录某个指标的实时数值,如CPU使用率、内存使用量等。测量值的值可以随时间变化,可以是任意数值。
P95(Percentile 95)和P90(Percentile 90)是常用的统计指标,用于描述数据集合的分布情况,表示在数据集合中有多少比例的数据小于或等于该数值。具体来说:
- P95表示在数据集合中有95%的数据小于或等于该数值,即95%的数据点的值低于或等于P95的值。
- P90表示在数据集合中有90%的数据小于或等于该数值,即90%的数据点的值低于或等于P90的值。
P95和P90等百分位数常用于描述数据的尾部分布情况,可以帮助我们了解数据集合中的长尾情况和异常值情况。在性能监控中,P95和P90通常用于衡量系统的性能稳定性和服务质量。
16)有写过什么脚本吗?
略
13)两道算法题
略