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-*
相关推荐
❀͜͡傀儡师1 小时前
使用Docker部署DashDot服务器仪表盘和Drupal
服务器·docker·容器
峰顶听歌的鲸鱼1 小时前
13.docker部署
linux·运维·笔记·docker·容器·云计算
喜欢你,还有大家2 小时前
sealos——高可用集群的部署
云原生·容器·kubernetes
可可苏饼干2 小时前
容器与 Docker
运维·笔记·学习·docker·容器
能不能别报错2 小时前
k8s的cicd流水线环境搭建实验
云原生·容器·kubernetes
todoitbo3 小时前
openEuler 云原生进阶:K3s 轻量级 Kubernetes 集群实战
云原生·容器·kubernetes·openeuler
赴前尘3 小时前
docker 配置ipv6地址
java·docker·容器