k8s的pod管理及控制器管理
2026/9/19 20:50:32 网站建设 项目流程

一、Pod 管理

1. 查看 Pod的运行情况

kubectl get pods -o wide

这里:

  • kubectl:操作 Kubernetes
  • get pods:查看 Pod
  • -o wide:显示更多信息

例如:

NAME READY STATUS RESTARTS AGE IP NODE lee 1/1 Running 0 9s 10.244.1.3 k8s-node1

重点看这几个:

字段含义
NAMEPod 名称
READY容器是否准备好,1/1 表示 1 个容器全部正常
STATUSPod 当前状态
RESTARTS容器重启次数
AGEPod 存活时间
IPPod IP
NODEPod 被调度到哪台节点

所以:

lee 1/1 Running 0 9s 10.244.1.3 k8s-node1

意思就是:

lee这个 Pod 有一个容器,容器已经正常运行,Pod IP 是10.244.1.3,运行在k8s-node1

2.创建pod


[root@k8s-master ~]# docker load -i nginx-1.26.tar
Loaded image: nginx:1.26
先拉镜像,你是什么版本就用什么版本
[root@k8s-master ~]# docker images | grep nginx
nginx:1.26 41b194461e4b 279MB 75.2MB
[root@k8s-master ~]# docker tag nginx:1.26 reg.timinglee.org/nginx/nginx:1.26
[root@k8s-master ~]# docker images | grep nginx
nginx:1.26 41b194461e4b 279MB 75.2MB
reg.timinglee.org/nginx/nginx:1.26 41b194461e4b 279MB 75.2MB
[root@k8s-master ~]# docker login reg.timinglee.org -u admin
Password:
Login Succeeded
[root@k8s-master ~]# docker push reg.timinglee.org/nginx/nginx:1.26
The push refers to repository [reg.timinglee.org/nginx/nginx]
6923759e66ab: Pushed
8a628cdd7ccc: Pushed
7a0654aeb922: Pushed
5e98d206134b: Pushed
d44088bb6ae8: Pushed
9ebfb40fb06b: Pushed
4fd410795c0f: Pushed
1.26: digest: sha256:c8042489f41ddaf05b7dfbe1e32d5227f94f1b002aca8e3b7b9c9d0cee6b0fed size: 2293

把镜像上传到 Harbor。

最终 Harbor 中有:

reg.timinglee.org └── nginx └── nginx └── 1.26

这样 Kubernetes 节点才能通过:

reg.timinglee.org/nginx/nginx:1.26

去拉镜像

并不意味着 node1、node2 也有这个镜像。

所以把镜像放进 Harbor 后,Pod 被调度到哪个节点,那个节点就可以从 Harbor 拉:

Harbor ↑ ┌───────┴───────┐ │ │ node1 node2 ↑ ↑ Pod Pod

3.kubectl run创建 Pod

kubectl run lee --image=reg.timinglee.org/nginx/nginx:1.26

意思:

创建一个名字叫lee的 Pod,使用 nginx 1.26 镜像。

注意:

kubectl run

创建的是最基本的 Pod

它没有 Deployment、ReplicaSet 这些控制器管理。

所以:

kubectl delete pod lee

删掉以后,它就真的没了

4.kubectl describe pod

你这里:

kubectl describe pod error

这个命令非常重要。

可以把它理解成:

把这个 Pod 的详细档案全部打印出来。

尤其是排错的时候。

你这里最关键的是:

Node: k8s-node2/172.25.254.20

说明:

error这个 Pod 被调度到了k8s-node2

然后:

Image: lee:v1

说明它需要:

lee:v1

这个镜像。

但是最关键的是最后的 Events:

Failed to pull image "lee:v1": Error response from daemon: failed to resolve reference "docker.io/library/lee:v1": docker.io/library/lee:v1: not found

这句话就非常关键。


5. 为什么lee:v1会去 Docker Hub?

执行:

kubectl run error --image lee:v1

Kubernetes 看到:

lee:v1

没有写仓库地址。

所以它会把它理解成:

docker.io/library/lee:v1

也就是:

Docker Hub ↓ library ↓ lee ↓ v1

但是 Docker Hub 上没有这个镜像。

所以:

ErrImagePull ↓ ImagePullBackOff

6.ImagePullBackOff是什么意思?

ImagePullBackOff

不是说 Kubernetes 本身挂了。

意思是:

Kubernetes 拉取镜像失败,并且正在进行退避重试。

过程大概:

Pod 创建 ↓ 拉取镜像 ↓ 失败 ↓ ErrImagePull ↓ 等待一段时间 ↓ 重新拉取 ↓ 又失败 ↓ ImagePullBackOff

BackOff就是:

失败以后不要疯狂重试,等一会儿再试。


7. Pod 为什么有 IP,但还是 Pending?

这里:

Status: Pending IP: 10.244.2.3

都有 IP 了,为什么还是 Pending?

因为 Pod 的生命周期不是:

有 IP = Running

Pod 还要:

创建 Pod ↓ 分配 IP ↓ 拉镜像 ↓ 创建容器 ↓ 启动容器 ↓ Running

情况是:

Pod 创建成功 ↓ 调度到 node2 ↓ 分配 10.244.2.3 ↓ 拉 lee:v1 ↓ 失败 ↓ Pending

所以:

有 Pod IP 不代表容器已经成功运行。


8. 为什么删除 Pod?

kubectl delete pods error

删除指定 Pod:

error

或者:

kubectl delete pods --all

删除当前 namespace 下的所有 Pod。

因为前面都是直接创建的 Pod,所以可以直接删。

但是要特别注意:

如果 Pod 被 Deployment 管理

例如:

Deployment ↓ ReplicaSet ↓ Pod

你执行:

kubectl delete pod xxx

Pod 虽然被删除了,但是 Deployment 会发现:

我明明需要 2 个 Pod 现在只剩 1 个

于是马上再创建一个。

所以:

直接创建的 Pod:删除就是删除。

Deployment 管理的 Pod:删除 Pod,控制器会重新创建

二、利用控制器实现版本更替

这里使用的是:

Deployment

它主要解决:

  • Pod 数量控制
  • Pod 自动创建
  • Pod 故障自动恢复
  • 版本更新
  • 滚动更新
  • 版本回滚

实验实际上是在做:

myapp:v1 ↓ Deployment ↓ 两个 Pod ↓ 访问业务 ↓ 升级 ↓ myapp:v2 ↓ 滚动更新 ↓ 回退 ↓ myapp:v1

1. 创建 Deployment 配置文件

执行:

kubectl create deployment webcluster \ --image=reg.timinglee.org/library/myapp:v1 \ --replicas=2 \ --dry-run=client \ -o yaml > webcluster.yml

这个命令可以拆成:

kubectl create deployment webcluster

创建一个 Deployment,名字叫:

webcluster
--image=reg.timinglee.org/library/myapp:v1

指定 Pod 使用的镜像。

--replicas=2

意思:

我要 2 个 Pod。

所以最终:

Deployment ↓ ReplicaSet ↓ ┌───────┴───────┐ ↓ ↓ Pod Pod v1 v1

这个特别重要。

--dry-run=client

意思:

只生成配置,不真正创建资源。

所以:

kubectl create deployment ...

本来会直接创建 Deployment。

但是加上:

--dry-run=client

以后:

不创建,只把 YAML 生成出来。

-o yaml

让 Kubernetes 把结果按照 YAML 格式输出。

然后:

> webcluster.yml

把输出保存到:

webcluster.yml

所以这一整条命令本质就是:

让 kubectl 帮我生成一个 Deployment YAML 文件

2. 看 YAML

核心内容:

apiVersion: apps/v1 kind: Deployment metadata: name: webcluster spec: replicas: 2 selector: matchLabels: app: webcluster template: metadata: labels: app: webcluster spec: containers: - image: myapp:v1 name: myapp

这里最重要的是理解:

Deployment ↓ Pod模板 ↓ Pod

3.replicas: 2

replicas: 2

表示:

始终保持 2 个符合条件的 Pod。

比如:

Pod 1 Pod 2

如果 Pod 1 挂了:

Pod 1 ❌ Pod 2 ✅

Deployment 会发现:

实际 = 1 期望 = 2

于是自动再创建一个:

Pod 1 ❌ Pod 2 ✅ Pod 3 ✅

这就是控制器的核心作用


4.selector是干什么的?

selector: matchLabels: app: webcluster

意思:

Deployment 通过app=webcluster这个标签寻找、管理自己的 Pod。

所以 Pod 模板里面必须有:

labels: app: webcluster

这两个要对应:

Deployment selector ↓ app=webcluster ↑ Pod labels app=webcluster

否则 Deployment 就不知道哪些 Pod 是自己的。


5.template是什么?

template:

可以理解成:

Pod 模板。

Deployment 并不是直接写:

pod1 pod2

而是告诉 Kubernetes:

按照这个模板创建 Pod。

例如:

template: spec: containers: - image: myapp:v1 name: myapp

意思:

创建 Pod 的时候,里面运行一个叫myapp的容器,使用myapp:v1

所以最终:

Deployment webcluster ↓ Pod模板 ↓ ┌─────┴─────┐ ↓ ↓ Pod-1 Pod-2 myapp:v1 myapp:v1

6.kubectl apply -f

kubectl apply -f webcluster.yml

意思:

根据 YAML 文件创建/更新 Kubernetes 资源。

于是:

webcluster.yml ↓ kubectl apply ↓ Deployment ↓ ReplicaSet ↓ 2个Pod

输出:

deployment.apps/webcluster created

说明 Deployment 创建成功。


7. 为什么会出现两个 Pod?

因为:

replicas: 2

所以:

kubectl get pods

看到:

webcluster-xxxx Running webcluster-yyyy Running

这两个 Pod 都属于:

Deployment webcluster

实际上中间还有一个 ReplicaSet:

Deployment ↓ ReplicaSet ↓ Pod Pod

这个层级一定要记住。


8.rollout history

kubectl rollout history deployment webcluster

查看 Deployment 的版本历史

第一次:

REVISION 1

表示:

当前 Deployment 的第一个版本。

之后你把:

myapp:v1

更新成:

myapp:v2

就产生:

REVISION 1 REVISION 2

所以你可以理解成:

Revision 1 myapp:v1 ↓ 更新 Revision 2 myapp:v2

9. 为什么要创建 Service?

执行:

kubectl expose deployment webcluster \ --port=80 \ --target-port=80 \ --type=NodePort

Deployment 本身主要负责:

管理 Pod。

但是客户端要访问 Pod,还需要:

Service。

所以:

客户端 ↓ Service ↓ Pod Pod

10.--port=80--target-port=80

这里很容易混。

--port=80

表示:

Service 对外提供的端口。

--target-port=80

表示:

Service 把流量转发到 Pod 的 80 端口。

所以:

客户端 ↓ Service:80 ↓ Pod:80

11.NodePort是什么?

得到:

80:30976/TCP

这里:

80

是 Service Port。

30976

是 NodePort。

所以你可以访问:

curl http://172.25.254.100:30976/

流量大概是:

172.25.254.100:30976 ↓ NodePort ↓ Service :80 ↓ ┌─────┴─────┐ ↓ ↓ Pod1 Pod2 :80 :80

所以你访问的是:

NodeIP:NodePort

12、版本更新

现在是整个实验的核心。

执行:

kubectl set image deployment/webcluster \ myapp=reg.timinglee.org/library/myapp:v2

意思:

修改 Deploymentwebcluster中,名字叫myapp的容器,把镜像从 v1 改成 v2。

原来:

Deployment ↓ myapp:v1 ↓ Pod v1 Pod v1

执行更新以后:

Deployment ↓ myapp:v2

然后 Deployment 会启动滚动更新


13. 什么叫滚动更新?

不是:

两个 v1 全部删除 ↓ 再创建两个 v2

而是逐步替换。

大概:

开始: Pod1 v1 Pod2 v1 更新: Pod1 v1 Pod2 v1 Pod3 v2 继续: Pod1 v1 Pod3 v2 Pod4 v2 最终: Pod3 v2 Pod4 v2

这样业务不会因为一次性删除所有旧 Pod 而直接中断。

这就是:

Rolling Update,滚动更新。


14. 为什么更新之后 Pod 名字变了?

之前:

webcluster-74f44fdcd7-25s4w webcluster-74f44fdcd7-f2jvc

更新以后:

webcluster-6c8b4bb9d7-hpxf7 webcluster-6c8b4bb9d7-kz46j

因为 Deployment 的 Pod 模板发生了变化:

myapp:v1 ↓ myapp:v2

因此 Deployment 创建了新的 ReplicaSet。

可以理解成:

Deployment │ ├── ReplicaSet A │ ├── Pod v1 │ └── Pod v1 │ └── ReplicaSet B ├── Pod v2 └── Pod v2

更新完成后:

ReplicaSet A Pod v1 Pod v1

被缩减到 0。

而:

ReplicaSet B Pod v2 Pod v2

变成 2 个。


15.rollout status

kubectl rollout status deployment/webcluster

查看滚动更新是否完成。

如果:

deployment "webcluster" successfully rolled out

就是:

滚动更新已经完成。


16. 再次查看 history

kubectl rollout history deployment webcluster

得到:

REVISION 1 2

意思:

Revision 1 → v1 Revision 2 → v2

17、版本回退

现在已经从:

v1 → v2

升级成功。

如果发现:

v2 有问题

怎么办?

不需要重新写 YAML。

直接:

kubectl rollout undo deployment webcluster --to-revision 1

意思:

把 Deployment 回退到 Revision 1。

也就是:

v2 ↓ 回退 ↓ v1

18. 为什么回退以后又出现新的 Pod?

回退并不是把原来的 Pod 原封不动拿回来。

Deployment 会重新调整 ReplicaSet。

可以理解为:

Revision 1 ↓ myapp:v1 Revision 2 ↓ myapp:v2

执行:

rollout undo --to-revision 1

以后:

Revision 1 的配置重新成为当前配置

然后 Kubernetes 再通过 ReplicaSet 创建新的 v1 Pod。

所以 Pod 名字仍然会变化。


19. 为什么回退之后 history 是 2 和 3?

你这里:

REVISION 2 3

第一次看到可能特别懵:

我明明回到 1 了,为什么没有 1?

这是 Deployment Revision 的一个很重要的特点。

你的过程实际上是:

第一次创建 Revision 1 v1 ↓ 更新 Revision 2 v2 ↓ 回滚 Revision 3 v1

所以:

Revision 3

实际上记录的是:

这次回滚操作产生的新 Deployment 状态。

它不是说:

3 = v3

而是:

Revision 3 → 当前内容又变成 v1

所以:

Revision 编号 ≠ 镜像版本号。

这一点考试和面试都很容易问。

20.总结

Deployment │ ↓ ReplicaSet │ ┌──────┴──────┐ ↓ ↓ Pod Pod │ │ └──────┬──────┘ ↓ Service │ ↓ NodePort │ ↓ 客户端访问

然后版本变化:

Deployment │ myapp:v1 ↓ ┌────────┴────────┐ ↓ ↓ Pod v1 Pod v1 ↓ set image v2 ↓ Deployment │ myapp:v2 ↓ ┌────────┴────────┐ ↓ ↓ Pod v2 Pod v2

如果 v2 出问题:

myapp:v2 ↓ 出问题 ↓ rollout undo ↓ myapp:v1

Pod 基本操作

# 查看 Pod kubectl get pods -o wide # 查看 Pod 详细信息 kubectl describe pod Pod名称 # 删除指定 Pod kubectl delete pod Pod名称 # 删除所有 Pod kubectl delete pods --all

Deployment

# 创建 Deployment kubectl create deployment # 创建/更新 YAML kubectl apply -f webcluster.yml # 查看 Deployment kubectl get deployment # 查看版本历史 kubectl rollout history deployment webcluster # 更新镜像 kubectl set image deployment/webcluster myapp=myapp:v2 # 查看更新进度 kubectl rollout status deployment/webcluster # 回滚 kubectl rollout undo deployment/webcluster --to-revision 1

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询