K8s云原生存储&存储进阶

Volume回顾

最开始直接将volume类型定义在一个yaml文件中存储不利于解藕,更适合于k8s管理员自己使用

volumes:
      - name: share-volume
        emptyDir: {}
          #medium: Memory

      - name: timezone
        hostPath:
          path: /etc/timezone
          type: File
      - name: nfs-volume
        nfs:
          server: 192.168.0.204
          path: /data/nfs/test-dp

后来引入了PV和PVC实现了解藕,之前只提到了静态存储,但是当集群规模变大,手动创建PV也是非常复杂的工作,而且不利于PV的回收,一旦创建的PV非常多,管理和扩容也很麻烦

更简单的持久化存储方式

下面讲解动态存储,通过StorageClass使用

StorageClass:存储类,由K8s管理员创建,用于动态PV的管理,可以链接至不同的后端存储,比如Ceph、GlusterFS等。之后对存储的请求可以指向StorageClass,然后StorageClass会自动的创建、删除PV

实现方式:

K8s云原生存储&存储进阶
  •   in-tree: 内置于K8s核心代码,对于存储的管理,都需要编写相应的代码。开发人员需要学习合适配各种配置,给开发人员造成较大的压力
  •   out-of-tree:让存储厂商适配k8s逻辑或接口,由存储厂商提供一个驱动(CSI或Flex Volume),安装到K8s集群,然后StorageClass只需要配置该驱动即可,驱动器会代替StorageClass管理存储,CSI符合未来发展趋势。(类似于容器厂商兼容k8s的过程,k8s独自开发CRI(Container runtime interface)接口,各容器厂商开发兼容K8S兼容k8s接口,让k8s可以有更多的容器厂商选择)

StorageClass官方文档:https://kubernetes.io/docs/concepts/storage/storage-classes/

k8s官方已经内置到代码中的StorageClass(in-tree模式,未来趋势向CSI方向迁移)

K8s云原生存储&存储进阶

下面是k8s适配是AWS厂商支持的一段参数(parameters之后适配):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate

下面是k8s适配NFS参数配置:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: example-nfs
provisioner: example.com/external-nfs
parameters:
  server: nfs-server.example.com
  path: /share
  readOnly: "false"

下面是适配Ceph RBD的参数配置:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.16.153.105:6789 # 配置cepth monitor
  adminId: kube #配置管理员账号
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube # 使用的pool
  userId: kube
  userSecretName: ceph-secret-user
  userSecretNamespace: default
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"

云原生存储Rook(存储和k8s的桥梁)

介绍

Rook是一个自我管理的分布式存储编排系统,它本身并不是存储系统,在存储和k8s之前搭建了一个桥梁,使存储系统的搭建或者维护变得特别简单,Rook将分布式存储系统转变为自我管理、自我扩展、自我修复的存储服务。它让一些存储的操作,比如部署、配置、扩容、升级、迁移、灾难恢复、监视和资源管理变得自动化,无需人工处理。并且Rook支持CSI,可以利用CSI做一些PVC的快照、扩容、克隆等操作。

参考文档:https://rook.io/
项目地址:https://github.com/rook

Rook架构

生产环境有单独的ceph集群,Rook建议使用外部连接方式连接k8s和cepth集群,但是测试开发环境是没有单独的ceph集群可以使用,中小型公司如果没有很强的运维能力,不建议在外部集群搭建ceph平台,而建议使用Rook跑一个k8s集群内部的cepth集群,本文档不去单独讲解CSI和Ceph,仅仅演示StorageClass和CSI连接ceph集群的实现方式,所以使用Rook实现本地ceph,Rook同时还能解决非生产环境中(部分大企业已经用在生产环境)mysql、redis、kafka较为方便有效的的存储实现方式,rook基于本地存储的需求,如果想深入学习外部存储集群方式,可以单独去看ceph、CSI的课程,如果rook用在生产环境,建议在本地环境搭建时,将OSD节点(cepth)和k8s业务节点分开

K8s云原生存储&存储进阶

Rook 包含多个组件:

  • Rook Operator:Rook 的核心组件,Rook Operator 是一个简单的容器,自动启动存储集群(Rook Operator 让用户可以通过 CRD 的使用来创建和管理存储集群。每种资源都定义了自己的 CRD.),并监控存储守护进程,来确保存储集群的健康。Rook 还会用 Kubernetes Pod 的形式,部署 Ceph 的 MON、OSD 以及 MGR 守护进程。
  • Rook Agent:在每个存储节点上运行,并配置一个 FlexVolume 插件,和 Kubernetes 的存储卷控制框架进行集成。Agent 处理所有的存储操作,例如挂接网络存储设备、在主机上加载存储卷以及格式化文件系统等。
  • Rook Discovers:检测挂接到存储节点上的存储设备。
  • Rook Cluster:提供了对存储机群的配置能力,用来提供块存储、对象存储以及共享文件系统。每个集群都有多个 Pool。Pool:为块存储提供支持。Pool 也是给文件和对象存储提供内部支持。Object Store:用 S3 兼容接口开放存储服务。File System:为多个 Kubernetes Pod 提供共享存储。

Ceph 包括多个组件:

  • Ceph Monitors(MON):负责生成集群票选机制。所有的集群节点都会向 Mon 进行汇报,并在每次状态变更时进行共享信息。
  • Ceph Object Store Devices(OSD):负责在本地文件系统保存对象,并通过网络提供访问。通常 OSD 守护进程会绑定在集群的一个物理盘上,Ceph 客户端直接和 OSD 打交道。
  • Ceph Manager(MGR):提供额外的监控和界面给外部的监管系统使用。
  • Reliable Autonomic Distributed Object Stores:Ceph 存储集群的核心。这一层用于为存储数据提供一致性保障,执行数据复制、故障检测以及恢复等任务。
  • MDS:负责跟踪文件存储层次结构
  • RGW:提供对象存储接口(AWS S3、阿里云OSS等)

为了在 Ceph 上进行读写,客户端首先要联系 MON,获取最新的集群地图,其中包含了集群拓扑以及数据存储位置的信息。Ceph 客户端使用集群地图来获知需要交互的 OSD,从而和特定 OSD 建立联系。

K8s云原生存储&存储进阶

Rook安装

注意事项:

  • K8s集群至少五个节点,每个节点的内存不低于5G,CPU不低于2核
  • 至少有三个存储节点,并且每个节点至少有一个裸盘
  • K8s集群所有的节点时间必须一致,被设置的节点不能打污点,除非配置污点容忍

参考文档:https://rook.io/docs/rook/v1.6/ceph-storage.html

注意:该文档仅为新版操作步骤

第一章 Rook安装 2

1.1 下载Rook安装文件 2

1.2 配置更改 2

1.3 部署rook 3

第二章 创建ceph集群 3

2.1 配置更改 3

2.2 创建Ceph集群 4

2.3 安装ceph snapshot控制器 5

第三章 安装ceph客户端工具 5

第四章 Ceph dashboard 6

4.1 暴露服务 6

4.2 登录 7

第五章 ceph块存储的使用 7

5.1 创建StorageClass和ceph的存储池 7

5.2 挂载测试 9

第六章 共享文件系统的使用 10

6.1 创建共享类型的文件系统 10

6.2 创建共享类型文件系统的StorageClass 11

6.3 挂载测试 11

第七章 PVC扩容 12

7.1 扩容文件共享型PVC 12

7.2 扩容块存储 14

第八章 PVC快照 14

8.1 块存储快照 14

8.1.1 创建snapshotClass 14

8.1.2 创建快照 15

8.1.3 指定快照创建PVC 16

8.1.4 数据校验 16

8.2 文件共享类型快照 17

第九章 PVC克隆 18

第十章 测试数据清理 18

Rook安装

注意1:rook的版本大于1.3,不要使用目录创建集群,要使用单独的裸盘进行创建,也就是创建一个新的磁盘,挂载到宿主机,不进行格式化,直接使用即可。对于的磁盘节点配置如下:

K8s云原生存储&存储进阶

注意2:做这个实验需要高配置,每个节点配置不能低于2核4G

注意3:k8s 1.19以上版本,快照功能需要单独安装snapshot控制器

下载Rook安装文件

下载指定版本Rook,也可以下载最新版

git clone --single-branch --branch v1.6.3 https://github.com/rook/rook.git

配置更改

cd rook/cluster/examples/kubernetes/ceph

修改Rook CSI镜像地址,原本的地址可能是gcr的镜像,但是gcr的镜像无法被国内访问,所以需要同步gcr的镜像到阿里云镜像仓库,文档版本已经为大家完成同步,可以直接修改如下:

vim operator.yaml

K8s云原生存储&存储进阶

改为:

ROOK_CSI_REGISTRAR_IMAGE: "registry.cn-beijing.aliyuncs.com/dotbalo/csi-node-driver-registrar:v2.0.1"

ROOK_CSI_RESIZER_IMAGE: "registry.cn-beijing.aliyuncs.com/dotbalo/csi-resizer:v1.0.1"

ROOK_CSI_PROVISIONER_IMAGE: "registry.cn-beijing.aliyuncs.com/dotbalo/csi-provisioner:v2.0.4"

ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.cn-beijing.aliyuncs.com/dotbalo/csi-snapshotter:v4.0.0"

ROOK_CSI_ATTACHER_IMAGE: "registry.cn-beijing.aliyuncs.com/dotbalo/csi-attacher:v3.0.2"

如果是其他版本,需要自行同步,同步方法可以在网上找到相关文章。可以参考https://blog.csdn.net/sinat_35543900/article/details/103290782

还是operator文件,新版本rook默认关闭了自动发现容器的部署,可以找到ROOK_ENABLE_DISCOVERY_DAEMON改成true即可:

K8s云原生存储&存储进阶

部署rook

1.5.3版本的部署步骤如下:

cd cluster/examples/kubernetes/ceph

kubectl create -f crds.yaml -f common.yaml -f operator.yaml

等待operator容器和discover容器启动

[root@k8s-master01 ceph]# kubectl -n rook-ceph get pod

K8s云原生存储&存储进阶

全部变成1/1 Running 才可以创建Ceph集群

创建ceph集群

配置更改

主要更改的是osd节点所在的位置:

K8s云原生存储&存储进阶

注意:新版必须采用裸盘,即未格式化的磁盘。其中k8s-master03 k8s-node01 node02有新加的一个磁盘,可以通过lsblk -f查看新添加的磁盘名称。建议最少三个节点,否则后面的试验可能会出现问题

创建Ceph集群

kubectl create -f cluster.yaml

创建完成后,可以查看pod的状态:

[root@k8s-master01 ceph]# kubectl -n rook-ceph get pod

K8s云原生存储&存储进阶

需要注意的是,osd-x的容器必须是存在的,且是正常的。如果上述Pod均正常,则认为集群安装成功。

更多配置:https://rook.io/docs/rook/v1.6/ceph-cluster-crd.html

安装ceph snapshot控制器

k8s 1.19版本以上需要单独安装snapshot控制器,才能完成pvc的快照功能,所以在此提前安装下,如果是1.19以下版本,不需要单独安装。

snapshot控制器的部署在集群安装时的k8s-ha-install项目中,需要切换到1.20.x分支:

cd /root/k8s-ha-install/

git checkout manual-installation-v1.20.x

创建snapshot controller:

kubectl create -f snapshotter/ -n kube-system

[root@k8s-master01 k8s-ha-install]# kubectl get po -n kube-system -l app=snapshot-controller

K8s云原生存储&存储进阶

具体文档:https://rook.io/docs/rook/v1.6/ceph-csi-snapshot.html

安装ceph客户端工具

[root@k8s-master01 ceph]# pwd

cd /root/rook/cluster/examples/kubernetes/ceph

[root@k8s-master01 ceph]# kubectl create -f toolbox.yaml -n rook-ceph

deployment.apps/rook-ceph-tools created

待容器Running后,即可执行相关命令

[root@k8s-master01 ceph]# kubectl get po -n rook-ceph -l app=rook-ceph-tools

K8s云原生存储&存储进阶

[root@k8s-master01 ceph]# kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash

[root@rook-ceph-tools-fc5f9586c-9hs8q /]# ceph config set mon auth_allow_insecure_global_id_reclaim false

[root@rook-ceph-tools-6f7467bb4d-qzsvg /]# ceph status

K8s云原生存储&存储进阶

[root@rook-ceph-tools-6f7467bb4d-qzsvg /]# ceph osd status

注:按照文档应该只有k8s-node01、k8s-node02、k8s-master03,这里我都加入了

K8s云原生存储&存储进阶

[root@rook-ceph-tools-6f7467bb4d-qzsvg /]# ceph df

K8s云原生存储&存储进阶

Ceph dashboard

暴露服务

默认情况下,ceph dashboard是打开的,可以创建一个nodePort类型的Service暴露服务:

vim dashboard-np.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: rook-ceph-mgr
    ceph_daemon_id: a
    rook_cluster: rook-ceph
  name: rook-ceph-mgr-dashboard-np
  namespace: rook-ceph
spec:
  ports:
  - name: http-dashboard
    port: 7000
    protocol: TCP
    targetPort: 7000
  selector:
    app: rook-ceph-mgr
    ceph_daemon_id: a
    rook_cluster: rook-ceph
  sessionAffinity: None
  type: NodePort

保存退出后,会创建一个端口,然后通过任意k8s节点的IP+该端口即可访问该dashboard:

[root@k8s-master01 ceph]# kubectl get svc -n rook-ceph rook-ceph-mgr-dashboard-np

K8s云原生存储&存储进阶
K8s云原生存储&存储进阶

登录

账号为admin,查看密码:

kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo

K8s云原生存储&存储进阶

问题警告解决:https://docs.ceph.com/en/octopus/rados/operations/health-checks/

ceph块存储的使用

块存储一般用于一个Pod挂载一块存储使用,相当于一个服务器新挂了一个盘,只给一个应用使用。

参考文档:https://rook.io/docs/rook/v1.6/ceph-block.html

创建StorageClass和ceph的存储池

[root@k8s-master01 ceph]# pwd

/root/rook/cluster/examples/kubernetes/ceph

[root@k8s-master01 ceph]# vim csi/rbd/storageclass.yaml

failureDomain: host是根据host来存放多个OSD副本,且模式为多个节点上(replicated:size决定副本数量),若单台node故障可以通过其他节点上的数据恢复。因为我是试验环境,所以将副本数设置成了2(不能设置为1),生产环境最少为3,且要小于等于osd的数量,其他配置可以参考视频:

K8s云原生存储&存储进阶

创建StorageClass和存储池:

[root@k8s-master01 ceph]# kubectl create -f csi/rbd/storageclass.yaml -n rook-ceph

K8s云原生存储&存储进阶

查看创建的cephblockpool和storageClass(StorageClass没有namespace隔离性):

[root@k8s-master01 ceph]# kubectl get cephblockpool -n rook-ceph

K8s云原生存储&存储进阶

[root@k8s-master01 ceph]# kubectl get sc

K8s云原生存储&存储进阶

此时可以在ceph dashboard查看到改Pool,如果没有显示说明没有创建成功

K8s云原生存储&存储进阶

挂载测试

创建一个MySQL服务

参考:https://rook.io/docs/rook/v1.6/ceph-block.html

[root@k8s-master01 kubernetes]# pwd

/root/rook/cluster/examples/kubernetes

使用RDB创建mysql.yaml,mysql要求有主从,有自己的独立空间使用块存储

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi #测试环境修改小一些
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
    tier: mysql
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: changeme
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pv-claim

[root@k8s-master01 kubernetes]# kubectl create -f mysql.yaml

K8s云原生存储&存储进阶

该文件有一段pvc的配置

K8s云原生存储&存储进阶

pvc会连接刚才创建的storageClass,然后动态创建pv,然后连接到ceph创建对应的存储

之后创建pvc只需要指定storageClassName为刚才创建的StorageClass名称即可连接到rook的ceph。如果是statefulset,只需要将volumeClaimTemplates里面的Claim名称改为StorageClass名称即可动态创建Pod。

其中MySQL deployment的volumes配置挂载了该pvc:

K8s云原生存储&存储进阶

claimName为pvc的名称

因为MySQL的数据不能多个MySQL实例连接同一个存储,所以一般只能用块存储。相当于新加了一块盘给MySQL使用。

创建完成后可以查看创建的pvc和pv

K8s云原生存储&存储进阶

此时在ceph dashboard上面也可以查看到对应的image的csi-vol

K8s云原生存储&存储进阶
K8s云原生存储&存储进阶

创建wordpress

kubectl create -f wordpress.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: NodePort
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
    tier: frontend
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
        - image: wordpress:4.6.1-apache
          name: wordpress
          env:
            - name: WORDPRESS_DB_HOST
              value: wordpress-mysql
            - name: WORDPRESS_DB_PASSWORD
              value: changeme
          ports:
            - containerPort: 80
              name: wordpress
          volumeMounts:
            - name: wordpress-persistent-storage
              mountPath: /var/www/html
      volumes:
        - name: wordpress-persistent-storage
          persistentVolumeClaim:
            claimName: wp-pv-claim
K8s云原生存储&存储进阶
K8s云原生存储&存储进阶

StatefulSet volumeClaimTemplates

每个pod都使用一个存储,pv和pvc是无法实现的,deployment中设置多个pod会共享同一个存储,volumeClaimTemplates主要用于StatefulSet独有设置,挂载到pvc上去,适用于mysql集群和redis集群

vim sts-sc.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx 
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "rook-ceph-block"
      resources:
        requests:
          storage: 1Gi
K8s云原生存储&存储进阶

尝试写一个文件,查看是否会共享

K8s云原生存储&存储进阶

kubectl delete pvc www-web-0 www-web-1 www-web-2

共享文件系统的使用

共享文件系统一般用于多个Pod共享一个存储

官方文档:https://rook.io/docs/rook/v1.6/ceph-filesystem.html

创建共享类型的文件系统

[root@k8s-master01 ceph]# pwd

/root/rook/cluster/examples/kubernetes/ceph

[root@k8s-master01 ceph]# kubectl create -f filesystem.yaml

cephfilesystem.ceph.rook.io/myfs created

[root@k8s-master01 ceph]# vim filesystem.yaml

创建完成后会启动mds容器,需要等待启动后才可进行创建pv

[root@k8s-master01 ceph]# kubectl -n rook-ceph get pod -l app=rook-ceph-mds

K8s云原生存储&存储进阶

也可以在ceph dashboard上面查看状态

K8s云原生存储&存储进阶

创建共享类型文件系统的StorageClass

[root@k8s-master01 cephfs]# pwd

/root/rook/cluster/examples/kubernetes/ceph/csi/cephfs

[root@k8s-master01 cephfs]# kubectl create -f storageclass.yaml

storageclass.storage.k8s.io/rook-cephfs created

之后将pvc的storageClassName设置成rook-cephfs即可创建共享文件类型的存储,类似于NFS,可以给多个Pod共享数据。

挂载测试

[root@k8s-master01 cephfs]# pwd

/root/rook/cluster/examples/kubernetes/ceph/csi/cephfs

[root@k8s-master01 cephfs]# ls

K8s云原生存储&存储进阶

kube-registry.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cephfs-pvc
  namespace: kube-system
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: rook-cephfs
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-registry
  namespace: kube-system
  labels:
    k8s-app: kube-registry
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 3
  selector:
    matchLabels:
      k8s-app: kube-registry
  template:
    metadata:
      labels:
        k8s-app: kube-registry
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
        - name: registry
          image: registry:2
          imagePullPolicy: Always
          resources:
            limits:
              cpu: 100m
              memory: 100Mi
          env:
            # Configuration reference: https://docs.docker.com/registry/configuration/
            - name: REGISTRY_HTTP_ADDR
              value: :5000
            - name: REGISTRY_HTTP_SECRET
              value: "Ple4seCh4ngeThisN0tAVerySecretV4lue"
            - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
              value: /var/lib/registry
          volumeMounts:
            - name: image-store
              mountPath: /var/lib/registry
          ports:
            - containerPort: 5000
              name: registry
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: registry
          readinessProbe:
            httpGet:
              path: /
              port: registry
      volumes:
        - name: image-store
          persistentVolumeClaim:
            claimName: cephfs-pvc
            readOnly: false

[root@k8s-master01 cephfs]# kubectl create -f kube-registry.yaml

K8s云原生存储&存储进阶

查看创建的pvc和pod

[root@k8s-master01 cephfs]# kubectl get po -n kube-system -l k8s-app=kube-registry

K8s云原生存储&存储进阶

[root@k8s-master01 cephfs]# kubectl get pvc -n kube-system

K8s云原生存储&存储进阶

该文件的pvc配置,用于连接ceph创建存储,如下:

K8s云原生存储&存储进阶

然后在deployment的volumes配置添加了该pvc,并将其挂载到了/var/lib/registry

K8s云原生存储&存储进阶

注意claimName为pvc的名称。

此时一共创建了三个Pod,这三个Pod共用了一个存储,挂载到了/var/lib/registry,该目录三个容器共享数据。

验证共享数据:

K8s云原生存储&存储进阶

Nginx挂载测试

vim nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  selector:
    app: nginx
  type: ClusterIP
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-share-pvc
spec:
  storageClassName: rook-cephfs 
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      containers:
      - name: nginx
        image: nginx 
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
        - name: www
          persistentVolumeClaim:
            claimName: nginx-share-pvc

kubectl create -f nginx.yaml

K8s云原生存储&存储进阶
K8s云原生存储&存储进阶

PVC扩容

文件共享类型的PVC扩容需要k8s 1.15+

块存储类型的PVC扩容需要k8s 1.16+

PVC扩容需要开启ExpandCSIVolumes,新版本的k8s已经默认打开了这个功能,可以查看自己的k8s版本是否已经默认打开了该功能:

kube-apiserver -h |grep ExpandCSIVolumes

K8s云原生存储&存储进阶

如果default为true就不需要打开此功能,如果default为false,需要开启该功能。

扩容文件共享型PVC

找到刚才创建的文件共享型StorageClass,将allowVolumeExpansion设置为true(新版rook默认为true,如果不为true更改后执行kubectl replace即可):

K8s云原生存储&存储进阶

找到创建的pvc:

[root@k8s-master01 cephfs]# kubectl get pvc -n kube-system

K8s云原生存储&存储进阶

[root@k8s-master01 cephfs]# kubectl edit pvc cephfs-pvc -n kube-system

将大小修改为2Gi,之前是1Gi

K8s云原生存储&存储进阶

保存退出:

查看PV和PVC的大小:

[root@k8s-master01 cephfs]# kubectl get pvc -n kube-system

K8s云原生存储&存储进阶

[root@k8s-master01 cephfs]# kubectl get pv

K8s云原生存储&存储进阶

查看容器内是否已经完成扩容:

[root@k8s-master01 cephfs]# kubectl exec -ti kube-registry-66d4c7bf47-2fbcl -n kube-system -- df -Th | grep "/var/lib/registry"

K8s云原生存储&存储进阶

同样的步骤可以扩容到3G:

K8s云原生存储&存储进阶

扩容块存储

扩容步骤类似,找到第五章创建PVC,直接edit即可

[root@k8s-master01 cephfs]# kubectl edit pvc mysql-pv-claim

persistentvolumeclaim/mysql-pv-claim edited

[root@k8s-master01 cephfs]# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

mysql-pv-claim Bound pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc 2Gi RWO rook-ceph-block 70m

可以看到此时pvc并没有扩容,但是pv已经扩容:

[root@k8s-master01 cephfs]# kubectl get pv | grep default/mysql-pv-claim

K8s云原生存储&存储进阶

也可以看到ceph dashboard的image也完成了扩容,但是pvc和pod里面的状态会有延迟,大概等待5-10分钟后,即可完成扩容:

K8s云原生存储&存储进阶
K8s云原生存储&存储进阶

PVC快照

注意:PVC快照功能需要k8s 1.17+

块存储快照

创建snapshotClass

[root@k8s-master01 rbd]# pwd

/root/rook/cluster/examples/kubernetes/ceph/csi/rbd

[root@k8s-master01 rbd]# kubectl create -f snapshotclass.yaml

K8s云原生存储&存储进阶

创建快照

首先在之前创建的MySQL容器里创建一个文件夹,并创建一个文件

[root@k8s-master01 rbd]# kubectl get po

K8s云原生存储&存储进阶

[root@k8s-master01 rbd]# kubectl exec -ti wordpress-mysql-6965fc8cc8-8n8z2 -- bash

root@wordpress-mysql-6965fc8cc8-6wt6j:/# cd /var/lib/mysql

root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# ls

K8s云原生存储&存储进阶

root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# mkdir test_snapshot

root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# echo "test for snapshot" > test_snapshot/1.txt

修改snapshot.yaml文件的source pvc为创建的MySQL pvc:

K8s云原生存储&存储进阶

创建快照及查看状态:

[root@k8s-master01 rbd]# kubectl create -f snapshot.yaml

K8s云原生存储&存储进阶

[root@k8s-master01 rbd]# kubectl get volumesnapshotclass

K8s云原生存储&存储进阶

[root@k8s-master01 rbd]# kubectl get volumesnapshot

K8s云原生存储&存储进阶

指定快照创建PVC

如果想要创建一个具有某个数据的PVC,可以从某个快照恢复:

[root@k8s-master01 rbd]# cat pvc-restore.yaml

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc-restore
spec:
  storageClassName: rook-ceph-block #storageClassName名称要对应
  dataSource:
    name: rbd-pvc-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 12Gi

[root@k8s-master01 rbd]# kubectl create -f pvc-restore.yaml

K8s云原生存储&存储进阶

注意:dataSource为快照名称,storageClassName为新建pvc的storageClass,storage的大小不能低于原pvc的大小。

[root@k8s-master01 rbd]# kubectl get pvc

K8s云原生存储&存储进阶

数据校验

创建一个容器,挂载该PVC,查看是否含有之前的文件:

[root@k8s-master01 rbd]# vim restore-check-snapshot-rbd.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: check-snapshot-restore
spec:
  selector:
    matchLabels:
      app: check 
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: check 
    spec:
      containers:
      - image: alpine:3.8
        name: check
        command:
        - sh
        - -c
        - sleep 36000
        volumeMounts:
        - name: check-mysql-persistent-storage
          mountPath: /mnt
      volumes:
      - name: check-mysql-persistent-storage
        persistentVolumeClaim:
          claimName: rbd-pvc-restore 

[root@k8s-master01 rbd]# kubectl create -f restore-check-snapshot-rbd.yaml

deployment.apps/check-snapshot-restore created

查看数据是否存在

[root@k8s-master01 rbd]# kubectl get po

K8s云原生存储&存储进阶

[root@k8s-master01 rbd]# kubectl exec -ti check-snapshot-restore-64b85c5f88-kh8b9 -- cat /mnt/test_snapshot/1.txt

K8s云原生存储&存储进阶

测试无误后清理数据(snapshotclass可以不删除,后期创建rbd快照直接用该snapshotclass即可):

[root@k8s-master01 rbd]# kubectl delete -f restore-check-snapshot-rbd.yaml -f pvc-restore.yaml -f snapshot.yaml

K8s云原生存储&存储进阶

文件共享类型快照

操作步骤和块存储类型无区别,可以参考:

https://rook.io/docs/rook/v1.6/ceph-csi-snapshot.html#cephfs-snapshots

PVC克隆

[root@k8s-master01 rbd]# pwd

/root/rook/cluster/examples/kubernetes/ceph/csi/rbd

[root@k8s-master01 rbd]# cat pvc-clone.yaml

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc-clone
spec:
  storageClassName: rook-ceph-block
  dataSource:
    name: mysql-pv-claim
    kind: PersistentVolumeClaim #基于当前的pvc创建pvc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 12Gi

[root@k8s-master01 rbd]# kubectl create -f pvc-clone.yaml

persistentvolumeclaim/rbd-pvc-clone created

[root@k8s-master01 rbd]# kubectl get pvc

K8s云原生存储&存储进阶

需要注意的是pvc-clone.yaml的dataSource的name是被克隆的pvc名称,在此是mysql-pv-claim,storageClassName为新建pvc的storageClass名称,storage不能小于之前pvc的大小。

测试数据清理

如果Rook要继续使用,可以只清理创建的deploy、pod、pvc即可。之后可以直接投入使用

数据清理步骤(必须听课):

  1. 首先清理挂载了PVC和Pod,可能需要清理单独创建的Pod和Deployment或者是其他的高级资源
    kubectl delete deployments.apps wordpress-mysql --all
    kubectl delete pod --all
  2. 之后清理PVC,清理掉所有通过ceph StorageClass创建的PVC后,最好检查下PV是否被清理
    kubectl delete pvc --all
  3. 之后清理快照:kubectl delete volumesnapshot XXXXXXXX
  4. 之后清理创建的Pool,包括块存储和文件存储
    1. kubectl delete -n rook-ceph cephblockpool replicapool
    2. kubectl delete -n rook-ceph cephfilesystem myfs
  5. 清理StorageClass:kubectl delete sc rook-ceph-block rook-cephfs
  6. 清理Ceph集群:kubectl -n rook-ceph delete cephcluster rook-ceph
  7. 删除Rook资源:
    1. kubectl delete -f operator.yaml
    2. kubectl delete -f common.yaml
    3. kubectl delete -f crds.yaml
  8. 如果卡住需要参考Rook的troubleshooting
    1. https://rook.io/docs/rook/v1.6/ceph-teardown.html#troubleshooting

for CRD in $(kubectl get crd -n rook-ceph | awk '/ceph.rook.io/ {print $1}'); do kubectl get -n rook-ceph "$CRD" -o name | xargs -I {} kubectl patch {} --type merge -p '{"metadata":{"finalizers": [null]}}' -n rook-ceph; done

  1. 清理数据目录和磁盘

参考链接:https://rook.io/docs/rook/v1.6/ceph-teardown.html#delete-the-data-on-hosts

参考链接:https://rook.io/docs/rook/v1.6/ceph-teardown.html

发布者:LJH,转发请注明出处:https://www.ljh.cool/37323.html

(0)
上一篇 2023年6月8日 下午6:36
下一篇 2023年6月23日 下午9:27

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注