本篇为OverView,内容包括kubectl的基础操作,整理的知识框架基于kubernetes官方文档v1.26, 元旦期间系统整理一下。
pod生命周期 Pending Runing Succeed Failed Unknown
- Pending(挂起):API server已经创建pod,但是该pod还有一个或多个容器的镜像没有创建,包括正 在下载镜像的过程;
- Running(运行中):Pod内所有的容器已经创建,且至少有一个容器处于运行状态、正在启动括正在重 启状态;
- Succeed(成功):Pod内所有容器均已退出,且不会再重启;
- Failed(失败):Pod内所有容器均已退出,且至少有一个容器为退出失败状态
- Unknown(未知):某于某种原因apiserver无法获取该pod的状态,可能由于网络通行问题导致
docker
https://zhuanlan.zhihu.com/p/571931032
cgroup
CGroups 全称control group,
- 用来限定一个进程的资源使用,
- 由 Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。
namespace
如果CGroup设计出来的目的是为了隔离上面描述的物理资源,那么namespace则用来隔离PID(进程ID),IPC,Network等系统资源。
将它们分配给特定的Namespace,每个Namespace里面的资源对其他Namespace都是透明的。
不同container内的进程属于不同的Namespace,彼此透明,互不干扰。
unionFS(storage driver:overlay2)
unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的
借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享
k8s是什么
K8S 负责自动化运维管理多个 Docker 程序的集群
组件1 etcd
分布式键值存储,用于保存Kubernetes集群的所有重要信息,例如配置数据、状态信息等
组件2 apiserver: kube-apiserver
kube-apiserver是Kubernetes API的前端,提供了Kubernetes控制平面的统一接口
组件3 controller: kube-controller-manager
kube-controller-manager负责管理控制器,这些控制器包括节点控制器、副本控制器、端点控制器等,它们负责保证系统的状态符合用户定义的期望状态
组件4 scheduler: kube-scheduler
kube-scheduler负责将Pod调度到具体的节点上,它考虑了诸如资源需求、硬件/软件约束等因素
组件5 kubelet
kubelet是每个节点上运行的代理,负责确保Pods按照规定运行
组件6 kube-proxy
kube-proxy负责维护节点上的网络规则,使得服务可以被正确地路由
组件7 container runtime
容器运行时,比如docker,containerd
组件8 container advisor
是一个监控代理,用于收集容器资源使用情况和性能数据
【面试题】一个网络请求来了,还没处理要怎么办
kube-proxy处理,负责集群内部外部流量,正确路由到正确的pod上,实现高可用
1.etcd是什么?分布式键值存储系统
2.etcd适用场景是什么,
1. 简述K8s的工作流程
- 创建一个包含应用程序的Deployment的yml文件,然后通过kubectl客户端工具发送给ApiServer。
- ApiServer接收到客户端的请求并将资源内容存储到数据库(etcd)中。
- Controller组件(包含scheduler、replication、endpoint)监控资源变化并作出反应。
- ReplicaSet检查数据库变化,创建期望数量的pod实例。
- Scheduler再次检查数据库变化,发现尚未被分配到具体执行节点(Node)的Pod,然后根据一组相关规则将Pod分配到可以运行它们的节点(Node)上,并更新数据库,记录Pod分配情况。
- Kubelet监控数据库变化,管理后续Pod的生命周期,发现被分配到它所在的节点上运行的那些Pod。如果找到新Pod,则会在该节点上运行这个新Pod。例如当有数据发送到主机时,将其路由到正确的pod或容器。
2. 简述控制器类型Deployment,StatefulSet,DaemonSet的区别
- 应用场景
- Deployment适用于无状态的应用场景,副本可以动态增加和减少
- StatefulSet适用于有状态的应用场景,副本要顺序启动停止
- DaemonSet适用于每个节点都运行一个或多个pod的场景
- 存储
- 持久卷,持久卷声明(PV,PVC):适用于持久化数据的应用,比如数据库
- 存储类(StroageClass),根据PVC动态创建PV,适用于需要动态创建存储的场景,如云存储、分布式存储
- 子路径卷 (Subpath Volume),多个pod共享存储
- 本地卷(Local Volume),节点的本地卷映射到pod中,节点间共享存储
4. 如何实现滚动更新和回滚【实现平滑升级和故障恢复的手段】
- 滚动更新逐步将pod下线,由新deployment进行更新
1
2
3
4
5
6
7
8
9
10
11创建pod副本,在执行Deployment和升级的时候最好带上record参数,便于查看历史版本信息。
kubectl apply -f abcdocker-test.yaml --record
更新1.替换镜像版本去更新
我们可以看到pod执行过程是等待新的pod启动完成,在进行销毁旧的pod,这样就完成了集群的更新工作我们可以看到pod执行过程是等待新的pod启动完成,在进行销毁旧的pod,这样就完成了集群的更新工作
sed -i 's#1.13.0-alpine#1.10.0-alpine#g' abcdocker-test.yaml
kubectl apply -f abcdocker-test.yaml --record
更新2.直接更新deployment【不是修改yaml文件】,要用kubctl edit deployment
kubectl get deployment
kubectl edit deployments deployment_name
更新3. kubctl set替换镜像
kubectl set image deployment/SVC_NAME -n namespace_name container_name=images:v1
回滚,使用 kubectl rollout
1 | kubectl rollout history deployment [deployment_name]查看所有的history |
5. 如何进行日志管理
- 使用kubectl的logs,获取制定pod的日志
kubectl logs [pod_name] - 修改Kube-proxy的配置文件,通常位于
/etc/kubernetes/manifests/kube-proxy.yaml将Pod的日志输出到宿主机的日志文件中,一般使用本地卷挂载 - 重启kube-proxy,使用宿主机的日志轮转工具,logrotate,设置轮转策略
sudo logrotate -d /etc/logrotate.d/pod-logs6. 如何进行监控管理
- k8s提供了一个metrics,访问这个http请求就返回一个表单,是以#开头的注释行和以指标名称为前缀的键值对
- 工具有Prometheus比较常用,Grafana进行可视化展示
- 使用Heapster对Kubernetes集群进行监控数据的采集和存储
7. etcd的作用
- 存储所有资源信息,保证数据的强一致性,作用是数据存储、配置管理、故障恢复
- 这些资源信息包括:服务发现、分布式锁、分布式数据队列、分布式通知和协调等功能
8. etc的基本原理
- 分布式存储:Etcd采用分布式存储方式,可以配置多节点群集,通过数据同步来保证数据可靠性。
- 高可用性:Etcd通过选举算法来保证在任何时候都有一个领导者节点负责数据的写入和更新,从而保证了数据的强一致性。
- 数据持久化:Etcd中的数据会定期进行持久化存储,即使在系统崩溃时也可以保证数据的完整性。
9. k8s的kube-scheduler调度器
10. k8s怎样负载均衡的
- Kubernetes的内置负载均衡器:Service组件,Service会根据服务后端的Pod IP和端口,将流量均衡地转发给每个Pod。这种方式是基于IP的负载均衡,支持TCP和UDP协议。
- 用传统的Nginx负载均衡服务器做边车(Sidecar)容器运行,监控流量
11. k8s的Labels和Selectors的作用
Label:用于标识和选择资源对象。
- 附加在资源对象上的键值对标签,标pod,service
- 标在资源上,可以供Selector进行服务发现,关联选择资源,监控日志等
Selector:用于选择资源,服务发现
12. k8s的Service是什么
Service为一组pod定义一个服务的入口地址,提供给前端用Ingress访问这个集群实例,可以起到服务发现,负载均衡,故障隔离的作用。
- 提供服务的稳定入口:Service为前端的应用程序或者ingress提供了稳定的服务入口,这个入口拥有一个全局唯一的虚拟IP地址,前端的应用可以通过这个IP地址访问后端的Pod集群。
- 实现负载均衡:Service内部实现了负载均衡机制,它会将所有进入的请求均匀地分配给后端的Pod副本,确保每个请求都能得到正确的响应。
- 实现故障隔离:当某个Pod发生故障时,Service会自动将该Pod从服务池中剔除,保证请求不会被故障的Pod处理,从而实现了故障隔离。
- 实现服务发现:Service允许前端的应用程序通过Label Selector来找到提供特定服务的Pod,从而实现了服务的自动发现。
13. Pod周期和状态是什么
周期:创建启动运行停止
状态:Pending/Running Succeed/Failed Unknown
pod
1. pod的原理
2. pod的特点
一个pod是一个最小的部署单元,容器的组合体,这些容器共享网络命名空间和存储卷,并共享生命周期
3. pause容器作用
4. pod的重启策略
在yaml文件的restartPolicy字段定义,默认是always
- Always(总是重启):
当容器退出时,无论是正常退出还是异常退出,Kubernetes 将总是重启该容器。这是默认的重启策略。 - OnFailure(仅在失败时重启):
当容器以非零的退出代码(表示失败)退出时,Kubernetes 将自动重启该容器。如果容器以零的退出代码(表示成功)退出,Pod 将不会被重启。 - ever(永不重启):
当容器退出时,无论是以何种退出代码,Kubernetes 将不会重启该容器。这通常用于一次性任务,确保任务完成后不会再次启动。
5. pod的镜像拉取策略
也是三种策略
6. pod的存活探针有哪几种
- HTTP 探针通过向容器的指定端口发送 HTTP 请求来检查容器的存活状态。如果返回的 HTTP 状态码表示成功(在指定的范围内),则认为容器是存活的。
- TCP 探针通过尝试与容器的指定端口建立 TCP 连接来检查容器的存活状态。如果连接成功,则认为容器是存活的。
- Exec 探针通过在容器内执行指定的命令来检查容器的存活状态。如果执行成功,即命令返回零退出码,则认为容器是存活的。
7. 存活探针的属性参数
8. pod的就绪探针有哪几种
9. 就绪探针的属性参数
10.就绪探针和存活探针的区别是什么
- 存活探针是将检查失败的容器杀死,创建新的启动容器来保持pod正常工作
- 就绪探针是,当就绪探针检查失败,并不重启容器,而是将pod移出endpoint,就绪探针确保了service 中的pod都是可用的,确保客户端只与正常的pod交互并且客户端永远不会知道系统存在问题
11. pod创建过程
kubectl run 创建pod
1
2
3
4
5
61、首先,用户通过kubectl或其他api客户端工具提交需要创建的pod信息给apiserver;
2、apiserver验证客户端的用户权限信息,验证通过开始处理创建请求生成pod对象信息,并将信息存入 etcd,然后返回确认信息给客户端;
3、apiserver开始反馈etcd中pod对象的变化,其他组件使用watch机制跟踪apiserver上的变动;
4、scheduler发现有新的pod对象要创建,开始调用内部算法机制为pod分配最佳的主机,并将结果信息 更新至apiserver;
5、node节点上的kubelet通过watch机制跟踪apiserver发现有pod调度到本节点,尝试调用docker启动 容器,并将结果反馈apiserver;
6、apiserver将收到的pod状态信息存入etcd中。使用deployment创建pod
1 | 1、kubectl apply -f mydeployment.yaml |
12.pod的终止过程
- 用户向apiserver发送pod删除的命令
- kubectl监控pod为terminating状态,就启动关闭pod过程
- endpoint控制器监控pod对象的关闭行为时,讲所有资源从endpoint列表删除
- 如果当前pod对象定义了preStop钩子处理器,则在其被标记为terminating后会意同步的方式启动执行
- pod对象容器进程收到了停止信息
- 宽限期过后,kubelet请求apiserver讲pod资源宽限期设0,对用户不可见
13. pod的初始化容器 init container
- 负责在主应用容器启动之前执行一些预处理工作或者初始化任务,挂载volume,等待外部服务就绪,安全检查等
14.pod的资源请求、限制如何定义
resources下的limits和requests,cpu核数和内存大小service
1. service如何与pod关联
pod后跟了label,然后service使用标签选择器,selector选择关联哪些pod作为后段2. service的域名解析格式
<service-name>.<namespace>.svc.<cluster-domain> <service-name>是服务的名称,是在创建服务时指定的。<namespace>是服务所在的命名空间,默认为 “default”。<cluster-domain>是集群的域名,通常为 “cluster.local”。3. service的类型
一般情况下service都是ClusterIP类型的,通过ingress接入的外部流量
- ClusterIP:仅供集群内部使用,默认ClusterIP
- NodePort:service可以对外访问应用,在每个节点暴露一个端口,外部访问任意NodeIP:port就可以脸上service
- LoadBalancer:service对外访问应用,公有云环境下,需要公网IP地址
- ExternalName:这种类型的service会把集群外部的服务引入集群内部,这样集群内直接访问service就 可以间接的使用集群外部服务了
4. 一个应用pod如何连接service
- 环境变量,配置注入
- DNS方式,k8s集群内有DNS服务器
5. 如何创建一个service代理外部的服务/集群内的应用如何访问外部的数据库服务?
创建一个没有标签选择器的service代理集群外部服务。 - 创建service时不指定selector,没了selector就不会自动创建endpoint
- 手动创建一个与service同名的endpoint,在这个endpoint里定义外部服务的IP和端口,然后就自动关联了
6. service endpoint kubeproxy的关系
- service:在kubernetes中,service是一种为一组功能相同的pod提供单一不变的接入点的资源。当 service被建立时,service的IP和端口不会改变,这样外部的客户端(也可以是集群内部的客户端)通过 service的IP和端口来建立链接,这些链接会被路由到提供该服务的任意一个pod上。通过这样的方式, 客户端不需要知道每个单独提供服务的pod地址,这样pod就可以在集群中随时被创建或销毁。
- endpoint:service维护一个叫endpoint的资源列表,endpoint资源对象保存着service关联的pod的ip和 端口。从表面上看,当pod消失,service会在endpoint列表中剔除pod,当有新的pod加入,service就 会将pod ip加入endpoint列表;但是正在底层的逻辑是,endpoint的这种自动剔除、添加、更新pod的 地址其实底层是由endpoint controller控制的,endpoint controller负责监听service和对应的pod副本 的变化,如果监听到service被删除,则删除和该service同名的endpoint对象,如果监听到新的service 被创建或者修改,则根据该service信息获取得相关pod列表,然后创建或更新service对应的endpoint对 象,如果监听到pod事件,则更新它所对应的service的endpoint对象。
- kube-proxy:kube-proxy运行在node节点上,在Node节点上实现Pod网络代理,维护网络规则和四层 负载均衡工作,kube-proxy会监听api-server中从而获取service和endpoint的变化情况,创建并维护路 由规则以提供服务IP和负载均衡功能。简单理解此进程是Service的透明代理兼负载均衡器,其核心功能 是将到某个Service的访问请求转发到后端的多个Pod实例上
kubelet的功能和作用
- Node管理,kubelet启动时向kubeproxy注册,定时向apiserver汇报节点和资源状态
- Pod管理,kubelet维护pod的生命周期,当kubelet监听到master的下发到自己节点的任务时,比如要创建、更新、删除一个pod,kubelet 就会通过CRI(容器运行时接口)插件来调用不同的容器运行时来创建、更新、删除容器。
- 容器健康检查。Pod中可以定义启动探针-存活探针-就绪探针,定期调用容器的探针检测Pod的生命周期,对失败的容器进行重启等操作
- 在Node上部署Metrics server进行资源监控
kube-apiserver的功能和作用,端口号是8080和6443
在命名空间的kube-system命名空间里,有一个名称为kube-api-master的pod,这个pod就是运行着 kube-api-server进程,它绑定了master主机的ip地址和6443端口,但是在default命名空间下,存在一个叫kubernetes的服务,该服务对外暴露端口为443,目标端口6443,这个服务的ip地址是clusterip地 址池里面的第一个地址,同时这个服务的yaml定义里面并没有指定标签选择器,也就是说这个 kubernetes服务所对应的endpoint是手动创建的,该endpoint也是名称叫做kubernetes,该endpoint 的yaml定义里面代理到master节点的6443端口,也就是kube-api-server的IP和端口。这样一来,其他 pod 访问kube-api-server的整个流程就是: pod创建后嵌入了环境变量,pod获取到了kubernetes这个服务的ip和443端口,请求到kubernetes这个服务其实就是转发到了master节点上的6443端口的kube-api-server这个pod里面pod挂了,原本到这个pod的流量要怎么办【面试题】
首先请求到
kubelet用存活探针检测到这个pod挂了,k8s的namespace是什么
实现多套环境的资源隔离,限定不同租户能占用的资源,比如CPU和内存Usage等
持续集成CI的好处,用途是什么
用于整合团队开发 中不同开发者提交到开发仓库 中的项目代码变化,并即时整合编译,检查整合 编译错误的服务。它需要一天中多次整合编译代码的能力,若出现整合错误, 可以优异地准确定位提交错误源
14. Docker Swarm?docker集群
是原生的 Docker 集群服务工具。它将一群 Docker 主机集成为单一一个 虚拟 Docker 主机。利用一个 Docker 守护进程, 通过标准的 Docker API 和任何完善的通讯工具, Docker Swarm 提供透明地将 Docker 主机扩散到多台主机上的服务
15. Docker Compose?
16. Dockerfile里,ADD和COPY
差不多,都用来向镜像加文件,一般就COPY就行
有必要使用 ADD 指令的最好例子是需要在本地自动解压归档文件到容器中的情况,如 ADD rootfs.tar.xz 。
17 Dockerfile里,ONBUILD命令
构建阶段的触发器,当一个镜像被用作另一个镜像的基础镜像时,ONBUILD 指令将在构建过程中自动触发,一般后接一些COPY命令。
##
容灾
主要指在发生硬件故障时,通过备份和恢复机制保证业务连续性(能够继续正常运行)的手段。适用于对业务连续性要求非常高的场景。
【场景】pod都处于pending状态,调度器失败,pv没做好,无法创建存储卷
- 使用kubectl describe podname
- 长时间都在pending,可能是schduler无法为pod分配node,Scheduer调度器无法为pod分配一个合适的node节点。而这又会有很多种情况, 比如,node节点处在cpu、内存压力,导致无节点可调度;pod定义了资源请求,没有node节点满足资 源请求;node节点上有污点而pod没有定义容忍;pod中定义了亲和性或反亲和性而没有节点满足这些 亲和性或反亲和性;以上是调度器调度失败的几种情况。
- pvc,pv无法动态创建。比如要使用StatefulSet 创建redis集群,因为粗心大意,定义的storageClassName名称写错了,那么会造成 无法创建pvc,这种情况pod也会一直处于pending状态,或者,即使pvc是正常创建了,但是由于某些异 常原因导致动态供应存储无法正常创建pv,那么这种情况pod也会一直处于pending状态