"/>
侧边栏壁纸
博主头像
PySuper 博主等级

千里之行,始于足下

  • 累计撰写 218 篇文章
  • 累计创建 15 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Kubernetes | 存储 NFS、PV、PVC、StorageClass | 静态供给 动态供给

PySuper
2021-09-10 / 0 评论 / 0 点赞 / 12 阅读 / 0 字
温馨提示:
本文最后更新于2024-06-12,若内容或图片失效,请留言反馈。 所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

NFS卷

NFS:主流的文件共享服务器

NFS卷:提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中

############# 每个Node上都要安装nfs-utils包 ################

# 安装NFS工具包
yum install nfs-utils -y

# 配置NFS共享路径
vi /etc/exports

/nfs/kubernetes *(rw,no_root_squash)

# 创建好共享文件夹(上面配置的)
mkdir -p /nfs/kubernetes

# 启动,并设置开机自启
systemctl start nfs && systemctl enable nfs

# 挂载文件夹
mkdir -p /nfs/kubernetes && mount -t nfs 172.26.209.141:/nfs/kubernetes /nfs/kubernetes

# 卸载 已挂载的文件夹
umount /nfs/kubernetes

使用Pod挂载NFS数据卷

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: zheng
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          imagePullPolicy: IfNotPresent
          volumeMounts: # 挂载存储卷
            - name: zheng    # 挂载存储卷的名字
              mountPath: /usr/share/nginx/html    # 挂载到容器中的哪个目录下
      volumes: # 使用网络数据卷:NFS
        - name: zheng
          nfs:  # 这里是NFS的地址
            server: 192.168.189.172	# NFS的服务器地址
            path: /nfs/kubernetes/pv-0	# 在这里随便创建一个html文件,访问nginx
            
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-nfs-svc    # service的标签
  name: nginx-nfs-svc    # service的名字
  namespace: zheng
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80    # 这里是容器中的访问入口
  selector:
    app: nginx    # 这里是选择Deployment中暴露的容器名
  type: NodePort    # service的端口暴露方式

PV-PVC

PV-PVC.png

PV

  • 对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
  • 手动创建的共享存储,数据卷定义
# PV 是事先 运维创建好的,后期直接通过PVC调用
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv  # PV的名字
  namespace: zheng
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfs/kubernetes/pv-1  # 创建PV的时候指定存储路径
    server: 192.168.189.172 # NFS服务器地址

访问模式

AccessModes:用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限

  • RWO(ReadWriteOnce):读写权限,但是只能被单个节点挂载
  • ROX(ReadOnlyMany):只读权限,可以被多个节点挂载
  • RWX(ReadWriteMany):读写权限,可以被多个节点挂载

回收策略

删除PV之后,进行的操作

  • Retain(保留): 保留数据,需要管理员手工清理数据
  • Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*
  • Delete(删除):与 PV 相连的后端存储同时删除

当前状态

STATUS:一个 PV 的生命周期中,可能会处于4中不同的阶段

  • Available(可用):表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定):表示 PV 已经被 PVC 绑定
  • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

PVC

  • 卷需求模板
  • 让用户不需要关心具体的Volume实现细节
  • Pod申请PVC作为卷来使用,K8S通过PVC查找绑定的PV,并挂载给Pod
    • 容量大小
    • 读写模式
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc # PVC的名字
  namespace: zheng
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi # 通过容量大小,实现自动查找和绑定

使用

  • 挂载的时候,指明使用PVC卷
  • 指定PVC的名字
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: zheng
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          imagePullPolicy: IfNotPresent
          volumeMounts: # 挂载存储卷
            - name: zheng    # 挂载存储卷的名字
              mountPath: /usr/share/nginx/html    # 挂载到容器中的哪个目录下
      volumes: # 使用PVC卷,PVC会根据存储大小,自动查找PV
        - name: zheng
          persistentVolumeClaim:  # 使用PVC存储
            claimName: nginx-pvc  # 指定的是PVC的名字

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-pvc-svc    # service的标签
  name: nginx-pvc-svc    # service的名字
  namespace: zheng
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80    # 这里是容器中的访问入口
  selector:
    app: nginx    # 这里是选择Deployment中暴露的容器名
  type: NodePort    # service的端口暴露方式

上面这种静态供给的方式,需要不断的创建PV,维护成本太高

K8S开始支持动态供给:StorageClass

SC-PVC

SC 区分名称空间

K8s默认不支持NFS动态供给,需要单独部署社区开发的插件

项目地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

SC-PVC.png

部署插件

基于 NFS 实现 PV 动态供给流程图

RABC

授权访问ApiServer

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # 替换为部署了PV的命名空间
  namespace: default


---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [ "" ]
    resources: [ "persistentvolumes" ]
    verbs: [ "get", "list", "watch", "create", "delete" ]
  - apiGroups: [ "" ]
    resources: [ "persistentvolumeclaims" ]
    verbs: [ "get", "list", "watch", "update" ]
  - apiGroups: [ "storage.k8s.io" ]
    resources: [ "storageclasses" ]
    verbs: [ "get", "list", "watch" ]
  - apiGroups: [ "" ]
    resources: [ "events" ]
    verbs: [ "create", "update", "patch" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # 替换为部署了PV的命名空间
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io


---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # 替换为部署了PV的命名空间
  namespace: default
rules:
  - apiGroups: [ "" ]
    resources: [ "endpoints" ]
    verbs: [ "get", "list", "watch", "create", "update", "patch" ]


---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # 替换为部署了PV的命名空间
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # 替换为部署了PV的命名空间
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

Deployment

# 部署插件,需要修改NFS服务器地址和共享目录
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # 替换为部署了PV的命名空间
  namespace: default
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
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.189.172	# 修改这里的NFS地址
            - name: NFS_PATH
              value: /nfs/kubernetes	# 修改这里的NFS路径
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.189.172	# 修改这里的NFS地址
            path: /nfs/kubernetes	# 修改这里的NFS路径

使用SC的PVC

SC

创建存储类-StorageClass

动态供给,在插件中(Deployment)中指定了nfs的地址之后,SC会自动创建PV

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mysql
  namespace: zheng	# StorageClass区分命名空间
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner	# 这里与部署的插件中保持一致
parameters:
  archiveOnDelete: "false"	# 删除SC之后,PV是否保留

PVC

持久数据卷

支持动态供给-storageClass的PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: zheng
spec:
  storageClassName: "mysql"	# 告诉PVC,这里使用storageClass,使用的是mysql这个存储类
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi	# storageClass会自动创建一个这么大的存储卷

使用

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: zheng
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          imagePullPolicy: IfNotPresent
          volumeMounts: # 挂载存储卷
            - name: zheng    # 挂载存储卷的名字
              mountPath: /usr/share/nginx/html    # 挂载到容器中的哪个目录下
      volumes: # 使用网络数据卷:NFS
        - name: zheng
          persistentVolumeClaim:  # 这里同样使用PVC,不过是动态供给的PVC(自动创建PV)
            claimName: mysql-pvc-sc	# PVC的名字

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-pvc-svc    # service的标签
  name: nginx-pvc-svc    # service的名字
  namespace: zheng
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80    # 这里是容器中的访问入口
  selector:
    app: nginx    # 这里是选择Deployment中暴露的容器名
  type: NodePort    # service的端口暴露方式
0

评论区