K8s 最小干活单元是 Pod,Pod 里面装容器;一般不直接手动管 Pod,交给控制器自动管。

一、基础概念
1. Pod 是什么?
Pod 就像一个豌豆荚,一个荚里面可以放 1 个或者多个容器(docker 容器)。 同一个 Pod 里面所有容器:共享网络、共享 IP,localhost就能互相访问;但是磁盘不共享,要用专门存储才可以。
重点:不要手动直接创建 Pod 上线业务。手动创建的 Pod 挂掉之后,不会自动复活。生产环境全部交给控制器管理 Pod。
2. 命名空间 Namespace
可以理解成集群里面的文件夹,用来把资源隔离开。 集群默认自带:default(默认文件夹,不指定就放这里)、kube-system(k8s 系统组件放这里)。
#看所有命名空间
kubectl get namespaces
#创建命名空间
kubectl create namespace 名字
#删除命名空间,命名空间里面所有东西会一起删掉
kubectl delete namespace 名字
3. K8s 三种管理资源方式
| 方式 | 说明 | 适合场景 |
|---|---|---|
| 命令式(敲命令直接操作) | kubectl run、kubectl delete,直接敲命令改资源 | 测试玩一玩,快速验证 |
| 命令式配置 | kubectl create -f xxx.yaml | 开发,简单项目 |
| 声明式配置(最推荐) | kubectl apply -f xxx.yaml,写 yaml 描述我想要什么状态,k8s 自动帮你达成 | 生产环境,支持版本回退,文件可以保存到 git |
apply:我想要 yaml 里面写的样子,集群没有就创建,不一样就更新;
create:只能新建,资源已经存在会报错。
二、Pod 常用命令(命令式操作)
#查看pod,-o wide看pod在哪台节点、podIP
kubectl get pods -o wide
#创建pod(仅测试用!生产不用)
kubectl run pod名字 --image=镜像名
#看pod详细信息,排错神器!报错就用describe看Events事件
kubectl describe pod pod名字
#删除pod
kubectl delete pod pod名字
#删除当前命名空间全部pod
kubectl delete pods --all
Pod 常见报错状态
ImagePullBackOff:拉镜像失败。镜像名字写错、仓库连不上、镜像不存在。
排错:
kubectl describe pod xxx看事件,会写清楚为啥拉不下来镜像。
CrashLoopBackOff:容器反复启动失败,启动完立刻崩掉,kubelet 反复重启它。
Burstable(中间):requests 和 limits 至少有一个没设置,且两者不相等。这类 Pod 在资源充足时可以用到上限,但节点资源紧张时会被优先回收,适合大多数普通业务。
Guaranteed(最高):requests 和 limits 都设置了且相等。这类 Pod 优先级最高,节点资源紧张时最不容易被驱逐,适合数据库、核心服务等关键业务。
BestEffort(最低):完全不设置 requests 和 limits。这类 Pod 优先级最低,节点资源紧张时最先被驱逐,只适合临时测试任务。
小结:生产环境建议尽量把核心服务配成 Guaranteed,普通业务用 Burstable,避免使用 BestEffort,这样能让集群在资源紧张时更稳定。
kubectl exec -it pod名字 -- /bin/bash #复制文件:宿主机 ↔ pod容器 #把容器里面文件拷到本机 kubectl cp pod名:/容器内路径 本机路径 #把本机文件拷进容器 kubectl cp 本机路径 pod名:/容器内路径 #attach连接pod(不推荐,会把你敲的命令全部记录进日志) kubectl attach -it pod名字
三、写 YAML 管理 Pod(声明式)
yaml 写清楚你想要 Pod 长啥样,kubectl apply -f pod.yml生效。
1. Pod 清单核心字段解释
apiVersion: v1 #API版本,pod固定v1
kind: Pod #资源类型:我要创建Pod
metadata:
name: testpod #pod名字
labels: #标签,给pod打标记,控制器靠标签找pod
app: myweb
spec: #这里写Pod详细配置
containers: #容器列表,可以写多个,代表一个pod多个容器
- name: myapp #容器名字
image: myapp:v1 #镜像名字
ports: #端口配置
- containerPort:80 #容器内部端口
hostPort:80 #宿主机节点端口,不建议用,端口会冲突
env: #设置环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
resources: #资源CPU内存限制
limits: #最大能用多少,不能超过
cpu: 500m
memory: 100M
requests: #调度的时候至少要给我分配这么多资源
cpu: 500m
memory: 100M
nodeSelector: #强制pod跑到指定节点机器上
kubernetes.io/hostname: k8s-node1
hostNetwork: false #true=直接用宿主机网络,podIP变成节点IP,慎用
restartPolicy: Always #重启策略
2. Pod 重启策略 restartPolicy(3 种)
Always(默认):不管怎么挂,永远重启容器。Deployment 控制器只能用这个。OnFailure:程序异常退出(返回非 0 错误码)才重启;正常执行完退出不重启。适合一次性任务。Never:容器退出,绝不重启。
3.QoS 服务质量(机器资源不够杀 Pod 的优先级)
当服务器 CPU 内存爆满,k8s 会杀掉一部分 Pod 释放资源,优先级从高到低:
- Guaranteed(最高,最后被杀):
requests和limitsCPU 内存数值完全一样。 - Burstable(中间):设置了 requests、limits,但是两者数值不一样。
- BestEffort(最低,最先被杀):完全不写 resources 资源限制。
生产环境重要业务一定要配置 Guaranteed,避免机器压力大被优先干掉。
4. 一个 Pod 跑多个容器
同一个 Pod 多个容器共享localhost网络,一个 nginx 容器,一个 busybox 容器,busybox 用localhost就访问 nginx。
坑:同一个 Pod 多个容器不能占用同一个端口,会端口冲突,容器启动报错。
5. init 容器(初始化容器)
Init 容器是 Pod 启动的时候最先跑的容器,必须全部 init 容器全部执行成功退出之后,业务主容器才会启动。 用途:做初始化工作:等待别的服务就绪、创建配置文件、下载资源。
init 容器必须运行到结束,不会一直后台运行。
spec:
initContainers:
- name: wait-service
image: busybox
command: ["/bin/sh","-c","until test -e /ok;do sleep 2;done"]
containers:
- name: myapp
image: myapp:v1
四、探针:检测容器活没活、能不能对外提供服务
kubelet 定期执行探针检查容器,一共 3 种探针。

1. livenessProbe 存活探针
判断容器进程是不是活着**。** 探测失败:直接杀掉容器,根据重启策略重启容器。
场景:进程卡死,但是容器没退出,状态还是 Running,但是业务访问报错。存活探针发现就把容器杀掉重建。
支持三种探测方式:
- tcpSocket:测试端口能不能连通
- httpGet:发 http 请求看返回码
- exec:在容器内部执行一条命令,返回码 0 代表成功
示例:
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3 #容器启动之后等3秒才开始探测
periodSeconds: 2 #每2秒探测一次
2. readinessProbe 就绪探针
判断容器业务能不能处理用户请求。 探测失败:不会杀容器!!只是把这个 Pod 从 Service 的后端端点移除,流量不再转发过来。 探测成功:再把 Pod 加回 Service,可以接收流量。
场景:程序启动慢,容器起来了,但是内部程序还没初始化完成,不能接收流量。就绪探针没成功,不给它转发流量。
3. startupProbe 启动探针
专门给启动特别慢的程序用。startupProbe 没成功之前,liveness 和 readiness 探针不运行。只要成功一次之后就不再执行。
两者核心区别记忆: 存活探针:进程死没死,死了杀掉重建 Pod 就绪探针:业务能不能干活,不能干活就摘掉流量,不杀 Pod
五、控制器(核心,生产环境用控制器管理 Pod)
不要手动创建 Pod!控制器负责帮我们创建、监控、更新、回滚 Pod。
常用控制器:ReplicaSet、Deployment、DaemonSet、Job、CronJob
1. ReplicaSet(副本控制器)
作用:保证集群里面永远维持指定数量的 Pod 副本。
- 如果 Pod 挂了,立刻新建 Pod 补数量;
- 如果手动删 Pod,控制器立刻新建一个;
- 如果 Pod 标签不匹配 selector 选择器,控制器不会管这个 Pod。
❗注意:一般不直接使用 ReplicaSet!Deployment 底层自动创建 ReplicaSet,我们操作 Deployment 即可。
2. Deployment(最常用,无状态业务,web 网站)
Deployment 是工作中 90% 场景使用的控制器。底层会自动创建 ReplicaSet。 能力:
- 维持指定副本数量;
- 滚动更新版本(升级镜像),升级的时候一边新建新版本 Pod,一边销毁旧版本 Pod,业务不中断;
- 版本回滚,升级出问题,一键退回上一个版本;
- 支持暂停更新、恢复更新。
常用 Deployment 命令
#命令快速创建deployment
kubectl create deployment webcluster --image myapp:v1 --replicas=2
#扩缩容,修改副本数量
kubectl scale deployment webcluster --replicas=4
#升级镜像版本
kubectl set image deployment/webcluster myapp=myapp:v2
#查看版本历史记录
kubectl rollout history deployment webcluster
#回滚,不加--to-revision就回退上一版
kubectl rollout undo deployment webcluster --to-revision=1
#暂停更新,修改配置不会立刻生效
kubectl rollout pause deployment webcluster
#恢复更新,此时才执行变更
kubectl rollout resume deployment webcluster
#重启全部pod
kubectl rollout restart deployment webcluster
Deployment 滚动更新策略
spec:
replicas: 6
strategy:
rollingUpdate:
maxSurge: 1 #更新过程最多比期望副本多出来几个Pod
maxUnavailable: 0 #更新的时候,最多允许几个Pod不可用,0代表更新过程所有Pod都不能少
maxUnavailable=0:升级的时候不会先删旧 Pod,先把新 Pod 跑起来,再删旧 Pod,零停机。
revisionHistoryLimit:保存多少个历史 ReplicaSet,用于回滚,默认 10。
3. DaemonSet 守护集
每一个节点机器上,运行一个 Pod。新增节点机器,自动在新机器跑一个 Pod。 适合:日志采集、监控代理、网络插件(flannel)。
Deployment 是不管机器,只管 Pod 数量;DaemonSet 每个节点一台一个 Pod。
4. Job 控制器(一次性任务)
运行一次性任务,任务执行完就结束,Pod 变成 Completed 完成状态。 参数:
completions:一共要成功完成多少个任务实例parallelism:最多同时跑几个任务实例backoffLimit:失败重试次数
适合:数据备份、批量计算,跑完就完事。
5. CronJob 定时任务控制器
定时执行 Job,类似 linux 的 crontab 定时任务。 schedule:* * * * * 分 时 日 月 周。
六、Service 服务(给一组 Pod 提供统一访问入口)
Pod 是会销毁重建的,PodIP 会变,不能直接拿 PodIP 访问业务。 Service 给一组 Pod 提供固定访问入口,做负载均衡,把请求转发给后端 Pod。
#把deployment暴露成service
kubectl expose deployment webcluster --port 80 --target-port 80
#--port service端口,--target-port pod容器端口
#查看service
kubectl get svc
#看service详情,看后端endpoints对应哪些podIP
kubectl describe svc webcluster
Service 几种类型:
- ClusterIP(默认):集群内部访问,集群外部访问不到。
- NodePort:每台机器开放一个端口,外部访问
节点IP:NodePort端口访问业务。 - LoadBalancer:云厂商负载均衡。
Service 通过标签 selector 筛选 Pod,只要 Pod 标签匹配,自动加入后端列表。结合就绪探针,如果就绪探针失败,Pod 自动从 Service 后端移除。
七、标签 Label
给 Pod、控制器打标签,key=value 格式。控制器靠标签筛选要管理哪些 Pod。
#给pod打标签
kubectl label pods pod名字 key=value
#删除标签,key后面加减号
kubectl label pods pod名字 key-
#查看资源带标签输出
kubectl get pods --show-labels
坑:如果手动把 Deployment 管理的 Pod 标签删掉,Pod 脱离控制器管理;Deployment 会立刻新建一个符合标签的 Pod。
八、容易踩坑的重点总结
- 不直接创建裸 Pod 做业务,Pod 挂了不会自动重建;优先用 Deployment。
- 同一个 Pod 多个容器共享网络,不能冲突端口。
- liveness 探针:进程挂掉杀掉重建 Pod;readiness 探针:业务没准备好摘掉流量,不杀 Pod。
- Deployment 滚动更新:升级不停业务,可以回滚版本。
- DaemonSet 每个节点运行一个 Pod,适合日志、监控组件。
- Job 一次性任务;CronJob 定时一次性任务。
- QoS 优先级:Guaranteed > Burstable > BestEffort,机器资源不足优先杀 BestEffort。
- init 容器全部跑完,业务容器才启动。
- Service 依靠标签找后端 Pod,PodIP 会变,ServiceIP 固定不变。
- yaml 文件使用
kubectl apply声明式管理,方便保存,方便回滚。