NFS搭建
安装nfs-server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| # 在每个机器。 yum install -y nfs-utils
# 在master 执行以下命令 echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
# 执行以下命令,启动 nfs 服务;创建共享目录 mkdir -p /nfs/data
# 在master执行 systemctl enable rpcbind systemctl enable nfs-server systemctl start rpcbind systemctl start nfs-server
# 使配置生效 exportfs -r
#检查配置是否生效 exportfs
|
配置nfs-client(选做)
1 2 3 4 5
| showmount -e 172.31.0.4
mkdir -p /nfs/data
mount -t nfs 172.31.0.4:/nfs/data /nfs/data
|
配置默认存储
配置动态供应的默认存储类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| ## 创建了一个存储类 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: archiveOnDelete: "true" ## 删除pv的时候,pv的内容是否要备份
--- apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed 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: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2 # resources: # limits: # cpu: 10m # requests: # cpu: 10m volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: 172.31.0.4 ## 指定自己nfs服务器地址 - name: NFS_PATH value: /nfs/data ## nfs服务器共享的目录 volumes: - name: nfs-client-root nfs: server: 172.31.0.4 path: /nfs/data --- apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - 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 # replace with namespace where provisioner is deployed 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 # replace with namespace where provisioner is deployed 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 # replace with namespace where provisioner is deployed namespace: default subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
|
确认是否生效
Ceph存储集群
Rook介绍
Rook https://rook.io 是一个自管理的分布式存储编排系统,可以为Kubernetes提供便利的存储解决方案。Rook本身并不提供存储,而是在kubernetes和存储系统之间提供适配层,简化存储系统的部署与维护工作。
目前,Rook支持的存储系统包括:Ceph、CockroachDB、Cassandra、EdgeFS、Minio、NFS。当然,Rook支持的最好的还是Cph 和 NFS。

为什么要使用Rook?
使用Rook的其中一个主要好处在于它是通过原生的Kubernetes机制和数据存储交互。这就意味着你不再需要通过命令行手动配置Ceph。
- 你想要在一个集群里部署CephFS吗?只需要创建一个YAML文件就行了!
- 什么?你还想要部署一个支持S3 API的对象存储?行,另外再建一个YAML文件就行!
Cpeh介绍
Ceph Ceph Documentation 是一种为优秀的性能、可靠性和可扩展性而设计的统一的、分布式文件系统。ceph 的统一体现在可以提供文件系统、块存储和对象存储,分布式体现在可以动态扩展。
Ceph支持三种存储:
- 块存储(RDB):可以直接作为磁盘挂载
- 文件系统(CephFS):提供POSIX兼容的网络文件系统CephFS,专注于高性能、大容量存储
- 对象存储(RADOSGW):提供RESTful接口,也提供多种编程语言绑定。兼容S3(是AWS里的对象存储)、Swift(是openstack里的对象存储)
核心组件
Ceph 主要有三个基本进程:
- OSD 用于集群中所有数据与对象的存储,处理集群数据的复制、恢复、回填、再均衡,并向其他osd守护进程发送心跳,然后向 Monitor 提供一些监控信息。
- Monitor 监控整个集群的状态,维护集群的 cluster MAP 二进制表,保证集群数据的一致性。
- MDS (可选) 为 Ceph 文件系统提供元数据计算、缓存与同步。MDS 进程并不是必须的进程,只有需要使用 CephFS 时,才需要配置 MDS 节点。
安装Ceph集群
通过rook安装ceph集群需要满足以下两个前提条件:
- 已部署好的Kubernetes集群 (✅)
- osd节点需要有未格式化⽂件系统的磁盘(✅)
前置准备
1. 在master1节点下载rook到本地,使用最新版本1.8.8
1
| git clone --single-branch --branch v1.8.8 https://github.com/rook/rook.git
|
2. 给所有需要安装ceph的worker节点安装lvm2
1 2 3 4 5 6
| yum install lvm2 -y
#检查是否安装成功 [root@sit-k8s-worker1 ~]# yum list installed | grep lvm2 lvm2.x86_64 7:2.02.187-6.el7_9.5 @iflytekdc-updates lvm2-libs.x86_64 7:2.02.187-6.el7_9.5 @iflytekdc-updates
|
3. 给worker节点打上标签,保证ceph只安装在这3台worker节点上
1 2 3
| kubectl label node k8s-worker1 role=ceph-storage kubectl label node k8s-worker2 role=ceph-storage kubectl label node k8s-worker3 role=ceph-storage
|
修改完成后使用命令查看label属性
1 2 3 4 5 6
| [root@k8s-master1 ~]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS k8s-worker1 Ready worker 3d17h v1.21.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-worker1,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,role=ceph-storage k8s-worker2 Ready worker 3d17h v1.21.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-worker2,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,role=ceph-storage k8s-worker3 Ready worker 3d17h v1.21.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-worker3,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,role=ceph-storage
|
- 手动下载安装ceph所需镜像
rook 中ceph依赖很多都是使用国外的镜像,下载很慢,而且经常出现400,所以建议直接手动下载。
注意,以下脚本在所有节点都需要运行(master 和 worker)
创建可执行文件 ceph.sh,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| image_list=( csi-node-driver-registrar:v2.5.0 csi-attacher:v3.4.0 csi-snapshotter:v5.0.1 csi-resizer:v1.4.0 csi-provisioner:v3.1.0 ) aliyuncs="registry.aliyuncs.com/it00021hot" google_gcr="k8s.gcr.io/sig-storage" for image in ${image_list[*]} do docker image pull ${aliyuncs}/${image} docker image tag ${aliyuncs}/${image} ${google_gcr}/${image} docker image rm ${aliyuncs}/${image} echo "${aliyuncs}/${image} ${google_gcr}/${image} downloaded." done
|
同时给其授予可执行权限
检查镜像是否下载完成
1
| docker images | grep csi
|

5. 修改ceph调度算法,通过节点亲和性让其运行在指定节点上,同时手动指定节点及磁盘
还记得我们之前挂载磁盘的时候给ceph预留了一个空盘吧?现在需要用到了~
先通过lsblk查看盘符,可以看到vdb2是预留给ceph的

然后修改ceph集群配置
1
| vim /root/rook/deploy/examples/cluster.yaml
|

注意,name 不能够配置为IP,而应该是标签 kubernetes.io/hostname 的内容
6. 修改operator.yaml,让CSI守护进程可以调度到主节点
默认情况下master节点是不允许调度的,但是ceph有些守护进程是需要调度到master去。
这一步是为了解决后面出现的问题,如果此时不修改也可以在后面出现问题的时候再改。
这些都是经验教训,网上的安装手册不会告诉你有这一步。
先查看一下master节点的污点设置
1 2 3
| [root@k8s-master1 ~]# kubectl describe no/sit-k8s-master1 | grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule
|
然后修改rook operator的配置
1
| vim /root/rook/deploy/examples/operator.yaml
|

安装ceph集群
ceph 相关镜像较大,创建集群过程中可能会存在镜像拉取失败问题,可以在worker节点提前下载。
所需镜像:
rook/ceph:v1.8.8
quay.io/ceph/ceph: v16.2.7
quay.io/cephcsi/cephcsi:v3.5.1
1. 创建ceph所需要的资源
1 2
| cd /root/rook/deploy/examples kubectl apply -f crds.yaml -f common.yaml -f operator.yaml
|
执行完成后等待容器启动,只有完全启动后才能执行进行下一步操作。

2. 安装ceph集群
需要先修改一下集群osd的资源限制,否则osd的内存使用率会无限增长(同样是经验教训)
1 2
| cd /root/rook/deploy/examples vim cluster.yaml
|
在186行处加入资源限制,建议内存设置4G以上,同时需要注意yaml文件的格式。

修改保存后执行以下命令安装ceph集群
1
| kubectl apply -f cluster.yaml
|
创建完成后,可以查看pod的状态:

以上是所有组件的 pod 完成后的状态,以rook-ceph-osd-prepare 开头的 pod 用于自动感知集群新挂载硬盘,只不过我们前面手动指定了节点,所以这个不起作用。osd-0、osd-1、osd-2容器必须是存在且正常的,如果上述pod均正常运行成功,则视为集群安装成功。
安装ceph dashboard
Ceph Dashboard 是一个内置的基于 Web 的管理和监视应用程序,它是开源 Ceph 发行版的一部分。通过 Dashboard 可以获取 Ceph 集群的各种基本状态信息。
默认的 ceph 已经安装的 ceph-dashboard,其 SVC 地址是 service clusterIP,并不能被外部访问,需要创建 service 服务
1
| kubectl apply -f dashboard-external-https.yaml
|
创建NodePort类型就可以被外部访问了
1 2 3 4
| [root@k8s-master1 ~]# kubectl get svc -n rook-ceph|grep dashboard
rook-ceph-mgr-dashboard ClusterIP 109.233.40.229 <none> 8443/TCP 8m28s rook-ceph-mgr-dashboard-external-https NodePort 109.233.34.181 <none> 8443:32234/TCP 29s
|
浏览器访问(master1-ip换成自己的集群ip): https://master1-ip:32234/
用户名默认是admin,至于密码可以通过以下代码获取:
1
| kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}"|base64 --decode && echo
|


安装rook工具箱
Rook 工具箱是一个包含用于 Rook 调试和测试的常用工具的容器,安装很简单
1 2
| cd /root/rook/deploy/examples kubectl apply -f toolbox.yaml -n rook-ceph
|
待容器Running后,即可执行相关命令:
1 2 3 4 5 6 7
| # 查看容器状态 [root@k8s-master1 ~]# kubectl get po -n rook-ceph | grep tools
rook-ceph-tools-775f4f4468-dcg4x 1/1 Running 0 2m12s
# 进入ceph容器 [root@k8s-master1 ~]# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- bash
|

工具箱相关查询命令
1 2 3 4
| ceph status ceph osd status ceph df rados df
|
部署 RBD StorageClass
Ceph 可以同时提供对象存储 RADOSGW、块存储 RBD、文件系统存储 Ceph FS。RBD 即 RADOS Block Device 的简称,RBD 块存储是最稳定且最常用的存储类型。RBD 块设备类似磁盘可以被挂载。RBD 块设备具有快照、多副本、克隆和一致性等特性,数据以条带化的方式存储在 Ceph 集群的多个 OSD 中。注意:RBD只支持ReadWriteOnce存储类型
1. 创建 StorageClass
1 2
| cd /root/rook/deploy/examples/csi/rbd kubectl apply -f storageclass.yaml
|
2. 校验pool安装情况
1 2 3 4 5
| [root@k8s-master1 ~]# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- bash
[root@rook-ceph-tools-775f4f4468-dcg4x /]# ceph osd lspools 1 device_health_metrics 2 replicapool
|
3. 查看StorageClass
1 2 3 4
| [root@k8s-master1 rbd]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 43s
|
4. 将Ceph设置为默认存储卷
1
| [root@k8s-master1 ~]# kubectl patch storageclass rook-ceph-block -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
|
修改完成后再查看StorageClass状态(有个default标识)
1 2 3 4
| [root@k8s-master1 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE rook-ceph-block (default) rook-ceph.rbd.csi.ceph.com Delete Immediate true 108s
|
通过上面的步骤我们已经给Kubernetes集群安装了Ceph存储,至此我们的高可用集群就已经搭建完毕,甚至可以直接在生产环境使用了。同时也可以看到使用Rook安装Ceph还是很简单的,只需要执行对应的yaml文件即可。
不过要注意的是我们目前给集群安装的StorageClass是基于RBD的块存储,只支持ReadWriteOnce存储类型,如果你要使用ReadWriteMany存储类型,还需要安装CephFs存储。