Kubernetes(2)pod的管理及优化
【一】Kubernetes 资源管理与操作方式
1.1 资源管理介绍
-
Kubernetes 把一切抽象为“资源”,用户通过操作资源来管理集群。
-
集群中运行服务 = 运行容器,而容器必须放在 Pod 内。
-
最小管理单元是 Pod,但通常不直接操作 Pod,而是借助 Pod 控制器 进行生命周期管理。
-
Pod 的访问通过 Service 实现,数据持久化则依赖 Kubernetes 提供的各类存储系统。
-
1.2 资源管理方式
类型 | 适用环境 | 优点 | 缺点 |
---|---|---|---|
命令式对象管理 | 测试 | 简单快捷 | 无法审计、无法跟踪 |
命令式对象配置 | 开发 | 可审计、可跟踪 | 配置文件多、操作繁琐 |
声明式对象配置 | 开发/生产 | 支持目录级操作、天然版本化 | 异常时调试略复杂 |
1.2.1 命令式对象管理
-
命令格式:
kubectl [command] [type] [name] [flags]
-
示例:
kubectl get pod kubectl get pod pod_name -o yaml
1.2.2 资源类型与常用命令
-
查看全部资源:
kubectl api-resources
-
常见资源包括 Pod、Deployment、Service、ConfigMap、Secret 等。
-
常用调试命令速查:
-
kubectl version
-
kubectl cluster-info
-
kubectl explain <资源>
-
kubectl create deployment web --image nginx --replicas 2
-
kubectl patch deployment web -p '{"spec":{"replicas":4}}'
-
kubectl delete deployment web
-
1.2.3 运行与调试命令示例
-
快速运行 Pod
kubectl run testpod --image nginx kubectl expose pod testpod --port 80 --target-port 80 curl <ClusterIP>
-
日志与交互:
kubectl logs testpod kubectl exec -it testpod -- /bin/bash kubectl cp anaconda-ks.cfg testpod:/
-
生成并应用 YAML:
kubectl create deployment webcluster --image nginx --dry-run=client -o yaml > webcluster.yml kubectl apply -f webcluster.yml kubectl delete -f webcluster.yml
-
标签管理:
kubectl label pods nginx app=web kubectl label pods nginx app- # 删除标签
【二】Pod 基础与两种创建模式
2.1 Pod 概念
-
最小可部署单元:一个 Pod 代表集群中运行的一个进程,拥有唯一 IP。
-
豌豆荚模型:可包含 1 个或多个容器,共享 IPC、Network、UTC namespace。
-
共享存储与端口:同一 Pod 内容器通过 localhost 通信,端口需避免冲突。
2.2 创建自主式 Pod(不推荐生产使用)
优点 | 缺点 |
---|---|
灵活、学习调试方便、一次性任务快速验证 | 管理复杂、缺乏高可用、无法自动扩缩、可维护性差 |
示例:
kubectl run timinglee --image nginx
kubectl get pods -o wide
一个pod里可以运行多个容器
创建pod模版
刚刚这里有一个运行成功,有一个失败,因为两个都是使用nginx的镜像,第一个占用了80端口,第二个肯定用不了了
修改配置文件,把第二个容器修改所需镜像,不再争取一个接口
此时两个容器就都能用了
缠绕启动之前创建的容器
虽然没有安装nginx,但是却也可以访问成功测试页面
因为它们位于一个pod中,是共用一个网络栈的,所以也能够访问到nginx测试页
可是这样写pod的维护性很差
查看当前命名空间的pod
查看所有命名空间里的pod
查看所有pod的详细信息
2.3 利用控制器管理 Pod(生产推荐)
能力 | 带来的价值 |
---|---|
高可用 | 自动故障恢复、健康检查与自愈 |
可扩展 | 一键扩缩容、HPA 自动弹性 |
版本管理 | 滚动更新、回滚、声明式配置 |
服务发现 | Service 自动负载均衡 |
多环境一致 | 同一套 YAML 跨环境复用 |
示例:
# 创建并扩容
kubectl create deployment timinglee --image nginx
kubectl scale deployment timinglee --replicas 6
kubectl scale deployment timinglee --replicas 2
2.4 应用版本更新
# 创建 v1 并暴露
kubectl create deployment timinglee --image myapp:v1 --replicas 2
kubectl expose deployment timinglee --port 80 --target-port 80
curl <ClusterIP> # 返回 v1# 滚动升级到 v2
kubectl set image deployment/timinglee myapp=myapp:v2
kubectl rollout history deployment timinglee
curl <ClusterIP> # 返回 v2# 回滚
kubectl rollout undo deployment timinglee --to-revision 1
curl <ClusterIP> # 再次返回 v1
还可以设定IP地址
#建立控制器并自动运行pod
#为timinglee扩容
、
#为timinglee缩容
应用版本的更新
#利用控制器建立pod
#暴漏端口
访问服务
[root@k8s-master ~]# curl 10.110.195.120
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ~]# curl 10.110.195.120
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
指定版本,会把老的版本关闭,开启新版本的内容
这些功能实际上是控制器的功能
2.4.1 使用 YAML 部署应用的优点
-
声明式配置:清晰描述期望状态,天然支持 Git 版本控制与回滚。
-
灵活可扩展:一份文件可组合 Deployment / Service / ConfigMap / Secret 等多资源。
-
CI/CD 友好:与 GitOps、Argo CD、Flux 等工具无缝集成。
2.4.2 资源清单常用字段速查表
字段 | 类型 | 说明 |
---|---|---|
apiVersion | String | API 版本,如 v1 、apps/v1 |
kind | String | 资源类型:Pod、Deployment、Service … |
metadata.name | String | 对象名称,同一命名空间唯一 |
metadata.namespace | String | 所属命名空间 |
spec.containers[] | List | 容器定义列表 |
spec.containers[].image | String | 镜像名称 |
imagePullPolicy | String | Always / IfNotPresent / Never |
command / args | List | 启动命令与参数 |
workingDir | String | 工作目录 |
ports[].containerPort | Int | 容器监听端口 |
ports[].hostPort | Int | 宿主机映射端口(慎用,易冲突) |
env[].name / value | String | 环境变量 |
resources.requests | Object | 调度所需最小资源 |
resources.limits | Object | 运行时最大可用资源 |
restartPolicy | String | Always / OnFailure / Never |
nodeSelector | Map | 节点选择标签 |
hostNetwork | Boolean | true=共享宿主机网络 |
2.4.3 如何获得资源帮助
kubectl explain pod.spec.containers
2.4.4 YAML 编写实战示例
2.4.4.1 运行单个容器 Pod
apiVersion: v1
kind: Pod
metadata:name: timingleelabels: { run: timing }
spec:containers:- name: timingleeimage: myapp:v1
kubectl run timinglee --image myapp:v1 --dry-run=client -o yaml > pod.yml
2.4.4.2 多个容器注意事项
-
端口冲突示例:两个 nginx 同时监听 80 → Pod 报错
CrashLoopBackOff
。 -
正确做法:不同容器使用不同端口或功能互补(如 sidecar)。
-
运行多个容器pod
一个端口干扰示例:
在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰
2.4.4.3 共享网络验证
# 同一 Pod 内 localhost 互通
kubectl exec test -c busyboxplus -- curl -s localhost
2.4.4.4 端口映射
ports:
- containerPort: 80hostPort: 80 # 节点 IP:80 即可访问
2.4.4.5 环境变量
env:
- name: NAMEvalue: timinglee
2.4.4.6 资源限制与 QoS
-
Guaranteed:requests = limits
-
Burstable:只设 requests 或 requests ≠ limits
-
BestEffort:未设 requests/limits(优先级最低)
2.4.4.7 容器启动管理
-
restartPolicy: Always 下,手动
docker rm
容器 → kubelet 立即重启。
2.4.4.8 选择运行节点
nodeSelector:kubernetes.io/hostname: k8s-node1
2.4.4.9 共享宿主机网络
hostNetwork: true # Pod 直接使用节点网络栈,可看到节点所有网卡
【三】Pod 生命周期与初始化容器(Init Container)
3.1 Init 容器:概念与功能
-
执行顺序:先于应用容器启动,必须全部成功完成后,主容器才会并行启动。
-
特性
-
总是运行到完成(Completed),不支持 Readiness Probe。
-
如果失败且
restartPolicy=Always
,Pod 将持续重启直至 Init 成功;若restartPolicy=Never
,则直接失败不再重启。
-
-
典型用途
-
运行一次性准备逻辑(数据库迁移、配置文件渲染、依赖检查)。
-
使用与主容器不同的镜像,避免把运维工具打包进业务镜像。
-
延迟应用启动,直到外部依赖就绪(例如等待 MySQL 端口可连接)。
-
3.1.2 Init 容器示例
apiVersion: v1
kind: Pod
metadata:name: initpod
spec:containers:- name: myappimage: myapp:v1initContainers:- name: init-myserviceimage: busyboxcommand: ["sh","-c","until test -e /testfile; do echo waiting; sleep 2; done"]
但是如果是server 展现的内容就很详细
在文件里编辑
引用的镜像
ommand在init容器里做的事情
init是最优先运行的,只有它运行完成,退出init容器后,才能运行上面的内容
会每隔两秒检测这个文件是否存在,检测不到就会一直输出后面的语句wating ~~
会一直检测init容器是否成功开启,开启了才会结束检测,否则一直检测
运行yml文件,这里没有成功,init还在检测,是因为没有拉取成功镜像
上传镜像到仓库中
重新拉取镜像
但是现在还不能运行成功
因为前面的文件没找到,系统中并不不存在testfile这个文件
查看它给我们的输出内容
验证流程:
kubectl apply -f pod.yml
kubectl get pods # 状态 Init:0/1
kubectl exec initpod -c init-myservice -- touch /testfile
kubectl get pods # 状态转为 Running
用命令创建这个文件
现在就成功了,状态也running了
删除yml文件
【四】探针(Probe):保障业务健康的三把“探照灯”
4.1 探针类型与行为
探针 | 触发失败时的动作 | 默认状态 |
---|---|---|
livenessProbe | kubelet 杀死容器 → 按重启策略处理 | Success |
readinessProbe | 从 Service Endpoints 摘除 Pod IP | Success |
startupProbe | 先禁用其他探针;失败则重启容器;成功一次后不再探测 | Success |
探测方式
-
ExecAction:容器内执行命令,返回码为 0 即成功。
-
TCPSocketAction:对指定端口进行 TCP 连通性检查。
-
HTTPGetAction:对指定路径/端口做 HTTP GET,状态码 200–399 为成功。
4.2 探针实战示例
4.2.1存活探针(livenessProbe)
livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 3periodSeconds: 1timeoutSeconds: 1
结果:8080 端口未监听 → Pod 进入 CrashLoopBackOff
,日志中可见 connection refused
。
4.2.2 就绪探针(readinessProbe)
readinessProbe:httpGet:path: /test.htmlport: 80initialDelaySeconds: 1periodSeconds: 3
步骤:
kubectl expose pod readiness --port 80
kubectl describe svc readiness # Endpoints 为空
kubectl exec readiness -- /bin/sh -c "echo ok > /usr/share/nginx/html/test.html"
kubectl describe svc readiness # Endpoints 出现 Pod IP
#没有暴漏端口,就绪探针探测不满足暴漏条件
只有当 /test.html
返回 200 时,Pod IP 才会被加入 Service,实现“就绪即流量”。
【第五部分】Pod 的优雅终止与滚动升级细节
5.1 优雅终止流程(Graceful Shutdown)
-
删除 Pod(
kubectl delete pod xxx
或 Deployment 滚动更新触发) -
API Server 将 Pod 置为 Terminating,并通知 kubelet。
-
Endpoints Controller 立即把 Pod IP 从所有 Service 中摘除 → 不再接收新流量。
-
kubelet 同时执行两步:
-
如果配置了
preStop
Hook,先运行该脚本(如通知注册中心下线)。 -
向容器主进程发送 TERM 信号;等待
terminationGracePeriodSeconds
(默认 30s)。
-
-
超时仍未退出:发送 KILL 信号强制终止。
-
容器全部退出后,kubelet 删除 Pod 对象,完成生命周期。
示例:
spec:terminationGracePeriodSeconds: 60containers:- name: applifecycle:preStop:exec:command: ["/bin/sh","-c","sleep 10 && /app/grace-stop.sh"]
5.2 Deployment 滚动升级流程拆解
阶段 | 发生事件 |
---|---|
1. 更新镜像 | kubectl set image deployment/myapp myapp=myapp:v2 |
2. 新建 ReplicaSet | 新 RS 创建 v2 Pod,副本数从 0 → 1 → 2 … |
3. 旧 Pod 逐一下线 | 每启动一个新 Pod,旧 RS 缩容 1 个,确保可用副本 ≥ (replicas - maxUnavailable) |
4. ReadinessGate 校验 | 仅当新 Pod readinessProbe 通过,才继续下一步 |
5. 完成/回滚 | 全部新 Pod Ready 后旧 RS 副本数为 0;若失败可随时 kubectl rollout undo |
参数速记:
strategy:type: RollingUpdaterollingUpdate:maxSurge: 25% # 升级期间最多额外启动的 PodmaxUnavailable: 25% # 允许的最大不可用比例
5.3 零中断升级最佳实践
-
PodDisruptionBudget (PDB):保证升级/驱逐时最小可用副本数
apiVersion: policy/v1 kind: PodDisruptionBudget metadata:name: myapp-pdb spec:minAvailable: 2selector:matchLabels: { app: myapp }
-
readinessProbe 必须覆盖真实启动耗时,避免“未就绪就上线”。
-
preStop 延迟 + 优雅关闭,确保注册中心、连接池、队列客户端优雅下线。
-
【第六部分】Pod 网络模型深度解析
6.1 集群内网络三大原则
-
每个 Pod 拥有独立 IP:跨节点、跨命名空间均可直接通过该 IP 访问。
-
所有 Pod 之间 无需 NAT 即可通信(扁平网络)。
-
节点与 Pod、Pod 与 Service 之间同样无需 NAT。
-
实现层面由 CNI 插件(Calico、Flannel、Cilium 等)通过 Linux Bridge/VXLAN/eBPF 等技术完成。
6.2 Pod 内容器共享网络栈
-
同一 Pod 内所有容器共享同一个 Network Namespace(IP、端口空间一致)。
-
localhost 互通:容器 A 访问容器 B 的端口,直接
localhost:<port>
。 -
端口冲突风险:多个容器监听同一端口会触发
bind: address already in use
。 -
解决方案:
-
不同容器监听不同端口;
-
或使用 sidecar 代理(如 Envoy)统一入口。
-
-
6.3 Pod 与 Service、Ingress 的协作流程
-
Pod → Pod:直接
pod-ip:container-port
。 -
Pod → Service:通过 ClusterIP(虚拟 IP)由 kube-proxy 转发到后端 Pod。
-
6.4 网络策略(NetworkPolicy)示例
默认集群 全通,可通过 NetworkPolicy 实现细粒度隔离:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:name: allow-app-to-db spec:podSelector: { matchLabels: { app: db } }ingress:- from:- podSelector: { matchLabels: { app: backend } }ports:- protocol: TCPport: 3306
作用:仅允许标签
app=backend
的 Pod 访问app=db
的 3306 端口,其余流量全部拒绝。 -
集群外 → Pod:
-
NodePort / LoadBalancer Service → kube-proxy → Pod;
-
Ingress Controller(Nginx、Traefik、Gateway API)→ Service → Pod。
-
【第七部分】Pod 存储全景:从临时卷到持久化
7.1 存储分类速览
类型 | 生命周期 | 典型用途 | 示例 |
---|---|---|---|
emptyDir | 随 Pod 创建而创建,随 Pod 删除而销毁 | 缓存、临时文件、共享目录 | emptyDir: {} |
hostPath | 与节点生命周期一致 | 单节点测试、日志收集 | hostPath: { path: /data } |
ConfigMap / Secret | 独立对象,可被多 Pod 挂载 | 配置、证书、密钥 | configMapRef: name: app-config |
PersistentVolume (PV) | 集群级资源,生命周期独立于 Pod | 数据库、文件存储 | NFS、Ceph、EBS |
PersistentVolumeClaim (PVC) | 用户对 PV 的申请 | 解耦应用与底层存储 | ReadWriteOnce 10Gi |
7.2 临时卷 emptyDir 实战
apiVersion: v1
kind: Pod
metadata:name: cache-pod
spec:containers:- name: appimage: nginxvolumeMounts:- name: cachemountPath: /tmp/cachevolumes:- name: cacheemptyDir: {}
两个容器挂载同一 emptyDir
即可实现 Pod 内共享高速缓存。
可指定 medium: Memory
把卷映射到节点 tmpfs,提升 IO 性能(数据随节点掉电丢失)。
# StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:type: gp3# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: db-data
spec:accessModes: [ReadWriteOnce]resources: { requests: { storage: 50Gi } }storageClassName: fast-ssd
7.3 安全与性能小贴士
动态供应示例:
7.4 持久化卷 PVC → PV 绑定流程
-
Secret 挂载默认只读;如需热更新,可使用
subPath
+inotify
。 -
PV Reclaim Policy:Retain / Delete / Recycle,生产环境建议
Retain
防止误删数据。 -
节点亲和性:
volumeBindingMode: WaitForFirstConsumer
让调度器先选节点再动态创建云盘,避免跨可用区挂载。 -
管理员创建 PV(静态供应)或 StorageClass(动态供应)。
-
用户声明 PVC:指定容量、访问模式、StorageClass。
-
控制器执行绑定:满足条件的 PV 与 PVC 一对一绑定。
-
Pod 引用 PVC:通过
persistentVolumeClaim
字段挂载。
【第八部分】Pod 可观测性:日志、指标、链路三件套
8.1 日志采集全景
维度 | 方案 | 特点 |
---|---|---|
stdout/stderr 日志 | 容器默认输出 | kubelet 自动轮转 10 MiB × 5 文件,需外部收集。 |
节点级收集 | DaemonSet + Fluent Bit / Filebeat | 低耦合、支持多租户隔离。 |
Sidecar 日志 | 额外容器 tail -F | 不改镜像即可适配旧应用。 |
日志架构 | Fluent Bit → Kafka → Elasticsearch → Kibana | 高吞吐、可检索。 |
示例 DaemonSet 片段:
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluent-bit
spec:template:spec:containers:- name: fluent-bitimage: cr.fluentbit.io/fluent/fluent-bit:2.2volumeMounts:- name: varlogmountPath: /var/log- name: varlibdockermountPath: /var/lib/docker/containersvolumes:- name: varloghostPath: { path: /var/log }- name: varlibdockerhostPath: { path: /var/lib/docker/containers }
8.2 指标监控体系
层级 | 组件 | 关键指标 |
---|---|---|
集群 | metrics-server | CPU、Memory 使用率,HPA 依赖。 |
节点 | node-exporter | CPU、Load、Disk、Network。 |
Pod | kube-state-metrics | Pod 重启次数、容器状态、PVC 绑定。 |
业务 | Prometheus SDK | 自定义 QPS、延迟、队列深度。 |
Prometheus 抓取配置:
- job_name: 'kube-pods'kubernetes_sd_configs:- role: podrelabel_configs:- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]action: keepregex: true
8.3 分布式链路追踪
-
自动注入:OpenTelemetry Operator 为 Pod 注入 SDK。
-
sidecar 模式:Jaeger Agent → Collector → Elasticsearch。
-
上下文透传:HTTP
traceparent
Header、gRPC metadata。
示例:
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:name: java-instrumentation
spec:java:image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
8.4 事件与告警
-
Kubernetes Events:
kubectl get events --sort-by='.lastTimestamp'
-
Alertmanager 规则:
-
Pod 连续重启 ≥ 5 次
-
节点磁盘使用率 ≥ 85 %
-
Deployment 滚动升级失败
-
8.5 一站式可观测平台
-
Grafana Cloud / Kube-prometheus-stack:一键部署 Prometheus + Alertmanager + Grafana。
-
Loki:轻量级日志聚合,与 Grafana 无缝集成。
-
Tempo:仅存储 Trace ID → 低成本、高扩展。