k8s 本地动态存储 Local Path Provisioner 部署

完整部署清单

yaml 复制代码
# 1. 命名空间:独立隔离 Local Path Provisioner 相关资源
# 功能:避免与其他业务资源冲突,便于权限控制和资源管理
apiVersion: v1
kind: Namespace
metadata:
  name: local-path-storage
---
# 2. 服务账号:为 Local Path Provisioner 提供专属运行身份
# 功能:关联 RBAC 权限,实现权限最小化,避免使用默认服务账号带来的安全风险
apiVersion: v1
kind: ServiceAccount
metadata:
  name: local-path-provisioner-service-account
  namespace: local-path-storage  # 与组件命名空间强绑定
---
# 3. 集群角色:定义 Provisioner 所需的集群级权限集合
# 遵循最小权限原则:仅授予组件正常运行必需的权限,避免过度授权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: local-path-provisioner-role  # 角色名称,用于后续权限绑定
rules:
# 权限组1:读取节点和PVC基础信息
# 用途:判断节点存储可用性、感知PVC状态
- apiGroups: [""]  # 核心API组(无组名)
  resources: ["nodes", "persistentvolumeclaims"]  # 操作的资源类型
  verbs: ["get", "list", "watch"]  # 只读操作,无修改权限
# 权限组2:管理PV、Pod、Endpoint资源
# 用途:动态创建/删除PV、感知Pod调度状态、维护组件服务发现
- apiGroups: [""]
  resources: ["endpoints", "persistentvolumes", "pods"]
  verbs: ["*"]  # 需完整操作权限(创建/删除/更新等)
# 权限组3:上报事件
# 用途:向K8s集群上报PV创建/删除、错误等状态事件,便于排查问题
- apiGroups: [""]
  resources: ["events"]
  verbs: ["create", "patch"]  # 仅允许创建和更新事件
# 权限组4:读取存储类配置
# 用途:关联本地存储类,获取存储供给规则
- apiGroups: ["storage.k8s.io"]  # 存储相关API组
  resources: ["storageclasses"]
  verbs: ["get", "list", "watch"]  # 只读操作,无需修改存储类
---
# 4. 集群角色绑定:将集群角色权限授予服务账号
# 功能:建立权限关联,使Provisioner通过服务账号获得上述角色权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: local-path-provisioner-bind  # 绑定名称,便于识别
roleRef:
  apiGroup: rbac.authorization.k8s.io  # RBAC API组
  kind: ClusterRole  # 绑定的资源类型为集群角色
  name: local-path-provisioner-role  # 关联上述定义的集群角色
subjects:
- kind: ServiceAccount  # 被授权对象类型为服务账号
  name: local-path-provisioner-service-account  # 被授权的服务账号名称
  namespace: local-path-storage  # 明确命名空间,避免跨命名空间权限泄漏
---
# 5. Deployment:定义 Local Path Provisioner 核心组件的运行配置
# 功能:管理Provisioner容器的生命周期,确保组件稳定运行
apiVersion: apps/v1
kind: Deployment
metadata:
  name: local-path-provisioner  # 部署名称,与组件名称一致
  namespace: local-path-storage  # 部署到独立命名空间
spec:
  replicas: 1  # 单副本部署:本地存储Provisioner无需多副本,单节点即可满足需求
  selector:
    matchLabels:
      app: local-path-provisioner  # 标签选择器,匹配目标Pod
  template:
    metadata:
      labels:
        app: local-path-provisioner  # Pod标签,与选择器对应,用于服务发现和调度
    spec:
      serviceAccountName: local-path-provisioner-service-account  # 关联专属服务账号
      containers:
      - name: local-path-provisioner  # 容器名称,与组件名称一致
        image: rancher/local-path-provisioner:v0.0.14  # 组件镜像:固定版本,避免兼容性问题
        imagePullPolicy: IfNotPresent  # 镜像拉取策略:本地有镜像时优先使用,减少网络依赖
        command:  # 容器启动命令
        - local-path-provisioner  # 启动二进制文件
        - --debug  # 开启调试日志:便于问题排查(生产环境可按需关闭)
        - start  # 启动服务指令
        - --config  # 指定配置文件参数
        - /etc/config/config.json  # 配置文件路径(挂载自ConfigMap)
        volumeMounts:  # 挂载配置文件卷
        - name: config-volume  # 卷名称,与下方volumes定义对应
          mountPath: /etc/config/  # 容器内挂载目录,对应启动命令中的配置路径
        env:  # 环境变量配置
        - name: POD_NAMESPACE  # 变量名:当前Pod所在命名空间
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace  # 动态获取Pod命名空间,避免硬编码
      volumes:  # 定义卷资源:挂载ConfigMap配置
        - name: config-volume  # 卷名称,与volumeMounts对应
          configMap:
            name: local-path-config  # 关联下方定义的ConfigMap,加载配置数据
---
# 6. 存储类:定义本地存储的动态供给规则
# 功能:为PVC提供存储供给模板,指定Provisioner、绑定策略等核心规则
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-path  # 存储类名称:创建PVC时需通过storageClassName引用
provisioner: rancher.io/local-path  # 存储供给者:与Provisioner镜像内置的Provisioner名称一致
volumeBindingMode: WaitForFirstConsumer  # 卷绑定模式:等待第一个Pod调度后再创建PV,避免PV与Pod跨节点
reclaimPolicy: Delete  # 回收策略:PVC删除后自动清理PV及本地数据,释放资源
---
# 7. ConfigMap:存储Provisioner核心配置数据
# 功能:分离配置与应用,支持动态调整存储路径、初始化/清理脚本(需重启Pod生效)
kind: ConfigMap
apiVersion: v1
metadata:
  name: local-path-config  # ConfigMap名称,与Deployment卷配置关联
  namespace: local-path-storage  # 与组件命名空间一致
data:
  # 核心配置:节点-存储路径映射表
  config.json: |-
        {
                "nodePathMap":[
                {
                        "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                        "paths":["/data"]
                }
                ]
        }
  # 初始化脚本:PV创建时执行
  # 功能:创建存储目录并设置权限,确保Pod可正常读写
  setup: |-
        #!/bin/sh
        path=$1
        mkdir -m 0777 -p ${path}
  # 清理脚本:PV删除时执行
  # 功能:删除存储目录及数据,释放节点磁盘空间
  teardown: |-
        #!/bin/sh
        path=$1
        rm -rf ${path}

部署前准备(最佳实践)

1. 节点环境检查

bash 复制代码
# 1. 所有节点创建存储目录并设置权限(与 ConfigMap 中 paths 一致)
sudo mkdir -p /data && sudo chmod 777 /data

# 2. 检查目录所在分区剩余空间(建议至少保留 10Gi 空闲空间)
df -h /data

# 3. 确保节点已安装必要依赖(如 util-linux 提供 pgrep 命令,用于健康检查)
sudo apt install -y util-linux  # Debian/Ubuntu 系统
# sudo yum install -y util-linux  # CentOS/RHEL 系统

2. 镜像预处理(离线环境必备)

bash 复制代码
# 提前拉取镜像并推送到私有仓库(或直接在所有节点加载)
docker pull rancher/local-path-provisioner:v0.0.14

# 离线环境保存镜像
docker save -o local-path-provisioner-v0.0.14.tar rancher/local-path-provisioner:v0.0.14
# 在其他节点加载镜像
docker load -i local-path-provisioner-v0.0.14.tar

部署与验证(标准化流程)

1. 部署执行

bash 复制代码
# 保存上述清单为 local-path-provisioner.yaml,执行部署
kubectl apply -f local-path-provisioner.yaml

# 验证命名空间创建
kubectl get ns local-path-storage -o wide

# 验证 Pod 运行状态(确保 STATUS 为 Running)
kubectl get pod -n local-path-storage -o wide --watch

# 验证存储类创建
kubectl get sc local-path -o yaml

2. 功能验证(标准化测试用例)

bash 复制代码
# 1. 创建测试 PVC(动态申请 2Gi 存储)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-local-path-pvc
  namespace: default
  labels:
    app.kubernetes.io/name: test-local-path
spec:
  accessModes:
    - ReadWriteOnce  # 本地存储仅支持单节点读写
  storageClassName: local-path
  resources:
    requests:
      storage: 2Gi
EOF

# 2. 创建测试 Pod 挂载 PVC
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: test-local-path-pod
  namespace: default
  labels:
    app.kubernetes.io/name: test-local-path
spec:
  containers:
  - name: test-container
    image: busybox:1.35  # 固定镜像版本,避免兼容性问题
    command: ["sleep", "86400"]  # 持续运行 24 小时
    volumeMounts:
    - name: local-storage
      mountPath: /data  # 挂载到 Pod 内部 /data 目录
    resources:
      requests:
        cpu: 50m
        memory: 64Mi
      limits:
        cpu: 100m
        memory: 128Mi
  volumes:
  - name: local-storage
    persistentVolumeClaim:
      claimName: test-local-path-pvc
EOF

# 3. 验证资源状态
# PVC 状态应为 Bound(绑定成功)
kubectl get pvc test-local-path-pvc -n default -o wide

# PV 状态应为 Bound(自动创建并绑定)
kubectl get pv -o wide

# Pod 状态应为 Running(挂载成功)
kubectl get pod test-local-path-pod -n default -o wide

# 4. 读写验证(确认存储可用)
kubectl exec -it test-local-path-pod -n default -- sh -c "echo 'k8s local-path test success' > /data/test.txt && cat /data/test.txt"
# 预期输出:k8s local-path test success

# 5. 节点本地验证(确认数据存储在 /data 目录)
# 先获取 Pod 所在节点
POD_NODE=$(kubectl get pod test-local-path-pod -n default -o jsonpath='{.spec.nodeName}')
# 登录节点查看数据目录(或通过 kubectl debug 查看)
kubectl debug node/${POD_NODE} -it --image=busybox:1.35 -- sh -c "ls -l /data/pvc-*/default/test-local-path-pvc/"

清理资源

bash 复制代码
# 删除测试 Pod 和 PVC
kubectl delete pod test-local-path-pod -n default
kubectl delete pvc test-local-path-pvc -n default

# 彻底卸载 Local Path Provisioner
kubectl delete -f local-path-provisioner.yaml

# 清理节点本地残留目录(可选)
sudo rm -rf /data/pvc-*
相关推荐
lichenyang4534 天前
Docker 学习笔记(四):Dockerfile,把项目打成自己的镜像
docker·容器
lichenyang4534 天前
Docker 学习笔记(三):Docker 网络、bridge、子网和容器互通
docker·容器
lichenyang4534 天前
Docker 学习笔记(二):docker run 的参数到底在控制什么?
docker·容器
运维开发故事7 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson9 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生9 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭9 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美10 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵11 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程