Kubernetes Pod 与控制器知识点

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(中间):requestslimits 至少有一个没设置,且两者不相等。这类 Pod 在资源充足时可以用到上限,但节点资源紧张时会被优先回收,适合大多数普通业务。

Guaranteed(最高):requestslimits 都设置了且相等。这类 Pod 优先级最高,节点资源紧张时最不容易被驱逐,适合数据库、核心服务等关键业务。

BestEffort(最低):完全不设置 requestslimits。这类 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 种)

  1. Always(默认):不管怎么挂,永远重启容器。Deployment 控制器只能用这个。
  2. OnFailure:程序异常退出(返回非 0 错误码)才重启;正常执行完退出不重启。适合一次性任务。
  3. Never:容器退出,绝不重启。

3.QoS 服务质量(机器资源不够杀 Pod 的优先级)

当服务器 CPU 内存爆满,k8s 会杀掉一部分 Pod 释放资源,优先级从高到低:

  • Guaranteed(最高,最后被杀):requestslimitsCPU 内存数值完全一样。
  • 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。

常用控制器:ReplicaSetDeploymentDaemonSetJobCronJob

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声明式管理,方便保存,方便回滚。
相关推荐
高磊20051 小时前
Kubernetes Pod 管理实战详解
linux·容器·kubernetes
流星白龙1 小时前
【Docker】9.Docker 镜像仓库实战
运维·docker·容器
想要成为老金高手2 小时前
Kubernetes 实战笔记(一):Pod 管理与 kubectl 核心命令全解
笔记·容器·kubernetes
张洛闻Eren2 小时前
云原生k8s【第六课】:K8s 访问控制
运维·docker·云原生·容器·kubernetes·k8s
Kina_C2 小时前
Kubernetes Pod 全生命周期管理:从命令实操到控制器版本更替
云原生·容器·kubernetes
奇特認2 小时前
kubernetes pod管理
云原生·容器·kubernetes
mohesashou2 小时前
k8s控制器管理
云原生·容器·kubernetes
Cicada1283 小时前
微服务是怎么长出来的
微服务·云原生·架构
王da魔3 小时前
Pod管理及优化
云原生·kubernetes