k8s 存储管理

k8s 存储管理

Volumes

HostPath

将节点上的文件或目录挂载到 Pod 上,此时该目录会变成持久化存储目录,即使 Pod 被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失. 类似于docker volume 挂载方式

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: nginx
    name: nginx-volume
    volumeMounts:
    - mountPath: /test-pd # 挂载到容器的哪个目录
      name: test-volume # 挂载哪个 volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data # 节点中的目录
      type: Directory # 检查类型,在挂载前对挂载目录做什么检查操作,有多种选项,默认为空字符串,不做任何检查


类型:
空字符串:默认类型,不做任何检查
DirectoryOrCreate:如果给定的 path 不存在,就创建一个 755 的空目录
Directory:这个目录必须存在
FileOrCreate:如果给定的文件不存在,则创建一个空文件,权限为 644
File:这个文件必须存在
Socket:UNIX 套接字,必须存在
CharDevice:字符设备,必须存在
BlockDevice:块设备,必须存在

EmptyDir

EmptyDir 主要用于一个 Pod 中不同的 Container 共享数据使用的,由于只是在 Pod 内部使用,因此与其他 volume 比较大的区别是,当 Pod 如果被删除了,那么 emptyDir 也会被删除。

存储介质可以是任意类型,如 SSD、磁盘或网络存储。可以将 emptyDir.medium 设置为 Memory 让 k8s 使用 tmpfs(内存支持文件系统),速度比较快,但是重启 tmpfs 节点时,数据会被清除,且设置的大小会计入到 Container 的内存限制中。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: nginx1
    name: nginx-emptydir
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
      
  - image: nginx2
    name: nginx-emptydir
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
      
  volumes:
  - name: cache-volume
    emptyDir: {}

NFS

nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。

更详细的可以参考 Linux之NFS

nfs 安装

# 安装 nfs
yum install nfs-utils -y

# 启动 nfs
systemctl start nfs-server

# 查看 nfs 版本
cat /proc/fs/nfsd/versions

# 创建共享目录
mkdir -p /data/nfs
cd /data/nfs
mkdir rw
mkdir ro

# 设置共享目录 export
vim /etc/exports
/data/nfs/rw 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
/data/nfs/ro 192.168.1.0/24(ro,sync,no_subtree_check,no_root_squash)
# 目录         网段           权限 

# 重新加载
exportfs -f
systemctl reload nfs-server

# 到其他测试节点安装 nfs-utils 并加载测试
mkdir -p /data/nfs/rw
mount -t nfs 192.168.1.2:/data/nfs/rw /mnt/nfs/rw

使用

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: nginx
    name: test-container
    volumeMounts:
    - mountPath: /usr/share/nginx  # 容器内覆盖挂载目录
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: 192.168.1.1 # 网络存储服务地址
      path: /data/nfs/rw/nginx # 网络存储路径
      readOnly: false  # 是否只读

PV 和 PVC

持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

在这里插入图片描述

使用了PV和PVC之后,工作可以得到进一步的细分:

  • 存储:存储工程师维护
  • PV: kubernetes管理员维护
  • PVC:kubernetes用户维护

在这里插入图片描述

生命周期

PVC和PV是一一对应的,PV和PVC之间的相互作用遵循以下生命周期:

  • **资源构建:**管理员手动创建底层存储和PV

    • 静态构建:集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 并且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。

    • 动态构建: 如果集群中已经有的 PV 无法满足 PVC 的需求,那么集群会根据 PVC 自动构建一个 PV,该操作是通过 StorageClass 实现的。想要实现这个操作,前提是 PVC 必须设置 StorageClass,否则会无法动态构建该 PV,可以通过启用 DefaultStorageClass 来实现 PV 的构建。

  • **资源绑定:**用户创建PVC,kubernetes负责根据PVC的声明去寻找PV,并绑定

    • 在用户定义好PVC之后,系统将根据PVC对存储资源的请求在已存在的PV中选择一个满足条件的
    • 一旦找到,就将该PV与用户定义的PVC进行绑定,用户的应用就可以使用这个PVC了
      如果找不到,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合其要求的PV
      PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再与其他PVC进行绑定了
  • **资源使用:**用户可在pod中像volume一样使用pvc

    Pod使用Volume的定义,将PVC挂载到容器内的某个路径进行使用。

  • **资源释放:**用户删除pvc来释放pv

    当存储资源使用完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被留在存储设备上,只有在清除之后该PV才能再次使用。

  • **资源回收:**kubernetes根据pv设置的回收策略进行资源的回收

    对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收,才能供新的PVC绑定和使用

    • 保留(Retain): 用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以通过下面的步骤来手动回收该卷:

      1. 删除 PersistentVolume 对象。与之相关的、位于外部基础设施中的存储资产 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍然存在。
      2. 根据情况,手动清除所关联的存储资产上的数据。
      3. 手动删除所关联的存储资产。

      如果你希望重用该存储资产,可以基于存储资产的定义创建新的 PersistentVolume 卷对象。

    • 删除(Delete): 删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部基础设施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 动态制备的卷会继承其 StorageClass 中设置的回收策略, 该策略默认为 Delete。管理员需要根据用户的期望来配置 StorageClass; 否则 PV 卷被创建之后必须要被编辑或者修补。

    • 回收(Recycle): 回收策略 Recycle) 已被废弃。取而代之的建议方案是使用动态制备。如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。
      在这里插入图片描述

PV

PV是存储资源的抽象,下面是资源清单文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 5Gi # pv 的容量
  volumeMode: Filesystem # 存储类型为文件系统
  accessModes: # 访问模式:ReadWriteOnce、ReadWriteMany、ReadOnlyMany
    - ReadWriteOnce # 可被单节点独写
  persistentVolumeReclaimPolicy: Recycle # 回收策略
  storageClassName: slow # 创建 PV 的存储类名,需要与 pvc 的相同
  mountOptions: # 加载配置
    - hard
    - nfsvers=4.1
  nfs: # 连接到 nfs
    path: /data/nfs/rw/test-pv # 存储路径
    server: 192.168.1.1 # nfs 服务地址

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

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

在这里插入图片描述

PVC

PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。下面是资源清单文件:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteOnce # 权限需要与对应的 pv 相同
  volumeMode: Filesystem
  resources:
    requests:
      storage: 4Gi # 资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv
  storageClassName: pv1 # 名字需要与对应 pv 的storageClass 相同
#  selector: # 使用选择器选择对应的 pv
#    matchLabels:
#      release: "stable"
#    matchExpressions:
#      - {key: environment, operator: In, values: [dev]}

PVC 的关键配置参数说明:

  • 访问模式(accessModes): 用于描述用户应用对存储资源的访问权限

  • 选择条件(selector): 通过Label Selector的设置,可使PVC对于系统中己存在的PV进行筛选

  • 存储类别(storageClassName): PVC在定义时可以设定需要的后端存储的类别,只有设置了该class的pv才能被系统选出

  • 资源请求(Resources ): 描述对存储资源的请求

pod 绑定 pvc

在 pod 的挂载容器配置中,增加 pvc 挂载

containers:
  ......
  volumeMounts:
    - mountPath: /tmp/pvc
      name: nfs-pvc-test
volumes:
  - name: nfs-pvc-test
    persistentVolumeClaim:
      claimName: nfs-pvc # pvc 的名称

StorageClass

k8s 中提供了一套自动创建 PV 的机制,就是基于 StorageClass 进行的,通过 StorageClass 可以实现仅仅配置 PVC,然后交由 StorageClass 根据 PVC 的需求动态创建 PV。

制备器

每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。

卷插件内置制备器配置例子
AWSElasticBlockStoreAWS EBS
AzureFileAzure File
AzureDiskAzure Disk
CephFS--
CinderOpenStack Cinder
FC--
FlexVolume--
Flocker-
GCEPersistentDiskGCE PD
GlusterfsGlusterfs
iSCSI--
QuobyteQuobyte
NFS--
RBDCeph RBD
VsphereVolumevSphere
PortworxVolumePortworx Volume
ScaleIOScaleIO
StorageOSStorageOS
Local-Local

使用流程

  1. 创建rbac

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
      namespace: kube-system
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-client-provisioner-runner
      namespace: kube-system
    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
      namespace: kube-system
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        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
      namespace: kube-system
    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
      namespace: kube-system
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
    roleRef:
      kind: Role
      name: leader-locking-nfs-client-provisioner
      apiGroup: rbac.authorization.k8s.io
    
  2. 创建 provisioner

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nfs-client-provisioner
      namespace: kube-system
      labels:
        app: nfs-client-provisioner
    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: quay.io/external_storage/nfs-client-provisioner:latest
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  value: 192.168.1.1
                - name: NFS_PATH
                  value: /data/nfs/rw
          volumes:
            - name: nfs-client-root
              nfs:
              	# 主要修改ip和挂载路径
                server: 192.168.1.1
                path: /data/nfs/rw
    
  3. 创建storageclass

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: managed-nfs-storage
      namespace: kube-system
    provisioner: fuseim.pri/ifs # 外部制备器提供者,编写为提供者的名称
    parameters:
      archiveOnDelete: "false" # 是否存档,false 表示不存档,会删除 oldPath 下面的数据,true 表示存档,会重命名路径
    reclaimPolicy: Retain # 回收策略,默认为 Delete 可以配置为 Retain
    volumeBindingMode: Immediate # 默认为 Immediate,表示创建 PVC 立即进行绑定,只有 azuredisk 和 AWSelasticblockstore 支持其他值
    
  4. 测试

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: auto-pv-test-pvc
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 300Mi
      storageClassName: managed-nfs-storage
    

pvc 处于pending 状态

$ kubectl describe pvc auto-pv-test-pvc 
# 日志如下
。。。。。
Events:
  Type    Reason                Age                 From                         Message
  ----    ------                ----                ----                         -------
  Normal  ExternalProvisioning  84s (x82 over 21m)  persistentvolume-controller  waiting for a volume to be created, either by external provisioner "fuseim.pri/ifs" or manually created by system administrator

在 k8s 1.20 之后,出于对性能和统一 apiserver 调用方式的初衷,移除了对 SelfLink 的支持,而默认上面指定的 provisioner 版本需要 SelfLink 功能,因此 PVC 无法进行自动制备。

  1. 配置selflink (不推荐使用)

    修改 apiserver 配置文件
    vim /etc/kubernetes/manifests/kube-apiserver.yaml
    
    spec:
      containers:
      - command:
        - kube-apiserver
        - --feature-gates=RemoveSelfLink=false # 新增该行
        ......
    
    修改后重新应用该配置
    kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
    
  2. 更换成不需要selflink 的镜像

    # 将 provisioner 修改为如下镜像之一即可
    
    gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
    
    registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
    # 国内用这个  但是现在貌似这个不好用了
    
  3. 使用 helm 安装 nfs 驱动(推荐方案)

    # 添加repo
    helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
    # 下载
    helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
        --set nfs.server=192.168.0.1 \
        --set nfs.path=/data/nfs/rw
    

    如果 helm install 失败 就进入官网手动下载 nfs-subdir-external-provisioner

    在这里插入图片描述

    下载下来后, 解压后 进入 nfs-subdir-external-provisioner 目录 修改 values.yaml

    tar -zxvf nfs-subdir-external-provisioner-4.0.18.tgz   & cd nfs-subdir-external-provisioner 
    
    vim values.yaml
    
    # 将image 替换
    repository: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner  # 国内无法访问
    rrepository: egistry.cn-shenzhen.aliyuncs.com/xiaohh-docker/nfs-subdir-external-provisioner    # 替换成这个,截止发文日期还可以用
    tag: v4.0.2
    
  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用Kubernetesk8s)管理MySQL时,有几个主要的方面需要考虑。首先,你需要部署MySQL on k8s的环境。这可以通过使用适当的Kubernetes资源(如Deployment、Pod和Service)来实现。具体的部署方法可以参考引用中提到的资源。 其次,当你需要卸载MySQL时,你可以使用以下命令: ``` kubectl delete pod -n mysql kubectl patch ns mysql -p '{"metadata":{"finalizers":null}}' kubectl delete ns mysql ``` 这些命令将删除与MySQL相关的Pod和命名空间。具体的卸载方法可以参考引用中提到的命令。 需要注意的是,虽然可以实现MySQL的主从复制,但目前官方还没有提供MySQL on k8s的高可用实现方案。一些网上的高可用方案存在,但我们公司尚未在生产环境中使用,所以无法评价这些方案的可行性和稳定性。此外,对于大数据领域而言,MySQL通常只用作元数据存储,因此即使主节点出现故障,对于整体业务的影响也不会很大。 综上所述,Kubernetes可以用于管理MySQL,并且可以实现MySQL的主从复制。但是,要实现MySQL on k8s的高可用性,需要进一步研究和评估可行的方案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MySQL 在 K8S 环境中部署与监控,一篇搞定它!](https://blog.csdn.net/m0_73311735/article/details/127282165)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go&Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值