k8s基础篇-pod
k8s基础篇-pod
创建pod流程
- 用户通过kubectl或API Server提交Pod配置。
- API Server Validates Pod配置,确认配置正确后持久化到Etcd。
- Scheduler监听API Server,发现新的Pod需要调度。
- Scheduler根据调度算法为Pod选择一个合适的Node。
- Scheduler通过API Server更新Pod状态,将Pod绑定到选中的Node。
- 目标Node上的kubelet监听到有Pod调度过来,调用容器运行时下载镜像。
- 容器运行时启动容器,并与Pod网络插件对接,设置网络。
- kubelet调用健康检查,如果正常则标记Pod为Running状态。
- 用户通过kubectl或API Server可以看到Pod运行在指定的Node上。
- 用户通过Service访问Pod。
删除pod流程
- 用户通过kubectl或API Server提交Pod删除请求。
- API Server接收到请求,将Pod标记为Terminating状态。
- Controller Manager中的Pod GC Controller监听到Pod被标记为Terminating状态。
- Pod GC Controller打开该Pod的grace period(默认30s)。在这个时间内允许Pod优雅终止。
- Kubelet获取到Pod状态变更事件,发送SIGTERM信号给Pod中的容器。
- 容器接收到SIGTERM信号后开始优雅关闭,例如完成当前请求后退出。
- grace period结束后,kubelet强制删除Pod中的容器。
- CNI和CSI组件清理Pod网络和存储资源。
- Kubelet将Pod状态更新为Terminated。
- GC Controller监听到Pod进入Terminated状态,从Etcd中删除该Pod。
- Pod删除完成。
创建pod
创建yaml文件来声明pod
YAML文件示例:
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
创建资源
kubectl create -f nginx.yaml
更新创建资源
kubectl apply -f nginx.yaml
kubectl run命令示例:
kubectl run nginx --image=nginx:1.15
删除Pod
kubectl delete pod nginx
显示Pod资源的详细信息
kubectl describe pod nginx
进入Pod
kubectl exec -it nginx bash
更改pod的启动命令和参数
通过command来更改pod的启动命令和参数 会将镜像中的cmd覆盖
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
command: # 可选,容器启动执行的命令
- sleep
- "10"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
pod状态及pod故障排查命令
Pod 的 Phase 字段只有 Pending、Running、Succeeded、Failed、Unknown,其余的为处 于上述状态的原因,可以通过 kubectl get po xxx –o yaml 查看。
状态 | 说明 |
---|---|
Pending(挂起) | Pod 已被 Kubernetes 系统接收,但仍有一个或多个容器未被创建,可以通过 kubectl describe 查看处于 Pending 状态的原因 |
Running(运行中) | Pod 已经被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个 是运行状态,或者是正在启动或者重启,可以通过 kubectl logs 查看 Pod 的日志 |
Succeeded(成功) | 所有容器执行成功并终止,并且不会再次重启,可以通过 kubectl logs 查看 Pod 日志 |
Failed(失败) | 所有容器都已终止,并且至少有一个容器以失败的方式终止,也就是说这个容器 要么以非零状态退出,要么被系统终止,可以通过 logs 和 describe 查看 Pod 日 志和状态 |
Unknown(未知) | 通常是由于通信问题造成的无法获得 Pod 的状态 |
ImagePullBackOff ErrImagePull | 镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可 以使用 describe 命令查看具体原因 |
CrashLoopBackOff | 容器启动失败,可以通过 logs 命令查看具体原因,一般为启动命令不正确,健 康检查不通过等 |
OOMKilled | 容器内存溢出,一般是容器的内存 Limit 设置的过小,或者程序本身有内存溢出, 可以通过 logs 查看程序启动日志 |
Terminating | Pod 正在被删除,可以通过 describe 查看状态 |
SysctlForbidden | Pod 自定义了内核配置,但 kubelet 没有添加内核配置或配置的内核参数不支持, 可以通过 describe 查看具体原因 |
Completed | 容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以通过 logs 查看容器日志 |
ContainerCreating | Pod 正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过 describe 查看具体原因 |
Pod 镜像拉取策略
通过 spec.containers[].imagePullPolicy 参数可以指定镜像的拉取策略,目前支持的策略如下:
操作方式 | 说明 |
---|---|
Always | 总是拉取,当镜像 tag 为 latest 时,且 imagePullPolicy 未配置,默认为 Always |
Never | 不管是否存在都不会拉取 |
IfNotPresent | 镜像不存在时拉取镜像,如果 tag 为非 latest,且 imagePullPolicy 未配置,默认为 IfNotPresent |
更改镜像拉取策略为 IfNotPresent:
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent # 可选,镜像拉取策略
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
Pod 重启策略
可以使用 spec.restartPolicy 指定容器的重启策略
操作方式 | 说明 |
---|---|
Always | 默认策略。容器失效时,自动重启该容器 |
OnFailure | 容器以不为 0 的状态码终止,自动重启该容器 |
Never | 无论何种状态,都不会重启 |
指定重启策略为 Never:
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent
command: # 可选,容器启动执行的命令
- sleep
- "10"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never
Pod 的三种探针 的实现方式
探针总类
种类 | 说明 |
---|---|
startupProbe | Kubernetes1.16 新加的探测方式,用于判断容器内的应用程序是否已经启动。如果 配置了 startupProbe,就会先禁用其他探测,直到它成功为止。如果探测失败,Kubelet 会杀死容器,之后根据重启策略进行处理,如果探测成功,或没有配置 startupProbe, 则状态为成功,之后就不再探测。 |
livenessProbe | 用于探测容器是否在运行,如果探测失败,kubelet 会“杀死”容器并根据重启策略 进行相应的处理。如果未指定该探针,将默认为 Success |
readinessProbe | 一般用于探测容器内的程序是否健康,即判断容器是否为就绪(Ready)状态。如 果是,则可以处理请求,反之 Endpoints Controller 将从所有的 Service 的 Endpoints 中删除此容器所在 Pod 的 IP 地址,无法对pod发送请求。如果未指定,将默认为 Success |
实现方式
种类 | 说明 |
---|---|
ExecAction | 在容器内执行一个指定的命令,如果命令返回值为 0,则认为容器健康 |
TCPSocketAction | 通过 TCP 连接检查容器指定的端口,如果端口开放,则认为容器健康 |
HTTPGetAction | 对指定的 URL 进行 Get 请求,如果状态码在 200~400 之间,则认为容器健康 |
创建一个没有探针的 Pod:
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent
command: # 可选,容器启动执行的命令
- sh
- -c
- sleep 10; nginx -g "daemon off;"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never
配置健康检查:
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent
command: # 可选,容器启动执行的命令
- sh
- -c
- sleep 10; nginx -g "daemon off;"
readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
httpGet: # 接口检测方式
path: /index.html # 检查路径
port: 80
scheme: HTTP # HTTP or HTTPS
#httpHeaders: # 可选, 检查的请求头
#- name: end-user
# value: Jason
initialDelaySeconds: 10 # 初始化时间, 健康检查延迟执行时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 2 次表示就绪
failureThreshold: 2 # 检测失败 1 次表示未就绪
livenessProbe: # 可选,健康检查
tcpSocket: # 端口检测方式
port: 80
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 2 次表示就绪
failureThreshold: 2 # 检测失败 1 次表示未就绪
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never
配置 StartupProbe
配置了 startupProbe,就会先禁用其他探测,直到它成功为止
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent
command: # 可选,容器启动执行的命令
- sh
- -c
- sleep 30; nginx -g "daemon off;"
startupProbe:
tcpSocket: # 端口检测方式
port: 80
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 2 次表示就绪
failureThreshold: 5 # 检测失败 1 次表示未就绪
readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
httpGet: # 接口检测方式
path: /index.html # 检查路径
port: 80
scheme: HTTP # HTTP or HTTPS
#httpHeaders: # 可选, 检查的请求头
#- name: end-user
# value: Jason
initialDelaySeconds: 10 # 初始化时间, 健康检查延迟执行时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 2 次表示就绪
failureThreshold: 2 # 检测失败 1 次表示未就绪
livenessProbe: # 可选,健康检查
exec: # 端口检测方式
command:
- sh
- -c
- pgrep nginx
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查
pod的preStop 和 postStart
建议容器在启动之前操作还是只用initcontainerd
-
preStop会在pod被删除前执行,postStart会在容器启动后立即执行。
-
preStop和postStart只能定义一个,不可同时定义。
-
preStop和postStart支持两种方式定义:exec和httpGet。
exec方式直接在pod执行命令;httpGet方式发送HTTP请求。
-
preStop执行过程不能保证一定成功完成,因为pod可能因为其他原因被直接终止。
-
postStart所执行的操作应该是快速并且幂等的,不能包含会卡住pod启动的操作。
-
preStop和postStart的执行是在容器入口点命令执行之前和之后,不会阻塞容器启动。
-
如果preStop阻塞了pod的终止,会导致pod处于Terminating状态超时。
-
preStop和postStart中的错误不会影响pod的生命周期,仅会在事件中记录。
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent
lifecycle:
postStart: # 容器创建完成后执行的指令, 可以是 exec httpGet TCPSocket
exec:
command:
- sh
- -c
- 'mkdir /data/'
preStop:
exec:
command:
- sh
- -c
- sleep 10
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!