k8s的pod管理与控制器 一、pod1.Pod 核心概念Pod 是 K8s 最小调度单元不是容器一个 Pod 可以运行 1 个或多个容器。Pod 内容器共享网络命名空间 (Pod‑IP)、共享存储 (volume)。Pod 生命周期短暂Pod 删除后不能复活重建就是全新 PodPod‑IP 会变。裸 Pod直接 kubectl run /yaml 创建不受控制器管理删除之后不会自动重建。生产几乎不直接创建裸 Pod一般由控制器管理 PodDeployment、ReplicaSet、StatefulSet、DaemonSet、Job、CronJob。2.Pod 生命周期状态状态含义Pending已经存入 etcd还没调度 / 正在拉取镜像ContainerCreating调度完成节点 kubelet 正在创建容器、拉镜像Running容器已经启动正常运行Succeeded一次性任务执行完成正常退出Failed容器异常崩溃退出Unknownapiserver 和节点 kubelet 通信中断常见报错状态ErrImagePull / ImagePullBackOff镜像拉取失败CrashLoopBackOff容器反复启动崩溃3.Pod 常用管理命令[rootk8s-master ~]# kubectl get namespaces #查看命名空间[rootk8s-master ~]# kubectl create namespace llj #创建命名空间[rootk8s-master ~]# kubectl delete namespaces llj #删除命名空间[rootk8s-master ~]# kubectl run llj --image nginx:latest #创建 pod 指定命名空间裸 Pod无控制器[rootk8s-master ~]# kubectl get pods -n llj 查看指定命名空间资源[rootk8s-master ~]# kubectl get pods -o wide #查看 Pod 列表(PodIP、运行在哪个节点)[rootk8s-master ~]# kubectl get pod llj -o yaml #查看pod完整yaml[rootk8s-master ~]# kubectl describe pod llj #查看pod详细事件、状态信息[rootk8s-master ~]# kubectl get pods -w #实时监控pod状态变化[rootk8s-master ~]# kubectl exec -it llj -- /bin/sh #交互式进入容器[rootk8s-master ~]# kubectl logs llj #查看日志[rootk8s-master ~]# kubectl logs -f llj #持续实时日志[rootk8s-master ~]# kubectl attach pod llj #连接到容器标准输出看控制台流attach 实时连接容器logs 读取已生成日志[rootk8s-master ~]# kubectl delete pod llj #按名字删除单个pod[rootk8s-master ~]# kubectl delete pods --all #删除default下所有pod-n指定其他nstips如果 Pod 是 Deployment 管理的删除 Pod 后ReplicaSet 立刻新建一个 Pod 补足副本数Pod 杀不完要么删deployment要么缩副本数为 0或删除 yaml 资源文件[rootk8s-master ~]# kubectl label pod llj envtest #给pod打标签[rootk8s-master ~]# kubectl label pod testpod env- #删除标签[rootk8s-master ~]# kubectl get pods --show-labels #查看所有pod的标签[rootk8s-master ~]# kubectl get pods -l appwebcluster #标签筛选pod二、控制器1.控制器是什么控制器运行在 kube‑controller‑manager负责管理 Pod 的生命周期实现自愈、扩容缩容、滚动更新、任务调度。裸 Podkind:Pod没有控制器管理删除之后不会重建。被控制器管理的 Pod控制器监控实际状态不断向期望状态对齐。2.6 种最常用控制器控制器作用适用场景Deployment无状态应用支持滚动更新、回滚Web 网站myapp、nginx最常用ReplicaSet保证一定数量 Pod 副本存活Deployment 底层依赖一般不直接创建StatefulSet有状态应用Pod 名称、IP 稳定有序MySQL 主从、Redis 集群DaemonSet每一个节点运行 1 个 Pod日志采集、监控代理、flannel 网络Job一次性任务执行完成 Pod 退出就结束备份、一次性脚本任务CronJob定时周期性执行任务每天凌晨备份定时任务(1)Deployment重中之重面试最高频Deployment上层管理者负责版本、滚动更新、回滚ReplicaSet保证副本数量Pod 挂了立刻重建Pod业务容器实例核心能力自愈Pod 崩溃、节点宕机自动重建 Pod扩容缩容修改副本数量滚动更新升级镜像逐步替换旧 Pod业务不中断版本回滚升级失败可以退回旧版本[rootk8s-master ~]# kubectl create deployment webcluster --image myapp:v1 #创建 Deployment[rootk8s-master ~]# kubectl edit deployments.apps webcluster #在线直接编辑 Deployment yaml实时生效edit全量编辑patch局部修改[rootk8s-master ~]# kubectl patch deployment nginx -p {spec:{replicas:2}} #修改副本数增量打补丁局部修改不用改完整 yaml[rootk8s-master ~]# kubectl expose deployment nginx --port80 --target-port80 #给 Pod 套一层访问入口Service外部 / 集群内可以通过 Service 访问 Pod,这条命令等价于手动写一份 Service 的 yaml 然后kubectl apply[rootk8s-master ~]# kubectl cp /tmp/test.txt pod名:/root/ #主机文件传到pod[rootk8s-master ~]# kubectl cp pod名:/root/test.txt /tmp/ #pod文件拷回主机[rootk8s-master ~]# kubectl rollout history deployment nginx #查看更新历史[rootk8s-master ~]# kubectl rollout undo deployment nginx #回滚上一版本[rootk8s-master ~]# kubectl rollout status deployment nginx #查看发布状态tipsrollout 只能用于 Deployment、DaemonSet、StatefulSet[rootk8s-master ~]# kubectl scale deployment nginx --replicas3 #扩缩副本数[rootk8s-master ~]# kubectl scale deployment nginx --replicas0 #扩缩副本数[rootk8s-master ~]# kubectl label deployment nginx envtest #给deployment打标签命令作用对象核心用途create deploymentDeployment创建edit deploymentDeployment全量在线修改 yamlpatch deploymentDeployment局部增量修改expose deploymentDeployment生成 Servicerollout deploymentDeployment滚动更新 / 回滚scale deploymentDeployment扩缩副本label任意资源打标签logsPod查看日志attachPod附着容器控制台execPod进入容器执行命令cpPod容器与主机传文件(2)ReplicaSet作用维持指定副本数量几乎不会单独创建 ReplicaSet由 Deployment 自动创建。如果你直接删 PodReplicaSet 马上新建 Pod 补足数量。kubectl get rs(3)DaemonSet特点集群每个节点上都会启动 1 个 Pod新增节点也会自动部署 Pod。典型例子flannel、监控、日志收集。kubectl get ds(4)StatefulSet有状态应用Deployment 创建出来的 Pod 是无状态随机名字IP 每次重建都会变StatefulSet Pod 名字固定有序mysql‑0、mysql‑1Pod 网络标识稳定不变。适合数据库集群。kubectl get statefulsets(5)Job 一次性任务Pod 执行完任务正常结束不再重启。(6)CronJob 定时任务类似 Linux crontab周期性定时运行 Jobtips: Deployment无状态web 业务滚动更新回滚DaemonSet每个节点跑 1 个 Pod网络插件 flannel 就是 DaemonSetStatefulSet有状态数据库集群Pod 名字固定Job一次性任务CronJob定时任务ReplicaSet 只管副本数没有版本管理能力不能回滚裸 Pod VS 控制器管理 Pod最重要考点1. 裸 Podkind:Pod没有上层控制器删除 Pod → 不会自动重建不会滚动更新、扩容缩容实验测试临时使用生产禁止。2. Deployment最常用无状态 Pod 控制器Deployment → ReplicaSet → PodDeployment 负责版本、滚动更新、回滚ReplicaSet 负责保证指定数量副本 Pod 一直活着直接删除 Deployment级联删除 RS 所有 PodClusterIP 实验的工作原理与完整时序流程图通过Deployment webclusterDeployment不直接创建 Pod只管理 ReplicaSetkubectl apply -f deploy.yaml提交 Deployment 到 APIServerapiserver 校验 yaml 格式把 Deployment 资源存入 etcd 数据库Deployment 控制器发现期望副本replicas:2当前没有ReplicaSet创建一个 ReplicaSet 资源RS 模板完全复制 Deployment 的 pod 模板RS 控制器读取自己的配置spec.replicas:2 期望 2 个 Podspec.selector.matchLabels: app:webcluster 筛选属于自己的 Pod查询 etcd当前没有匹配标签的 Pod于是 RS 按照 template构造 2 个 Pod 对象提交给 apiserver 存入 etcd。kube‑scheduler调度器发现一批 spec.nodeName(主机名 为空的Pending Pod调度算法选出节点把节点名写入Pod.spec.nodeName已经把 Pod 绑定到该节点更新etcd。kubelet 监听 apiserver 的 Pod 资源变化收到事件有一个 Podspec.nodeName 当前节点主机名这个 Pod 归我管理。真正开始在节点构建 Podkubelet 开始干活①拉取镜像 myapp:v1②准备存储、环境变量③调用 CNI‑flannel 分配 PodIP配置 veth‑pair 网络④调用容器运行时 (containerd/docker)↓创建2个Pod给每个Pod的 metadata.labels app:webcluster↓CNI(flannel)给每个Pod分配PodIPPod ReadyTrue↓Endpoints控制器读取Service.spec.selector(app:webcluster)筛选出这两个Pod取出PodIP targetPort(80)↓存入同名Endpoints资源webservice↓Service iptables/ipvs读取Endpoints列表做负载均衡curl ClusterIP → 轮流转发到 10.244.2.8:80 / 10.244.5.95:80service的ipvs模式1.在所有节点中安装ipvsadm工具[rootk8s-master ~]# for name in 100 10 20 254 do ssh -l root 172.25.254.$name dnf install ipvsadm -y done2.配置集群中的kube-proxy[rootk8s-master ~]# kubectl -n kube-system edit cm kube-proxy59 mode: ipvs #修改 kube‑proxy ConfigMap 开启 ipvs 模式tips改完 ConfigMap 不会自动生效ConfigMap 更新了但是现存的 kube‑proxy Pod 不会自动读取新配置必须重建 kube‑proxy Pod新启动的 Pod 才会加载 mode:ipvs[rootk8s-master ~]# kubectl -n kube-system get pods[rootk8s-master ~]# kubectl -n kube-system delete pods kube-proxy-7cjrg kube-proxy-7vpjw kube-proxy-hnrqf #删除所有 kube‑proxy podDeployment会自动重建[rootk8s-master ~]# ipvsadm -Ln #验证是否已经切换 ipvs 模式