【面试】02 k8s
面试题:https://blog.csdn.net/crazymakercircle/article/details/128671196
k8s 是什么
是一套容器编排系统,可以对基于容器的应用、服务实现全生命周期的管理。包括应用部署、更新、监控、扩缩容等。
介绍下 k8s 的基础组件
组件有什么
master: kube-scheduer, kube-apiserver, kube-controller-manager
node: kubelet, kube-proxy
其他:etcd(可以独立于 master 节点),coredns
各个组件作用
kube-apiserver: 所有组件的通信,都会经过 apiserver
kube-scheduler: 调度集群资源。检测到有pod需要调度,就会进行筛选、打分、绑定node。
kube-controller-manager: k8s 自动化能力(部署、更新、扩缩容)的核心。像:deployment/replication/endpoint controller
etcd: key-value 数据库,保存 k8s 资源对象的信息。集群个数一般为奇数个(仲裁选举容错模式)。
kubelet:
- 监听apiserver,如果有本机的需要启动的pod,就会启动
- 管理 本机Pod 的生命周期
kube-proxy: 实现 node 上 pod 的网络通信能力。主要通过 iptables,还有 ipvs
coredns: 实现 k8s 内部 svc 和 pod 的域名解析
k8s 基础概念
master: 管理节点
node: 工作节点,或叫 worker
工作负载:工作负载就是应用程序,应用程序就是一组 pod,不过一般不直接管理 pod,而是通过 deployment, daemonset, stateset, job/cronjob 等进行管理
Namespace: 不同 namespace 的资源(工作负载)是隔离的。
pod: k8s 的最小调度单元,一个 Pod 可以有多个容器,这些容器共享相同的 Namespace, 网络,端口,可以通过 Localhost 访问。debug 时候就利用的这一点。
- 探针:启动、存活、就绪。(存活和就绪两个探针的检测条件一样,但是处置方法不一样)
service: pod 的 ip 会因为 pod 异常而变化,所以用 service 来进行统一入口,四层的负载均衡
- 四种 service 类型:cluster ip(默认), node port, load balance, external name
endpoint: service 和 Pod 并不会直接相连,中间有一层 endpoint,来记录 ip,port
ingress:service 是四层的,实际中,需要一个七层的代理,他就是干这个用的。ingress - service - endpoint - pod
deployment: 无状态应用通过它管理(web)。动态控制 Pod 的属性(镜像)、状态(个数–扩缩容(rs, rc),),有了 deployment,不再用 rc,改为deployment + rs。
replication controller:被 deployment + rs 替代了。
replicaSet:一般不直接操作,通过修改deployment来控制它。
statefulset:有状态应用通过它管理(mysql)。
job: 一次性任务
CronJob:定时任务
label: 标签,K8s 通过标签筛选资源
存储:
- Volume:跟 pod 的生命周期保持一致,一个 pod 对应一个 volume
- pv:独立于 pod 的生命周期,一个 pv 对应一个 volume
- pvc:PVC 是一个声明,有了 PVC,k8s 会用现成的 PV,或者创建一个 PV 来供 pod 使用
- storageclass: 是为了减少人工而去自动创建pv的组件
自动扩缩容:
- HPA:pod 横向扩容,增加 pod 个数。cpu 利用率,qps。
- VPA:pod 纵向扩容,增加 pod 资源。
CRI: containerd, docker
CNI: Flannel, Calico
CNM:docker 公司的
CRD:自定义资源。很多组件都是自定义资源。
DNS:servicename.namespace.svc.cluster.local, pod-ip-address.namespace.pod.cluster.local
IPVS:是 linux 提供网络负载均衡的内核模块,kube-proxy 的网络模式有两种 iptables(规则列表),ipvs(规则哈希表)。
Heapster:是k8s原生的监控方案。heapster以pod的形式运行,从kubelet获取监控数据,kubelet从cAdvisor获得数据
pod 相关问题
pod 定义
pod 是 k8s 最小操作单元,一个 pod 可以包含多个容器,这组容器的有网络、存储资源是共享的,比如可以通过 localhost:port 来访问彼此。
pod 共享资源
- pid namespace
- network namespace: ip, port
- IPC namespace: inter-process communication. different containers in one pod can communicate with each other;
- UTS namespace: UNIX Time Sharing, hostname, domain,
- pod volumes
pod init container
先于应用容器的容器,必须成功退出,才会往下执行
一个 pod 可以有多个 containers,也可以有多个 init containers。
作用:
- 依赖检查。如数据库是否准备完毕
- 配置准备。放到emptydir volume中
- 数据预热。将xx数据放到缓存中
- 等
pod pause container
pause container 相当于 pod 的根容器,它会在 init containers 启动完成后,所有 app containers 启动前启动。
作用:
- 创建共享的 namespace(ipc, uts, net, pid),
- pod 级别 volumes,
- 启动 init 进程,回收僵尸进程。
- 等
pod containers 启动顺序
init containers -> pause container(跟容器) -> app containers
pod command, args 与容器的 entrypoint 怎么运行
覆盖关系。
command 不为空,会覆盖 entrypoint
command 为空,arg 不为空,会使用 Pod 的 args 执行 entrypoint
deployment创建 pod 流程
注:
- 过滤:根据 node selector, 申请资源匹配,节点亲和
- 打分:根据规则来的。比如资源使用率最低、同一个 service 拆开
- 选择 node
pod 销毁流程
- apiserver: 验证,修改 pod 对象信息。更新 etcd(宽限期,默认 30s)。状态为 Terminating。
kubelet watch apiserver:
- send sigterm(kill -14) to CRI(docker/containerd)
- run prestop hook(if exist)
endpoint controller watch apiserver:
- delete endpoint
kubelet (grace period expired):
- send sigkill(kill -9) to CRI
- response apiserver pod will delete immediatly
apiserver:
- delete pod from etcd.
terminating pod怎么办:
- –force –grace-period=0
- 修改pod属性:终结器finalizers
文档:
pod 的创建、销毁流程 K8s无法删除状态为terminating的pod解决方法
pod 的状态
Pending
持续 pending 的原因:
- 镜像 Pull 不下来
- 没有合适的 node
- pv, pvc 无法成功创建
- Running
- Successed
- Failed: failed at least one pod
- Unknown: may cause by network communicate problem
pod 怎么发现 service 的
- 环境变量:创建 pod 时,会把有效的 service 和 ip 的对应存到环境变量中
- CoreDNS:FQDN 来访问
聊聊 pod 通信机制
- pod 内容器间:lo 回环地址
- pod 间:overlay 网络(覆盖网络)
- pod 与 service:各 node 上的 iptables 或 ipvs
pod 的 SLA:QOS
QOS 就是在 node 资源不足的时候,清理 pod 的顺序。
三种 QOS(不被清理优先级从高到低):Guaranteed > Burstable > Best-Effor
- Guaranteed:所有容器,cpu 和 mem 的 request 和 limit 都一致
- Burstable:任一容器,cpu 或 mem 的 request 和 limit 不一致
- Best-Effor:所有容器,都没有指定 cpu 或 mem 的 request 和 limit
pod的oom机制
pod的oom与系统地oom不同,会先Kill掉 best effort, 然后是 burstable的,最后是 guarantee 的
标签相关
标签的理解
标签是 key-value 形式的键值对,可以附加在任何资源对象上,用于管理对象,匹配、筛选。
比如 deployment, service 和 pod 的匹配关系,就是通过标签选择器来实现的。
service 相关
如何创建一个外部 service,比如 mysql
- 创建一个没有 label selector 的 service,这样就不会创建 endpoint。但是其他信息要填写。比如 port 的端口号、名称、协议等等。
- 手动创建一个 endpoint。endpoint 中定义外部服务的 ip, 端口等。endpoint 的 name、port name, port protocol 要与 service 的一致。
service, endpoint, kube-proxy 三者的关系
- endpoint是一组pod的ip,port
- service是这一组pod的四层负载均衡的1个ip,port
- kube-proxy是将它们两个的对应关系转换为iptables,ipvs的规则,从而实现流量转发
无头 service
一般用于
- 为每个 Pod 创建了独立的 DNS 记录,主要用于有状态应用集群(redis/mysql/…)的集群内节点间的服务发现
- 客户端自行处理负载均衡。(如:mysql主从)
K8S 部署 Redis Cluster 集群(三主三从模式)
service流量分发策略都有什么
- 轮询 RoundRobin
- 会话保持 SessionAffinity
deployment 相关
扩缩容
- 修改 yaml:replicas
- kubectl scale
发布策略都有什么
deployment 自带:
- rolling update
- recreate
通过 deployment
蓝绿:
- 两个 deployment,修改 service 的 label selector
- 两套 service+deployment,修改 ingress
金丝雀:
- 最笨:启动相同 label 的 v2 pod,相当于通过 k8s service 自带的流量策略实现金丝雀
- ingress annotation 实现基于:cookie, header, 流量比例
- istio:todo
滚动发布的 2 个重要参数
- 更新过程中,最大不可用 Pod 数量:maxUnavailable
- 更新过程中,最大激增 Pod 数量:maxSurage
滚动发布的过程描述
- 增加 maxSurage 个新 pod
- 删除 maxUnavailable 个旧 pod
- 重复 1,2 两步,直到所有 pod 都为新 pod
任何时刻,都会保证:
- 至少(old - maxUnavailable)个pod可用
- 之多会有(old + maxSurage)个pod存在
- 新pod通过健康检查后,才会进行流量转移,老pod停止。
怎么回滚
rollout history 查看都有什么版本可以回滚
rollout undo 进行回滚
存储相关
Volume
生命周期与 pod 相同
常见的 volume 类型:
- emptyDir:空目录
- hostpath:不常用
- configmap:不加密配置
- secret:加密配置
- pvc:持久存储声明
- 网络存储:nfs
PersistentVolume 的意义
pv 存在的意义就是:
- 更加灵活地管理存储,
- 解耦存储的管理和应用的管理。
PV 访问模式
- 单节点读写 RWO
- 多节点只读 ROX
- 多节点读写 RWX
pv 怎么扩容
主要看 storageclass 的 allowVolumeExpansion 字段。true/false
PVC 的意义
PVC 是应用定义 yaml 中使用的
PV 是运维人员管理的
storageclass
sotrageclass 就是为了减少人工而去自动创建 pv 的组件。
K8S 快速入门(十六)实战篇:StorageClass(存储类) 大白话说明白 K8S 的 PV / PVC / StorageClass
node 相关
node 调度都有什么
cordon(警戒)
影响:
- 不允许新的,已有 pod 保留;
如何恢复:kubectl uncordon node_name
drain(驱逐)
影响:
- 驱逐已有 Pod,调度到其他 node 上;
- 不允许新的。
如何恢复:kubectl uncordon node_name
delete(删除)
影响:
- 驱逐已有 Pod,调度到其他 node 上;
- 从 master 节点删除该 node,master 不可见该节点
如何恢复:
- master 不可恢复这个 node
- 利用节点自注册功能:重启 node kubelet。
taints(污点)、Tolerations(容忍)
污点:给 node 增加污点:key:[value:]effect
- kubectl taint nodes k8s-node01 check=zhang:NoSchedule
- effect: 不调度、优先不调度、不调度且驱逐已有的
容忍:给 pod 增加容忍:
- 特殊:tolerationSeconds:当可以容忍 NoExecute 的污点,但是对应时间后会被驱逐
Affinity(亲和)、AntiAffinity(反亲和)
因为有硬/软亲和、节点/pod 亲和,所以,共有如下几种情况:
- 节点硬亲和,节点软亲和,节点硬反亲和,节点软反亲和
- 节点硬亲和,节点软亲和,节点硬反亲和,节点软反亲和
总的来说:
亲和:与已有的 pod 在一起。
- 节点亲和:根据节点的标签,来决定亲和/反亲和此节点
- Pod 亲和:如果 A 拓扑域,已经运行了满足 labelselector 的 pod,则亲和/反亲和此拓扑域。
- 硬亲和:必须亲和/反亲和此节点/拓扑域
- 软亲和:优先亲和/反亲和此节点/拓扑域
TopologyKey(拓扑域)
拓扑域:就是拥有相同 label(key & value)的一组 node,称在一个拓扑域中。
topologySpreadConstraints(拓扑分布约束)
根据指定的 TopologyKey,来定义偏移量限制
kubelet 的 node 监控怎么实现的
- metrics-server:提供 kubectl top api 数据。
- cAdvisor:容器监控组件
etcd相关
简单介绍下etcd
etcd是一个高可用的、分布式的key-value数据库。Go语言编写。
主要用于共享配置和服务发现。
v2是纯内存,v3实现了数据持久化。
数据一致性使用的是Raft共识算法。
官网介绍,10w+并发
etcd使用场景
- 服务发现
- 一致型共享机制
- 消息发布与订阅
- 分布式锁
- 分布式通知
etcd 性能优化
controller相关
都有哪些controller
Node Controller:监控节点的状态,负责在节点不可用时执行相应的操作,例如将Pod标记为不可调度、在节点无法通信时驱逐Pod。
Replication Controller:确保指定数量的Pod副本在任何时候都在运行。如果Pod被删除或崩溃,Replication Controller会创建新的Pod来满足副本数要求。
Endpoint Controller:填充Endpoints对象,使服务能够正确地找到相应的Pod,确保服务与后端Pod之间的通信。
Service Account & Token Controllers:创建默认的Service Account并管理API访问令牌,确保每个命名空间都有一个默认的Service Account。
Namespace Controller:处理命名空间的创建和删除,确保在删除命名空间时清理相关资源。
Job Controller:管理Job对象,确保Job中定义的任务(Pod)按预期运行和完成,适用于一次性任务或批处理任务。
CronJob Controller:管理CronJob对象,按照预定义的时间表周期性地运行Job。
DaemonSet Controller:确保每个节点上都运行一个DaemonSet定义的Pod,通常用于节点级别的任务,例如日志收集和监控。
StatefulSet Controller:管理有状态应用,确保有状态Pod的创建、删除和更新按序执行,维护Pod的稳定网络标识和持久存储。
Deployment Controller:管理Deployment对象,确保应用按期望的版本和副本数运行,支持滚动更新和回滚。
ReplicaSet Controller:类似于Replication Controller,但功能更强大,通常与Deployment一起使用,确保指定数量的Pod副本在任何时候都在运行。
Horizontal Pod Autoscaler (HPA) Controller:根据资源使用情况(例如CPU或内存)自动扩展或缩减Pod数量,以满足应用的需求。
Vertical Pod Autoscaler (VPA) Controller:根据实际资源使用情况调整Pod的资源请求和限制(CPU和内存),提高资源利用率。
Ingress Controller:管理Ingress资源,提供外部访问到集群内部服务的方式,通过HTTP/HTTPS路由流量。
ResourceQuota Controller:管理和执行ResourceQuota资源,确保命名空间内的资源使用不超过设定的配额。
LimitRange Controller:管理和执行LimitRange资源,设置命名空间内Pod和容器的默认资源请求和限制。
PersistentVolume Controller:管理PersistentVolume资源,确保持久存储卷的生命周期,包括创建、绑定和回收。
PersistentVolumeClaim Controller:管理PersistentVolumeClaim资源,确保持久存储卷正确地绑定到请求的Pod。
StorageClass Controller:管理StorageClass资源,定义不同存储提供者的存储类型和配置,支持动态存储卷的创建。
k8s备份
网络相关
如何访问集群内的服务
- pod: hostport
- service: nodeport
简单聊聊flannel
flannel是一个管理k8s网络的组件,起相同功能的还有calico
flannel,在所有node上,搭建一个overlay网络,用于互相通信。
安全相关
k8s如何保证安全
rbac控制:角色、授权、用户,用户组
kubenetes secret怎么用
一般都是挂载
日志相关
fluentd
fluentd可以对接多种源的日志,将日志发送给多种目标。 最简单一点,他可以替代logstash,构成EFK集群。
https://www.cnblogs.com/lvzhenjiang/p/14196982.html
集群联邦
Federation, Karmada, clusternet
helm是什么
helm就是可以以应用的维度来管理该应用涉及到的各种yaml。 从而很方便的进行应用版本发布、回滚、更新、升级、安装等操作
k8s的服务发现是怎么做的
1,用户或自动化工具(如kubectl)创建或更新Service对象,API Server将这些变化更新到etcd。 2,Endpoint Controller监控API Server中的Service和Pod变化,更新Endpoints对象,记录后端Pod的IP和端口。 3,CoreDNS监控API Server,根据Service和Endpoints的变化动态更新DNS记录,实现服务发现。
怎么理解docker-swarm
docker-swarm侧重容器的管理。 k8s侧重业务的管理
印象深刻的问题
CoreDNS 响应在 Alpine 系统报错的问题
CoreDNS 低版本有个 bug,IPV6 的 DNS 响应是 NXDomain,而当 DNS 客户端系统是 alpine 系统时,会报错,其他系统(Ubuntu 等)不会报错。升级 CoreDnS 后解决。
踩坑:CoreDNS 日志、iptables、iproute、flannel、kubelet、kube-proxy