节点本地数据卷


emptyDir卷

emptyDir卷: 是一个临时存储卷,与Pod生命周期绑定在一起,当 Pod被从节点上删除时,emptyDir 卷中的数据也会被永久删除

emptyDir卷的数据临时存储在/var/lib/kubelet/pods/{podid}/containers/plugins/volumes/kubernetes.io~empty-dir/目录下.

应用场景: Pod中容器之间数据共享.


emptyDir配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
    - image: k8s.gcr.io/test-webserver
      name: test-container
      volumeMounts:
        - mountPath: /cache
          name: cache-volume
  volumes:
    - name: cache-volume
      # 卷类型为emptyDir
      emptyDir: {}

hostPath

hostPath卷: 挂载Pod所在Node的文件或目录到Pod中的容器.
应用场景: Pod容器需要访问宿主机文件;通常用来收集日志.


hostPath配置示例

将宿主机/tmp目录挂载到容器/test-pd目录

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
    - image: k8s.gcr.io/test-webserver
      name: test-container
      volumeMounts:
        - mountPath: /test-pd
          name: test-volume
  volumes:
    - name: test-volume
      hostPath:
        # 宿主上目录位置
        path: /tmp
        # 此字段为可选
        type: Directory

网络数据存储卷:NFS

nfs

NFS卷: 提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中,宿主机需要安装nfs-utils包. 适合测试环境使用,不建议生产环境使用.

  • NFS优点: 配置简单,性能较高
  • NFS缺点: 自身不支持高可用,单节点部署生产环境风险高.

nfs的动态存储类创建的pvc不支持动态扩容缩容,不支持使用kubectl edit 编辑pvc容量


rhel8搭建nfs服务器

rhel8配置nfs


nfs存储卷配置示例

node上必需要安装nfs的客户端

yum install nfs-utils -y

pod挂载nfs示例yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  containers:
    - name: myapp
      image: <Image>
      volumeMounts:
        - mountPath: Path to mount # 容器中的挂载点(挂砸到容器中的哪个目录)
          name: nfs-data            # 从哪个volumes挂载
      # pod资源限制
      resources:
        limits:
          memory: "128Mi"
          cpu: "500m"
      ports:
        - containerPort: <Port>
  volumes:
    - name: nfs-data
      nfs:
        server: 192.168.31.63 # nfs服务器地址
        path: /ifs/k8s        # nfs服务器存储路径

NFS创建PV,PVC到POD挂载PVC

流程: 使用NFS创建PV----->使用PV绑定PVC----->POD使用PVC

---
# 使用NFS创建一个pv
apiVersion: v1
kind: PersistentVolume
metadata:
  # 创建的PV的名字
  name: mypv
spec:
  capacity:
    storage: { 2:<Size> } # 声明存储大小,例如 5Gi
  volumeMode: Filesystem
  accessModes:
    # ReadWriteOnce:读写权限、并且只能被单个Node挂载
    # ReadWriteMany:读写权限,允许被多个Node挂载
    # ReadOnlyMany:只读权限,允许被多个Node挂载
    - ReadWriteOnce
  # pv回收策略:
  # A. `Retain`模式:`PVC`删除后,PV依然存在
  # C. `Delete`模式:`PVC`删除后,PV同时被删除
  # D. `Recycle`模式:`PVC`删除后,PV可再次使用
  persistentVolumeReclaimPolicy: Recycle
  # 将NFS挂载为PV
  nfs:
    # NFS服务器存储目录
    path: /tmp
    # NFS服务器地址
    server: 172.17.0.2
---
# 使用pvc绑定pv
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # 创建的PVC存储的名字
  name: mypvc
spec:
  resources:
    requests:
      storage: { 2:<Size> } # 传入需要的存储容量,不能大于PV的容量
  volumeMode: Filesystem
  # ReadWriteOnce:读写权限、并且只能被单个Node挂载
  # ReadWriteMany:读写权限,允许被多个Node挂载
  # ReadOnlyMany:只读权限,允许被多个Node挂载
  accessModes:
    - ReadWriteOnce
---
# pod绑定pvc
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  containers:
    - name: myapp
      image: <Image>
      volumeMounts:
        - mountPath: Path to mount # 容器中的挂载点(挂砸到容器中的哪个目录)
          name: pod-data # 从哪个volumes挂载
      # pod资源限制
      resources:
        limits:
          memory: "128Mi"
          cpu: "500m"
      ports:
        - containerPort: <Port> # 容器暴露的端口
  # 使用PVC声明一个volumes(存储卷)
  volumes:
    - name: pod-data # 存储卷的名字
      persistentVolumeClaim:
        claimName: mypvc # 要使用的pvc的名字

PV和PVC

PV和PVC


NFS版PV动态供给StorageClass(存储类)

NFS版StorageClass插件地址
部署NFS Provisioner参考

免积分下载部署yaml


创建所需的rbac

nfs-rbac.yaml示例

---
# 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: storage
---
# 创建服务账号
kind: ServiceAccount
apiVersion: v1
metadata:
  # 服务账号名
  name: nfs-client-provisioner
  # 替换为deployment的命名空间
  namespace: storage
---
# 创建集群角色
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # 集群角色名
  name: nfs-client-provisioner-runner
# 添加集群角色权限
rules:
  - apiGroups: [""]
    # 向该角色增加对PV执行查看,创建,删除 权限
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    # 向该角色增加对PVC执行查看,更新 权限
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    # 向该角色增加对动态存储类执行查看 权限
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    # 向该角色增加对events(集群事件)进行 创建 更新 补丁 权限
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
# 创建集群角色绑定
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # 角色绑定的名称
  name: run-nfs-client-provisioner
subjects:
  # 绑定服务账号
  - kind: ServiceAccount
    # 要绑定的服务账号名--就是第一个yaml创建的sa
    name: nfs-client-provisioner
    # 绑定到哪个命名空间
    namespace: storage
roleRef:
  kind: ClusterRole
  # 要绑定的集群角色名--就是第2个yaml创建的集群角色
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
# 创建role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # 创建的角色名
  name: leader-locking-nfs-client-provisioner
rules:
  - apiGroups: [""]
    # 向该角色增加对endpoint 查看 创建 更新 补丁 的权限
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# 创建role绑定
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # 该角色绑定的名字
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    # 要绑定的服务账号名--就是第一个yaml创建的服务账号
    name: nfs-client-provisioner
    # 替换为deployment要部署到的命名空间
    # 绑定到storage命名空间
    namespace: storage
roleRef:
  kind: Role
  # 要绑定的角色名称,就是上一个yaml创建的role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

# 清理rbac授权
kubectl delete -f nfs-rbac.yaml -n kube-system

# 执行rbac授权
kubectl apply -f nfs-rbac.yaml

创建deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  # Deployment名
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # 部署到哪个命名空间
  namespace: storage
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      # 使用哪个服务账号
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          # image: lizhenliang/nfs-subdir-external-provisioner:v4.0.1
          image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              # NFS服务器地址
              value: 192.168.31.63
            - name: NFS_PATH
              # NFS服务器share目录
              value: /ifs/kubernetes
      volumes:
        - name: nfs-client-root
          nfs:
            # NFS服务器地址
            server: 192.168.31.63
            # NFS服务器share目录
            path: /ifs/kubernetes

创建class

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # 或选择其他名称,必须与部署的环境 PROVISIONER_NAME 匹配
parameters:
  # 启用PV归档模式 true|false
  archiveOnDelete: "false"

使用存储类创建PVC

---
# 创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # pvc名称
  name: pv-volume
spec:
  # 存储类名称
  storageClassName: nfs-client
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi # pvc容量
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐