1 工作负载(workloads)
工作负载(workload)是在kubernetes集群中运行的应用程序。无论你的工作负载是单一服务还是多个一同工作的服务构成,在kubernetes中都可以使用pod来运行它。
workloads分为pod与controllers
- pod通过控制器实现应用的运行,如何伸缩,升级等
- controllers在集群中管理pod
- pod与控制器之间通过label-selector相关联,是唯一的关联方式
2 pod介绍
2.1 pod定义与分类
2.1.1 pod定义
- pod(豌豆荚)是Kubernetes集群管理(创建、部署)与调度的最小计算单元,表示处于运行状态的一组容器。
- Pod不是进程,而是容器运行的环境。
- 一个Pod可以封装一个容器或多个容器(主容器或sidecar边车容器)
- 一个pod内的多个容器之间共享部分命名空间
- 用户pod默认会被调度运行在node节点之上(不运行在master节点上,但也有例外情况)
- pod内的IP不是固定的,集群外不能直接访问pod
2.1.2 pod分类
- 静态Pod 也称之为"无控制器管理的自主式pod",直接由特定节点上的kubelet守护进程管理,不需要API服务器看到它们,尽管大多数Pod都是通过控制面(例如,Deployment)来管理的,对于静态Pod而言,kubelet直接监控每个Pod,并在其失效时重启之。
- 控制器管理的pod 控制器可以控制pod的副本数,扩容与裁剪,版本更新与回滚等。
2.2 查看pod命令
kubectl get pod
kubectl get pod -n kube-system
2.3 pod的yaml资源清单格式
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod,Deployment,ReplicaSet,Replication
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略 Always表示下载镜像 IfNotPresent表示优先使用本地镜像 Never表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
initialDelaySeconds <integer> # 容器启动后等待多少秒执行第一次探测
timeoutSeconds <integer> # 探测超时时间。默认1秒,最小1秒
periodSeconds <integer> # 执行探测的频率。默认是10秒,最小1秒
failureThreshold <integer> # 连续探测失败多少次才被认定为失败。默认是3。最小值是1
successThreshold <integer> # 连续探测成功多少次才被认定为成功。默认是1
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
不用写这么多在pod里,使用controller控制器更容易全面部署。
在编写yaml的时候,可结合帮助,灵活运用,找到所需的那个代码。
k8s查看yaml文件帮助的命令
构建pod,ns,rs,rc等等,只需在后面加上即可出现对应模板
kubectl explain pod/ns/rs/rc/networkpolicy/hpa.spac
3 pod 创建与验证
3.1 命令创建pod
查找帮助文档:
kubectl run -h
创建一个使用指定镜像的Pod:
kubectl run <pod-name> --image=<image>
例如,使用nginx镜像创建一个Pod:
kubectl run mypod --image=nginx
3.2 使用yaml文件创建pod
以下是一个简单的Pod定义文件示例(pod.yaml):
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
spec:
containers:
- name: mycontainer
image: nginx
ports:
- containerPort: 80
这个定义文件创建了一个名为mypod的Pod,其中包含一个名为mycontainer的容器,使用的是nginx镜像,并暴露了80端口。
使用以下命令来创建Pod(create如果资源存在会报错):
kubectl apply -f pod.yaml
验证Pod是否成功创建:使用kubectl get pods命令来查看Pod列表,确认你的Pod已经成功创建并运行。
kubectl get pods
查看Pod详情:如果你需要更详细的信息,可以使用describe命令:
kubectl describe pod mypod
删除Pod:如果你需要删除Pod,可以使用以下命令:
kubectl delete pod mypod
kubectl delete -f pod.yaml
3.3 容器镜像拉取策略
Kubernetes容器镜像拉取策略决定了Kubernetes在启动容器时如何获取镜像。主要有以下几种拉取策略:
- IfNotPresent:这是默认的拉取策略。如果容器镜像在本地不存在,则尝试从远程仓库拉取。如果本地已存在,则直接使用本地缓存的镜像。
- Always:每次启动容器时,都尝试从远程仓库拉取最新的镜像。即使本地已经存在相同版本的镜像,也会拉取最新的版本。
- Never:容器不会尝试从远程仓库拉取镜像。只有在本地存在所需版本的镜像时,容器才会启动。这适用于完全离线的环境或者需要手动预先拉取镜像的情况。
3.4 pod的标签
3.4.1 通过命令管理pod标签
- 为pod设置label,用于控制器通过label与pod关联
- 语法与node标签几乎一致
- node的label用于将pod调度到指定label的node节点
- 查看Pod的标签:
kubectl get pods <pod-name> --show-labels
- 给现有的Pod添加标签:
kubectl label pods <pod-name> <key>=<value>
例如,给名为mypod的Pod添加标签app=myapp:
kubectl label pods mypod app=myapp
- 更新Pod的标签: 如果你想要更新一个已经存在的标签的值,你可以先删除旧的标签,然后重新添加新的标签:
kubectl label pods <pod-name> <key>-
然后重新添加新的标签值:
kubectl label pods <pod-name> <key>=<new-value>
- 删除Pod的标签:
kubectl label pods <pod-name> <key>-
这将删除指定的标签。例如,删除mypod的app标签:
kubectl label pods mypod app-
- 使用标签选择器来获取Pod列表:
kubectl get pods -l <key>=<value>
例如,获取所有标签包含app=myapp的Pod:
kubectl get pods -l app=myapp
- 使用标签选择器来删除Pod:
kubectl delete pods -l <key>=<value>
例如,删除所有标签包含app=myapp的Pod:
kubectl delete pods -l app=myapp
- 使用标签选择器来编辑Pod:
kubectl edit pods -l <key>=<value>
- 查看所有Pod的标签: 如果你想要查看所有Pod的标签,可以使用以下命令:
kubectl get pods --all-namespaces --show-labels
3.4.2 通过yaml创建pod时添加标签
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
environment: production
spec:
containers:
- name: mycontainer
image: nginx
ports:
- containerPort: 80
在这个例子中,定义了一个名为mypod的Pod,它包含一个标签app=myapp和一个标签environment=production。这些标签可以在创建Pod时被添加到Pod的元数据中。
3.5 pod资源限制
在Kubernetes中,Pod的资源限制是通过在Pod的YAML定义文件中的spec.containers[].resources部分设置的。资源限制分为两种:
- Requests(请求):这是容器所需的最小资源量,也是调度器用来为Pod选择节点的依据。如果一个节点没有足够的资源来满足请求,Pod将不会被调度到该节点。
- Limits(限制):这是容器可以使用的最大资源量。如果容器尝试使用超过这个限制的资源,它可能会被限制(如CPU)或被杀掉(如内存)。
资源限制通常包括CPU和内存,但也可以包括其他资源类型,如存储或自定义资源。以下是CPU和内存资源限制的一些示例:
- CPU资源限制:可以指定整数或小数点数(如1或0.5),或者以毫核为单位(如500m表示半核)。1213
-
- 例如,设置CPU请求和限制:
resources:
requests:
cpu: "500m"
limits:
cpu: "1"
- 内存资源限制:通常以字节为单位,可以使用多种后缀。
-
- 例如,设置内存请求和限制:
resources:
requests:
memory: "64Mi"
limits:
memory: "128Mi"
在设置资源限制时,应遵循以下准则:
- requests的值必须小于或等于limits的值。
- limits建议不超过宿主机配置的20%,以确保节点资源的合理分配。
- 如果Pod的requests值过高,可能会导致节点上的Pod数量减少,从而造成资源浪费。
- 如果没有为容器设置内存的requests,Kubernetes会自动设置与limits相匹配的requests值。
3.6 pod中运行多个容器的方法
在Kubernetes中,Pod可以运行多个容器,这些容器共享网络和存储资源。
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
labels:
app: multi-app
spec:
containers:
- name: container-1
image: nginx
ports:
- containerPort: 80
- name: container-2
image: redis
ports:
- containerPort: 6379
一个主容器,一个边车容器。辅助主容器的工作。
3.7 对pod里的容器进行操作
命令帮助:
kubectl exec -h
- 执行命令到正在运行的容器,比如查看容器内部的进程或执行一次性任务:
kubectl exec <pod-name> -c <container-name> -- <command>
例如,进入一个正在运行的容器并执行ls命令:
kubectl exec mypod -- ls
- 在容器中打开一个shell会话,这对于交互式调试非常有用:
kubectl exec -it <pod-name> -- /bin/sh
例如,进入一个正在运行的容器
kubectl exec -it mypod -- /bin/sh
4 pod调度
4.1 pod调度流程
Step1
通过kubectl命令应用资源清单文件(yaml格式)向api server发起一个create pod请求
Step2
apiserver接收到pod创建请求后,生成一个包含创建信息资源清单文件
Step3
apiserver将资源清单文件中信息写入etcd数据库
Step4
Scheduler启动后会一直watch API Server,获取podSpec.NodeName为空的Pod,即判断pod.spec.Node ==null?若为null,表示这个Pod请求是新的,需要创建,因此先进行调度计算(共计2步:1、过滤不满足条件的,2、选择优先级高的),找到合适的node,然后将信息在etcd数据库中更新分配结果:pod.spec.Node=nodeA(设置一个具体的节点)
Step5
kubelet通过watch etcd数据库(即不停地看etcd中的记录),发现有新的Node出现,如果这条记录中的Node与所在节点编号相同,即这个Pod由scheduler分配给自己,则调用node中的container Runtime,进而创建container,并将创建后的结果返回到给apiserver用于更新etcd数据库中数据状态。
补充概念:
- API Server: API Server是Kubernetes控制平面的前端组件,它作为系统的入口点,对外提供Kubernetes API。所有的客户端工具(如kubectl)、集群中的其他组件以及外部系统都通过API Server与Kubernetes集群通信。API Server负责处理API请求,更新状态,以及触发各种事件。
- etcd: etcd是一个分布式键值存储系统,用于持久化Kubernetes集群的所有数据,包括集群状态、配置数据、网络策略等。etcd保证了数据的一致性和高可用性,是Kubernetes集群状态管理的核心。
- Scheduler: Scheduler是Kubernetes中的一个关键组件,负责决定将未绑定的Pods调度到哪个节点上运行。Scheduler通过一系列规则和策略来评估集群中的节点,选择最适合运行Pod的节点。调度决策基于资源需求、亲和性、反亲和性、数据局部性、工作负载间干扰等因素。
- Kubelet: Kubelet是运行在每个Kubernetes节点上的服务,负责维护节点上容器的生命周期。它与API Server通信,接收Pod的指令,并与容器运行时接口(如Docker、containerd等)交互来创建、更新或删除容器。
- Container Runtime: 容器运行时(Container Runtime)是负责运行容器的软件。Kubernetes支持多种容器运行时,包括Docker、containerd、CRI-O等。容器运行时负责拉取容器镜像、创建容器实例、执行容器内进程、监控容器状态等任务。
4.2 调度约束方法
在Kubernetes中,调度约束是一种机制,它允许用户指定Pod应该在哪个节点上运行,或者根据特定的规则来选择节点。以下是两种调度约束方法的解释:
- NodeName: nodeName是一个字段,可以直接指定Pod应该运行在特定的节点上。当在Pod的spec中设置nodeName时,Kubernetes调度器将不会进行常规的调度流程,而是直接将Pod绑定到指定的节点上。这通常用于手动调度或在自动化脚本中指定特定的节点。
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
spec:
nodeName: k8s-master # 指定Pod要运行的节点名称
containers:
- name: my-container
image: nginx
- NodeSelector(节点选择器): nodeSelector是一种更灵活的调度约束方法,它允许基于节点的标签来选择节点。用户首先需要给节点打上标签(使用kubectl label nodes命令),然后在Pod的spec中设置nodeSelector,匹配相应的节点标签。
Pod定义示例,使用nodeSelector:
复制
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeselector
spec:
nodeSelector:
disktype: "ssd" # 选择具有特定标签的节点
containers:
- name: my-container
image: nginx
5 pod生命周期
5.1 pod生命周期
5.1.1 Pod 状态
- 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
- 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
5.1.2 重启策略
- Always:表示容器挂了总是重启,这是默认策略
- OnFailures:表示容器状态为错误时才重启,也就是容器正常终止时不重启
- Never:表示容器挂了不予重启
对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费资源的。所以Always重启策略是这么做的:第一次容器挂了立即重启,如果再挂了就要延时10s重启,第三次挂了就等20s重启...依次类推。
5.2 HealthCheck健康检查
5.2.1Health Check 方式
在Kubernetes中,HealthCheck健康检查是一种机制,用于确定容器是否存活并且能够正常工作。这通常通过两种类型的探针来实现:
- 存活探针(Liveness Probes):
- 存活探针用于检测容器是否存活。如果探针失败,Kubernetes会根据Pod的restartPolicy来重启容器。如果容器没有提供存活探针,默认状态为成功(Success)。
- 存活探针可以配置为不同类型的探测方式,包括:
方式 | 说明 |
ExecAction | 在容器内执行命令,如果命令成功执行,则认为容器存活。 |
TCPSocketAction | 对容器的指定端口进行TCP检查,如果端口开放,则认为容器存活。 |
HTTPGetAction | 对容器的IP地址、端口和路径执行HTTP GET请求,如果响应状态码在200-399之间,则认为容器存活。 |
- 就绪探针(Readiness Probes):
- 就绪探针用于确定容器是否准备好服务请求。如果探针失败,Kubernetes将不会将流量路由到该Pod。如果容器没有提供就绪探针,默认状态也为成功(Success)。
- 就绪探针同样可以使用与存活探针相同的三种探测方式。
5.2.2 liveness-exec案例
- 编写yaml文件
[root@master ~]# cat liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness-exec
name: liveness-exec
spec:
restartPolicy: OnFailure #改为Never的话检测失败后直接不重启
containers:
- name: liveness-exec
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command: ["test","-e","/tmp/healthy"]
initialDelaySeconds: 5 #探测延时时长,第一次探测前等待5秒,默认为0
periodSeconds: 5 #每5秒执行一次liveness探测,默认值10秒,最小1秒
timeoutSeconds: 2 #超长时长,默认为1s,最小值也为1s
failureThreshold: 3 #处于成功状态时,探测操作至少连续多少次的失败才被视为检测不通过,默认为3,最小为1
- apply使其生效:
[root@master ~]# kubectl apply -f liveness-exec.yaml
pod/liveness-exec created
- 验证
[root@master ~]# kubectl get pod liveness-exec -o wide
[root@master ~]# kubectl describe pod liveness-exec
正常运行 没有重启
10秒后,probe再次检测,由于文件被删,检测失败,此后容器会进行多次重启操作。
5.2.3 liveness-httpget案例
- 编写yaml文件
[root@master ~]# cat liveness-http.yaml
apiVersion : v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness-http
image: nginx
ports:
- name: http
containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh" ,"-c","echo liveness-http test > /usr/share/nginx/html/health"]
livenessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
[root@master ~]# kubectl apply -f liveness-http.yaml
pod/liveness-http created
- 验证
[root@master ~]# kubectl get pod liveness-http -o wide
[root@master ~]# curl 172.20.102.181/health
# 删除文件,使探针寻找不到文件
[root@master ~]# kubectl exec -it liveness-http -- rm /usr/share/nginx/html/health
[root@master ~]# kubectl describe pod liveness-exec
删除文件:
404报错:
5.2.4 liveness-tcp 案例
- 编写yaml文件
[root@master ~]# more liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: liveness-tcp
spec:
containers:
- name: liveness-tcp
image: nginx
ports:
- name: http
containerPort: 80
livenessProbe:
tcpSocket:
port: http
[root@master ~]# kubectl apply -f liveness-tcp.yaml
pod/liveness-tcp created
- 验证
[root@master ~]# kubectl get pod liveness-tcp
[root@master ~]# kubectl exec -it liveness-tcp -- /usr/sbin/nginx -s stop
会自动重启pod
5.2.5 readiness-httpget案例
- 编写yaml文件
apiVersion : v1
kind: Pod
metadata:
name: readiness-http
spec:
containers:
- name: readiness-http
image: nginx
ports:
- name: http
containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh" ,"-c","echo readiness-http test > /usr/share/nginx/html/health"]
readinessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
initialDelaySeconds: 5 # 探测延时时长,第一次探测前等待5秒,默认为0
periodSeconds: 5 # 每5秒执行一次liveness探测,默认值10秒,最小1秒
- 验证
[root@master ~]# kubectl get pod readiness-http -o wide
[root@master ~]# curl 172.20.102.181/health
# 删除文件,使探针寻找不到文件
[root@master ~]# kubectl exec -it readiness-http -- rm /usr/share/nginx/html/health
[root@master ~]# kubectl describe pod readiness-exec
# 新建一个文件
[root@master ~]# kubectl exec -it readiness-http -- touch /usr/share/nginx/html/health
[root@master ~]# kubectl get pod readiness-http -o wide
# 又running了
5.2.6 liveness+readiness综合案例
- 编写yaml文件
[root@master ~]# cat ness-tcp.yaml
apiVersion : v1
kind: Pod
metadata:
name: ness-http
spec:
containers:
- name: ness-http
image: nginx
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
path: /index.html
port: http
initialDelaySeconds: 1 # 探测延时时长,第一次探测前等待5秒,默认为0
periodSeconds: 3 # 每5秒执行一次liveness探测,默认值10秒,最小1秒
readinessProbe:
httpGet:
path: /index.html
port: http
initialDelaySeconds: 5 # 探测延时时长,第一次探测前等待5秒,默认为0
periodSeconds: 5 # 每5秒执行一次liveness探测,默认值10秒,最小1秒
[root@master ~]# kubectl apply -f ness-tcp.yaml
pod/ness-tcp created
检测方式同上,既可以检测崩溃后重启,也可检测流量是否就绪
同时使用的好处:
- 自愈能力:如果应用程序崩溃或停止响应,存活探针可以触发容器重启,从而恢复服务。
- 流量管理:就绪探针确保流量只会发送到已经完全启动并准备好处理请求的容器,从而提高服务的可靠性和稳定性。
5.3 poststart 和 pre-stop
5.3.1 poststart
在Kubernetes中,PostStart 是一个生命周期钩子,它在容器创建后立即执行。这个钩子通常用于执行容器启动后需要立即进行的操作,比如清理工作、初始化设置或者发送通知等。
- 创建yaml文件
[root@master ~]# cat poststart.yaml
apiVersion: v1
kind: Pod
metadata:
name: poststart
spec:
containers:
- name: poststart
image: nginx
lifecycle:
postStart:
exec:
command: ["mkdir", "-p", "/usr/share/nginx/html/poststart"]
- 验证
[root@master ~]# kubectl get pod poststart
[root@master ~]# kubectl exec -it poststart -- ls -l /usr/share/nginx/html
# 可以看到文件已经被创建
5.3.2 pre-stop
在Kubernetes中,PreStop 是生命周期钩子,它在容器即将停止之前执行。这个钩子通常用于执行清理任务,如保存状态、关闭网络连接、释放资源等。PreStop 钩子可以确保容器在被终止前能够优雅地关闭。
- 创建yaml文件
[root@master ~]# cat prestop.yaml
apiVersion: v1
kind: Pod
metadata:
name: prestop
spec:
containers:
- name: prestop
image: nginx
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 600"]
- 验证
[root@master ~]# kubectl delete pod prestop
# 可以发现不会立刻被删除
6 pod故障排除
- 检查Pod状态: 使用kubectl get pods命令来查看Pod的状态。如果Pod没有运行,它可能会显示为Pending、Unknown或Error。
- 查看Pod日志: 使用kubectl logs <pod-name>来查看Pod的日志,这可以帮助你了解Pod内部发生了什么。
- 检查容器状态: 使用kubectl describe pod <pod-name>来获取Pod的详细信息,包括容器的状态和事件。
- 检查容器探针: 如果Pod配置了liveness或readiness探针,检查它们是否正常工作。探针失败可能导致容器重启。
- 检查资源限制: 如果Pod处于Pending状态,可能是因为没有足够的资源。检查集群的资源使用情况和Pod的资源请求。
- 检查网络问题: 如果Pod无法访问服务或网络连接失败,检查网络策略和Pod的网络配置。
- 检查存储问题: 如果Pod需要访问持久化存储,确保Persistent Volume(PV)和Persistent Volume Claim(PVC)正常工作。
- 检查配置和依赖: 确保Pod使用的配置文件、环境变量和依赖服务都是正确的。
- 检查镜像问题: 如果Pod无法启动,可能是因为容器镜像无法拉取。检查镜像名称和版本是否正确,以及是否有访问权限。
- 检查调度问题: 如果Pod无法调度到节点上,检查节点的资源限制、污点(Taints)和容忍度(Tolerations)。
- 使用诊断工具: 使用Kubernetes的诊断工具,如kubectl debug(如果你使用的是Kubernetes 1.20及以上版本)来进一步诊断问题。
- 检查集群健康: 使用kubectl get nodes来检查集群中所有节点的状态。如果节点有问题,它可能会影响Pod的调度和运行。
- 查看事件: 使用kubectl get events来查看集群中的事件,这可能会提供有关Pod问题的线索。
- 检查权限和角色: 确保Pod和服务账户具有执行操作所需的权限。
- 重启Pod: 如果问题无法确定,尝试重启Pod来查看问题是否仍然存在。
- 更新Kubernetes: 如果你怀疑是Kubernetes本身的bug,考虑更新到最新版本。