K8S进阶核心综合学习笔记(持久化存储+特殊容器+调度管理)

K8S学习笔记(持久化存储+特殊容器+调度管理)

一、K8S持久化存储

1. 持久化存储核心意义

K8s中所有业务应用均运行在Pod容器中,Pod拥有独立生命周期,重启、删除、重建后内部数据会彻底丢失。对于MySQL、Redis等有数据留存需求的业务,必须通过存储卷实现数据持久化,保证业务数据不随Pod生命周期销毁。

2. K8S存储通用基础

2.1 查看集群支持的所有存储类型

执行以下命令可查看K8s原生支持的全部存储卷:

shell 复制代码
kubectl explain pods.spec.volumes

生产常用存储类型:emptyDir、hostPath、nfs、persistentVolumeClaim、glusterfs、cephfs、configMap、secret

2.2 存储卷通用使用步骤

  1. 在Pod资源清单中定义 volumes 字段,关联对应存储介质;

  2. 在容器中通过 volumeMounts 挂载存储卷,保证两端name名称一致。

3. 四大常用存储卷详解

3.1 emptyDir 临时存储卷

核心特点
  • Pod调度到节点时自动创建空临时目录,无需手动指定宿主机路径;

  • 数据仅当前Pod生命周期有效,Pod删除/重建,数据永久丢失

  • 适用于临时缓存、Pod内多容器共享临时数据场景,不用于持久化业务数据。

实操案例

资源清单 emptydir.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: pod-empty
spec:
 containers:
 - name: container-empty
   image: nginx
   imagePullPolicy: IfNotPresent
   volumeMounts:
   - mountPath: /cache
     name: cache-volume
 volumes:
 - emptyDir: {}
   name: cache-volume

部署与验证命令

shell 复制代码
# 创建Pod
kubectl apply -f emptydir.yaml
# 查看Pod调度节点
kubectl get pod pod-empty -o wide
# 获取Pod UID,定位节点存储目录
kubectl get pod pod-empty -o yaml | grep uid
# 节点目录固定路径:/var/lib/kubelet/pods/[Pod-UID]/volumes/kubernetes.io~empty-dir/cache-volume
# 删除Pod验证数据丢失
kubectl delete pod pod-empty

3.2 hostPath 节点级持久化存储

核心特点
  • 直接挂载宿主机指定目录/文件,Pod删除后数据保留在节点本地;

  • 存在单点故障:仅Pod调度到原节点时,数据可复用;调度到其他节点则数据丢失;

  • 常用类型 DirectoryOrCreate:宿主机无目录则自动创建。

实操案例

资源清单hostpath.yaml(指定节点调度,规避随机调度问题)

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: test-hostpath
spec:
  nodeName: k8s-node2 # 强制调度到指定节点
  containers:
  - image: nginx
    name: test-nginx
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
     path: /data
     type: DirectoryOrCreate

验证逻辑:节点写入index.html内容,删除重建Pod后,数据依然保留。

3.3 NFS 网络共享存储

核心特点

解决hostPath单点故障问题,基于网络共享目录,集群所有节点均可挂载,实现跨节点数据共享;缺点是NFS服务端存在单点故障,生产高可用场景需搭配分布式存储(GlusterFS/CephFS)。

实操部署流程
  1. 服务端(master节点)安装配置NFS
shell 复制代码
# 安装工具
yum install -y nfs-utils
# 创建共享目录
mkdir /data -pv
# 配置共享规则
vim /etc/exports
/data 192.168.166.0/24(rw,sync,no_root_squash,no_subtree_check)
# 生效配置并启动服务
exportfs -avr
systemctl enable --now nfs
  1. 所有Worker节点安装客户端
shell 复制代码
yum install nfs-utils -y
systemctl enable --now nfs
  1. Pod挂载NFS资源清单 nfs.yaml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: test-nfs
spec:
 containers:
 - name: test-nfs
   image: nginx
   imagePullPolicy: IfNotPresent
   ports:
   - containerPort: 80
     protocol: TCP
   volumeMounts:
   - name: nfs-volumes
     mountPath: /usr/share/nginx/html
 volumes:
 - name: nfs-volumes
   nfs:
    path: /data
    server: 192.168.166.7 # NFS服务端IP

3.4 PV/PVC 解耦式持久化存储

3.4.1 核心概念
  • PV(PersistentVolume):集群级存储资源,由管理员定义,代表真实存储介质,生命周期独立于Pod;

  • PVC(PersistentVolumeClaim):用户存储声明,用于申请PV资源,指定存储大小、访问模式;

  • 核心价值:存储与业务解耦,管理员维护底层PV,开发通过PVC直接使用存储。

3.4.2 PV访问模式
  • RWO(ReadWriteOnce):单节点读写;

  • RWX(ReadWriteMany):多节点读写;

  • ROX(ReadOnlyMany):多节点只读。

3.4.3 PV回收策略
  • Retain(默认):删除PVC后,PV保留、数据留存,状态变为Released,需手动清理复用;

  • Delete:删除PVC后,PV和底层存储数据自动删除。

3.4.4 完整实操流程
  1. 扩展NFS共享目录
shell 复制代码
mkdir /data/v{1..10} -p
vim /etc/exports
/data/v1 192.168.166.0/24(rw,no_root_squash)
/data/v2 192.168.166.0/24(rw,no_root_squash)
exportfs -arv
  1. 创建多个PV(pv.yaml)
yaml 复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
 name: v1
spec:
 capacity:
  storage: 1Gi
 accessModes: ["ReadWriteOnce"]
 nfs:
  path: /data/v1
  server: 192.168.166.7
---
apiVersion: v1
kind: PersistentVolume
metadata:
 name: v2
spec:
 capacity:
  storage: 2Gi
 accessModes: ["ReadWriteMany"]
 nfs:
  path: /data/v2
  server: 192.168.166.7
  1. 创建PVC绑定PV(pvc.yaml)
yaml 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: my-pvc
spec:
 accessModes: ["ReadWriteMany"]
 resources:
   requests:
     storage: 2Gi
  1. Pod挂载PVC使用存储
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: pod-pvc
spec:
 containers:
 - name: nginx
   image: nginx
   imagePullPolicy: IfNotPresent
   volumeMounts:
   - name: nginx-html
     mountPath: /usr/share/nginx/html
 volumes:
 - name: nginx-html
   persistentVolumeClaim:
     claimName: my-pvc
  1. 查看绑定状态
shell 复制代码
kubectl get pv
kubectl get pvc

4. 存储选型总结

  • 临时数据、缓存场景:emptyDir

  • 单节点固定业务、临时持久化:hostPath

  • 多节点共享、普通持久化业务:NFS

  • 生产规范、大规模集群:PV+PVC

二、K8S特殊容器

1. 初始化容器(Init Container)

1.1 核心概述

Init容器是Pod专属的前置初始化容器,支持配置多个,严格串行执行,所有Init容器执行成功退出后,主容器才会启动。Pod内所有容器共享网络命名空间和数据卷,Init容器初始化的配置、文件可被主容器复用。

补充:每个Pod默认包含 pause infra容器,负责实现Pod内部网络共享,该镜像拉取失败会直接导致Pod启动异常。

1.2 Init容器与普通容器区别

  • Init容器必须执行成功,失败会持续重启Pod(restartPolicy=Never除外);

  • 多Init容器串行执行,普通容器并行启动;

  • Init容器独立于主容器生命周期,先于PreStart钩子执行。

1.3 核心优势

  • 安全隔离:调试工具、运维脚本放在Init容器,无需混入业务镜像;

  • 权限隔离:可单独配置Secret权限,业务容器无高权限;

  • 依赖阻塞:精准控制主容器启动时机,解决服务依赖问题。

1.4 典型应用场景

  • 服务依赖等待:Web服务等待数据库、注册中心就绪;

  • 初始化配置:自动生成集群配置、节点注册信息;

  • 环境预处理:文件初始化、权限配置、日志目录创建。

1.5 实操案例(服务依赖等待)

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: init-demo
  labels:
    demo: init-demo
spec:
  containers:
  - name: init-demo
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-demo1
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice;sleep 2; done;']
  - name: init-demo2
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2;done;']
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - port: 5566
    targetPort: 6655
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 8899
    targetPort: 9988
    protocol: TCP

验证命令

shell 复制代码
kubectl get pods
kubectl get service
kubectl logs init-demo -c init-demo1

1.6 关键约束

  • Pod未完成初始化前,状态为Pending,不会进入Ready状态;

  • Pod重启后,所有Init容器会重新执行;

  • 仅支持修改Init容器的image字段,其余字段修改不生效;

  • Init容器不支持就绪探针,Pod内所有容器名称必须唯一。

2. 临时容器(Ephemeral Containers)

2.1 核心概述

临时容器是K8s用于线上故障临时调试的特殊容器,动态注入运行中的Pod,无资源保证、不会自动重启,仅用于排查问题,不参与业务运行。

2.2 核心限制

  • 不支持端口、健康探针、资源配额配置;

  • 无法通过kubectl edit添加,仅可通过专属API创建;

  • 创建后不可修改、不可删除,调试结束自动失效。

2.3 适用场景

针对Distroless极简镜像场景:该镜像无Shell、无调试工具,无法通过kubectl exec进入容器排查问题,可通过临时容器注入busybox等调试工具,实现交互式排障。

2.4 实操排障案例

  1. 部署基础Nginx Pod
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  namespace: default
  labels:
    app:  nginx
spec:
  containers:
  - name:  nginx
    ports:
    - containerPort: 80
    image: nginx
    imagePullPolicy: IfNotPresent
  1. 注入临时容器调试
shell 复制代码
# 动态注入busybox调试容器,关联目标nginx容器
kubectl debug -it nginx-test --image=busybox:1.28 --target=nginx
# 查看容器进程
ps -ef | grep nginx
  1. 查看临时容器信息
shell 复制代码
kubectl describe pods nginx-test

三、K8S调度管理

1. 调度概述

K8s默认调度器会将Pod随机调度到健康节点,生产环境为满足高可用、资源隔离、专属部署需求,可通过节点选择器、Pod亲和性/反亲和性、污点与容忍手动控制调度策略。

2. 节点选择器

2.1 nodeName 强制指定节点

直接指定Pod运行的节点名称,跳过调度算法,强制绑定节点,适用于固定节点部署场景。

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod1
spec:
  nodeName: k8s-node1 # 强制运行在node1节点
  containers:
  - name: nginx
    image: nginx

2.2 nodeSelector 标签匹配调度

通过节点标签筛选目标节点,灵活性高于nodeName,适合批量节点调度。

操作命令

shell 复制代码
# 给节点打标签
kubectl label nodes k8s-node1 node=worker01
# 查看节点标签
kubectl describe nodes k8s-node1

资源清单

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod-1
spec:
  nodeSelector:
    node: worker01 # 匹配对应标签节点
  containers:
  - name: tomcat
    image: tomcat:8.5-jre8-alpine

3. Pod亲和性与反亲和性

3.1 核心分类

  • Pod亲和性(podAffinity):让Pod与指定Pod部署在同一拓扑域,提升通信效率;

  • Pod反亲和性(podAntiAffinity):让Pod与指定Pod分散部署,实现高可用、避免单点故障。

3.2 调度规则级别

  • requiredDuringSchedulingIgnoredDuringExecution:硬规则,必须满足,不满足则Pod pending;

  • preferredDuringSchedulingIgnoredDuringExecution:软规则,尽量满足,不满足仍可调度。

3.3 常用拓扑域(topologyKey)

topologyKey 拓扑范围 用途
kubernetes.io/hostname 节点级别 节点级Pod分散/集中部署(最常用)
topology.kubernetes.io/zone 可用区级 跨可用区容灾
topology.kubernetes.io/region 地域级 跨地域容灾部署

3.4 实操案例

  1. Pod硬亲和性(同节点部署)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app2: myapp2
spec:
  containers:
  - name: nginx
    image: nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command: ["sh","-c","sleep 3600"]
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app2, operator: 'In', values: ["myapp2"]}
        topologyKey: kubernetes.io/hostname
  1. Pod软反亲和性(尽量不同节点)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod1-first
  labels:
    app1: myapp1
spec:
  containers:
  - name: nginx
    image: nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2-second
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command: ["sh","-c","sleep 3600"]
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchExpressions:
                - key: app1
                  operator: 'In'
                  values: ["myapp1"]
            topologyKey: kubernetes.io/hostname

4. 污点与容忍(节点资源隔离)

4.1 核心原理

  • 污点(Taints):节点属性,用于拒绝Pod调度、驱逐存量Pod,实现节点隔离;

  • 容忍(Tolerations):Pod属性,允许Pod忽略节点污点,调度到专属节点;

  • 搭配使用:污点隔离普通Pod,容忍放行专属Pod。

4.2 污点三大策略

  • NoSchedule:无容忍Pod禁止调度到该节点(仅限制新Pod);

  • PreferNoSchedule:软限制,尽量不调度,非强制;

  • NoExecute:强制限制,禁止新Pod调度,同时驱逐节点上无容忍的存量Pod。

4.3 污点常用命令

shell 复制代码
# 查看节点污点
kubectl describe node k8s-master
# 设置污点
kubectl taint node k8s-node1 web=true:NoSchedule
kubectl taint node k8s-node2 app=true:NoExecute
# 删除污点
kubectl taint node k8s-node1 web-

4.4 容忍配置与案例

核心字段:key(污点键)、operator(Equal/Exists)、value(污点值)、effect(策略)、tolerationSeconds(驱逐延迟时间)

容忍NoSchedule污点案例

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web-tolerations
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations:
  - key: web
    operator: Equal
    value: "true"
    effect: NoSchedule

容忍NoExecute污点(60秒后驱逐)

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: app-tolerations
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations:
  - key: app
    operator: Exists
    effect: NoExecute
    tolerationSeconds: 60

4.5 调度优先级规则

Pod优先调度到无污点节点,即使Pod容忍节点污点;如需实现节点专属部署,需同时搭配「污点+容忍+节点亲和性」。

四、全文核心总结

  1. 持久化存储:从临时存储到网络存储,再到PV/PVC解耦存储,适配从测试到生产的全场景,生产优先使用PV+PVC架构;

  2. 特殊容器:Init容器负责前置初始化、解决服务依赖;临时容器负责线上故障调试,是运维排障核心工具;

  3. 调度管理:简单调度用节点选择器,高可用用Pod反亲和,资源隔离用污点容忍,三者组合可满足所有生产调度需求。

(注:文档部分内容可能由 AI 生成)

相关推荐
li星野1 小时前
位运算 & 数学 & 高频进阶九题通关(Python + C++)
c++·python·学习·算法
Skylwn2 小时前
保姆级教程之将 GitHub Models 接入 NewAPI
笔记·github
Zhu7582 小时前
[软件部署]在k8s环境部署alist
云原生·容器·kubernetes
脆皮炸鸡7552 小时前
库制作与原理~动态链接
linux·开发语言·经验分享·笔记·学习方法
nnsix2 小时前
设计模式 - 工厂模式 笔记
笔记·设计模式
y = xⁿ3 小时前
Java并发八股学习日记
java·开发语言·学习
2401_840192273 小时前
k8s的crd、operator、cr分别是什么?
运维·分布式·kubernetes·prometheus
@codercjw4 小时前
工程图制图经验
学习
星幻元宇VR4 小时前
VR文旅大空间|沉浸式体验重塑文旅新场景
科技·学习·安全·vr·虚拟现实