当前位置: 首页 > news >正文

基于云原生分布式存储ceph实现k8s数据持久化

在这里插入图片描述

文章目录

        • 1、初始化集群
          • 1.1 集群机器配置
          • 1.2 配置主机名
          • 1.3 配置hosts文件
          • 1.4、配置互信
          • 1.5、关闭防火墙
          • 1.6、关闭selinux
          • 1.7、配置Ceph安装源
          • 1.8、配置时间同步
          • 1.9、安装基础软件包
        • 2、安装ceph集群
          • 2.1 安装ceph-deploy
          • 2.2 创建monitor节点
          • 2.3 安装ceph-monitor
          • 2.4 部署osd服务
          • 2.5 创建ceph文件系统
          • 2.6 测试k8s挂载ceph rbd
          • 2.7 基于ceph rbd生成pv
          • 2.8 基于storageclass动态生成pv
          • 2.9 k8s挂载cephfs

1、初始化集群

1.1 集群机器配置
主机名ip硬盘大小
master1-admin192.168.75.160100G60G60G
node1-monitor192.168.75.161100G60G60G
node2-osd192.168.75.162100G60G60G
1.2 配置主机名
[root@localhost ~]# hostnamectl set-hostname master1-admin && bash
[root@localhost ~]# hostnamectl set-hostname node1-monitor && bash
[root@localhost ~]# hostnamectl set-hostname node2-osd && bash
1.3 配置hosts文件

修改master1-admin、node1-monitor、node2-osd机器的/etc/hosts文件,增加如下三行:

192.168.75.160 master1-admin
192.168.75.161 node1-monitor
192.168.75.162 node2-osd
1.4、配置互信

生成ssh 密钥对

[root@master1-admin ~]# ssh-keygen -t rsa  #一路回车,不输入密码
把本地的ssh公钥文件安装到远程主机对应的账户
[root@master1-admin ~]# ssh-copy-id node1-monitor

在这里插入图片描述

[root@master1-admin ~]# ssh-copy-id node2-osd 
[root@master1-admin ~]# ssh-copy-id master1-admin
[root@node1-monitor ~]# ssh-keygen  #一路回车,不输入密码
把本地的ssh公钥文件安装到远程主机对应的账户
[root@node1-monitor ~]# ssh-copy-id  master1-admin
[root@node1-monitor ~]# ssh-copy-id  node1-monitor
[root@node1-monitor ~]# ssh-copy-id node2-osd
[root@node2-osd ~]# ssh-keygen  #一路回车,不输入密码
把本地的ssh公钥文件安装到远程主机对应的账户
[root@node2-osd ~]# ssh-copy-id master1-admin 
[root@node2-osd ~]# ssh-copy-id node1-monitor 
[root@node2-osd ~]# ssh-copy-id node2-osd
1.5、关闭防火墙
[root@master1-admin ~]# systemctl stop firewalld ; systemctl disable firewalld
[root@node1-monitor ~]# systemctl stop firewalld ; systemctl disable firewalld
[root@node2-osd ~]# systemctl stop firewalld ; systemctl disable firewalld
1.6、关闭selinux

所有ceph节点的selinux都关闭

#临时关闭
setenforce 0
#永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
#注意:修改selinux配置文件之后,重启机器,selinux才能永久生效
1.7、配置Ceph安装源

配置阿里云的repo源,master1-admin、node1-monitor、node2-osd上操作:

yum install -y yum-utils && sudo yum-config-manager --add-repo https://dl.fedoraproject.org/pub/epel/7/x86_64/ && sudo yum install --nogpgcheck -y epel-release && sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 && sudo rm /etc/yum.repos.d/dl.fedoraproject.org*

在 /etc/yum.repos.d/ceph.repo新建repo源

cat  /etc/yum.repos.d/ceph.repo
[Ceph]
name=Ceph packages for $basearch
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1
[Ceph-noarch] 
name=Ceph noarch packages 
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1 
[ceph-source]
name=Ceph source packages 
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/SRPMS/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1
1.8、配置时间同步

配置机器时间跟网络时间同步,在ceph的每台机器上操作

service ntpd stop
ntpdate cn.pool.ntp.org
crontab -e
* */1 * * * /usr/sbin/ntpdate   cn.pool.ntp.orgservice crond restart
1.9、安装基础软件包

安装基础软件包,在ceph的每台机器上操作

yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel  python-devel epel-release openssh-server socat  ipvsadm conntrack ntpdate telnet deltarpm

2、安装ceph集群

2.1 安装ceph-deploy

在master1-admin节点安装ceph-deploy

[root@master1-admin ~]# yum install python-setuptools  ceph-deploy -y

在master1-admin、node1-monitor和node2-osd节点安装ceph

[root@master1-admin]#  yum install ceph ceph-radosgw  -y
[root@node1-monitor ~]# yum install ceph ceph-radosgw  -y
[root@node2-osd ~]# yum install ceph ceph-radosgw  -y
root@master1-admin ~]# ceph --version
ceph version 10.2.11 (e4b061b47f07f583c92a050d9e84b1813a35671e)
2.2 创建monitor节点

创建一个目录,用于保存 ceph-deploy 生成的配置文件信息的

[root@master1-admin ceph ~]# cd /etc/ceph
[root@master1-admin ceph]# ceph-deploy new master1-admin node1-monitor node2-osd
[root@master1-admin ceph]# ls

#生成了如下配置文件

ceph.conf  ceph-deploy-ceph.log  ceph.mon.keyring 

Ceph配置文件、一个monitor密钥环和一个日志文件

2.3 安装ceph-monitor

1、修改ceph配置文件
#把ceph.conf配置文件里的默认副本数从3改成1 。把osd_pool_default_size = 2
加入[global]段,这样只有2个osd也能达到active+clean状态:

[root@master1-admin ceph]# cat ceph.conf 
[global]
fsid = 6300ffea-4e1d-4f19-ad27-935894f2d6ee
mon_initial_members = node1-monitor
mon_host = 192.168.75.161
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
filestore_xattr_use_omap = true
osd_pool_default_size = 2
mon clock drift allowed = 0.500
mon clock drift warn backoff = 10

mon clock drift allowed #监视器间允许的时钟漂移量默认值0.05
mon clock drift warn backoff #时钟偏移警告的退避指数。默认值5

ceph对每个mon之间的时间同步延时默认要求在0.05s之间,这个时间有的时候太短了。所以如果ceph集群如果出现clock问题就检查ntp时间同步或者适当放宽这个误差时间。

cephx是认证机制是整个 Ceph 系统的用户名/密码

2、配置初始monitor、收集所有的密钥

[root@master1-admin]# cd /etc/ceph
[root@master1-admin]# ceph-deploy mon create-initial
[root@master1-admin]# ls *.keyring
ceph.bootstrap-mds.keyring  ceph.bootstrap-mgr.keyring  ceph.bootstrap-osd.keyring  ceph.bootstrap-rgw.keyring  ceph.client.admin.keyring  ceph.mon.keyring
2.4 部署osd服务

准备osd

[root@ master1-admin ceph]# cd /etc/ceph/
[root@master1-admin ceph]# ceph-deploy osd prepare master1-admin:/dev/sdb [root@master1-admin ceph]# ceph-deploy osd prepare node1-monitor:/dev/sdb 
[root@master1-admin ceph]# ceph-deploy osd prepare node2-osd:/dev/sdb

激活osd

[root@master1-admin ceph]# ceph-deploy osd activate master1-admin:/dev/sdb1
[root@master1-admin ceph]# ceph-deploy osd activate node1-monitor:/dev/sdb1
[root@master1-admin ceph]# ceph-deploy osd activate node2-osd:/dev/sdb1

查看状态

[root@ master1-admin ceph]# ceph-deploy osd list master1-admin node1-monitor node2-osd

要使用Ceph文件系统,你的Ceph的存储集群里至少需要存在一个Ceph的元数据服务器(mds)。

2.5 创建ceph文件系统

创建mds

[root@ master1-admin ceph]# ceph-deploy mds create master1-admin node1-monitor node2-osd

查看ceph当前文件系统

[root@ master1-admin ceph]# ceph fs ls   	No filesystems enabled

一个cephfs至少要求两个librados存储池,一个为data,一个为metadata。当配置这两个存储池时,注意:

  1. 为metadata pool设置较高级别的副本级别,因为metadata的损坏可能导致整个文件系统不用
  2. 建议,metadata pool使用低延时存储,比如SSD,因为metadata会直接影响客户端的响应速度。

创建存储池

[root@ master1-admin ceph]# ceph osd pool create cephfs_data 128
pool 'cephfs_data' created
[root@ master1-admin ceph]# ceph osd pool create cephfs_metadata 128
pool 'cephfs_metadata' created

关于创建存储池
确定 pg_num 取值是强制性的,因为不能自动计算。下面是几个常用的值:
*少于 5 个 OSD 时可把 pg_num 设置为 128
*OSD 数量在 5 到 10 个时,可把 pg_num 设置为 512
*OSD 数量在 10 到 50 个时,可把 pg_num 设置为 4096
*OSD 数量大于 50 时,你得理解权衡方法、以及如何自己计算 pg_num 取值

*自己计算 pg_num 取值时可借助 pgcalc 工具
随着 OSD 数量的增加,正确的 pg_num 取值变得更加重要,因为它显著地影响着集群的行为、以及出错时的数据持久性(即灾难性事件导致数据丢失的概率)。

创建文件系统

创建好存储池后,你就可以用 fs new 命令创建文件系统了

[root@master1-admin ceph]# ceph fs new xianchao cephfs_metadata cephfs_data
new fs with metadata pool 2 and data pool 1

其中:new后的fsname 可自定义

[root@ master1-admin ceph]# ceph fs ls              #查看创建后的cephfs
[root@ master1-admin ceph]# ceph mds stat          #查看mds节点状态

xianchao:1 {0=master1-admin=up:active} 2 up:standby
active是活跃的,另1个是处于热备份的状态

[root@master1-admin ceph]# ceph -scluster 6300ffea-4e1d-4f19-ad27-935894f2d6eehealth HEALTH_OKmonmap e1: 1 mons at {node1-monitor=192.168.75.161:6789/0}election epoch 3, quorum 0 node1-monitorfsmap e6: 1/1/1 up {0=node2-osd=up:active}, 2 up:standbyosdmap e20: 3 osds: 3 up, 3 inflags sortbitwise,require_jewel_osdspgmap v46: 320 pgs, 3 pools, 2068 bytes data, 20 objects326 MB used, 15000 MB / 15326 MB avail320 active+clean

**HEALTH_OK表示ceph**集群正常

2.6 测试k8s挂载ceph rbd

需要有一套k8s环境

[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES                  AGE    VERSION
master   Ready    control-plane,master   117m   v1.23.1
node1    Ready    <none>                 116m   v1.23.1

master节点ip:192.168.75.140
node1节点ip:192.168.75.141

kubernetes要想使用ceph,需要在k8s的每个node节点安装ceph-common,把ceph节点上的ceph.repo文件拷贝到k8s各个节点/etc/yum.repos.d/目录下,然后在k8s的各个节点yum install ceph-common -y

[root@master1-admin ceph]# scp /etc/yum.repos.d/ceph.repo 192.168.75.140:/etc/yum.repos.d/
[root@master1-admin ceph]# scp /etc/yum.repos.d/ceph.repo 192.168.75.141:/etc/yum.repos.d/
[root@node1 ~]#  yum install ceph-common -y
[root@master ~]# yum install ceph-common -y

将ceph配置文件拷贝到k8s的控制节点和工作节点

[root@master1-admin ceph]# scp /etc/ceph/* 192.168.75.140:/etc/ceph/
[root@master1-admin ceph]# scp /etc/ceph/* 192.168.75.141:/etc/ceph/

创建ceph rbd

[root@master1-admin ~]# ceph osd pool create k8srbd1 6
pool 'k8srbd1' created
[root@master1-admin ~]# rbd create rbda -s 1024 -p k8srbd1
[root@master1-admin ~]# rbd feature disable  k8srbd1/rbda object-map fast-diff deep-flatten

创建pod,挂载ceph rbd

[root@master ceph]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: testrbd
spec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: testrbdmountPath: /mntvolumes:- name: testrbdrbd:monitors:- '192.168.75.160:6789'- '192.168.75.161:6789'- '192.168.75.162:6789'pool: k8srbd1image: rbdafsType: xfsreadOnly: falseuser: adminkeyring: /etc/ceph/ceph.client.admin.keyring
[root@master ceph]# kubectl apply -f pod.yaml 

查看pod是否创建成功

[root@master ceph]# kubectl get pod -owide
NAME      READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
testrbd   1/1     Running   0          43s   10.244.166.130   node1   <none>           <none>

注意: k8srbd1下的rbda被pod挂载了,那其他pod就不能占用这个k8srbd1下的rbda了

例:创建一个pod-1.yaml

[root@master ceph]# cat pod-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: testrbd1
spec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: testrbdmountPath: /mntvolumes:- name: testrbdrbd:monitors:- '192.168.75.160:6789'- '192.168.75.161:6789'- '192.168.75.162:6789'pool: k8srbd1image: rbdafsType: xfsreadOnly: falseuser: adminkeyring: /etc/ceph/ceph.client.admin.keyring
[root@master ceph]# kubectl apply -f pod-1.yaml 
[root@master ceph]# kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
testrbd    1/1     Running   0          4m41s
testrbd1   0/1     Pending   0          5s

查看testrbd1详细信息

[root@master ceph]# kubectl describe pods testrbd1
Events:Type     Reason            Age   From               Message----     ------            ----  ----               -------Warning  FailedScheduling  52s   default-scheduler  0/2 nodes are available: 1 node(s) had no available disk, 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.

上面一直pending状态,通过warnning可以发现是因为我的pool: k8srbd1 image: rbda,已经被其他pod占用了

2.7 基于ceph rbd生成pv

1、创建ceph-secret这个k8s secret对象,这个secret对象用于k8s volume插件访问ceph集群,获取client.admin的keyring值,并用base64编码,在master1-admin(ceph管理节点)操作

[root@master1-admin ~]# ceph auth get-key client.admin | base64
QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ==

2.创建ceph的secret,在k8s的控制节点操作

[root@master~]# cat ceph-secret.yaml 
apiVersion: v1
kind: Secret
metadata:name: ceph-secret
data:key: QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ==
[root@master~]# kubectl apply -f ceph-secret.yaml

3.回到ceph 管理节点创建pool池

[root@master1-admin ~]# ceph osd pool create k8stest 6
pool 'k8stest' created
[root@master1-admin ~]# rbd create rbda -s 1024 -p k8stest
[root@master1-admin ~]# rbd feature disable  k8stest/rbda object-map fast-diff deep-flatten

4、创建pv

[root@master~]# cat pv.yaml 
apiVersion: v1 
kind: PersistentVolume 
metadata: name: ceph-pv 
spec:   capacity:     storage: 1Gi   accessModes:     - ReadWriteOnce   rbd:     monitors:       - '192.168.75.160:6789'- '192.168.75.161:6789'- '192.168.75.162:6789'    pool: k8stest     image: rbda     user: admin     secretRef:       name: ceph-secret     fsType: xfs     readOnly: false   persistentVolumeReclaimPolicy: Recycle
[root@master~]# kubectl apply -f pv.yaml 
persistentvolume/ceph-pv created
[root@master~]# kubectl get pv

在这里插入图片描述
5、创建pvc

[root@master~]# cat pvc.yaml 
kind: PersistentVolumeClaim 
apiVersion: v1 
metadata:   name: ceph-pvc 
spec:   accessModes:     - ReadWriteOnce   resources:     requests:       storage: 1Gi
[root@master~]# kubectl apply -f pvc.yaml
[root@masterceph]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
ceph-pvc      Bound    ceph-pv                                    1Gi        RWO         

6、测试挂载pvc

[root@master~]# cat pod-2.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:selector:matchLabels:app: nginxreplicas: 2 # tells deployment to run 2 pods matching the templatetemplate: # create pods using pod definition in this templatemetadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80volumeMounts:- mountPath: "/ceph-data"name: ceph-datavolumes:- name: ceph-datapersistentVolumeClaim:claimName: ceph-pvc
[root@master~]# kubectl apply -f pod-2.yaml
[root@master~]# kubectl get pods -l app=nginx
NAME                                 READY   STATUS    RESTARTS   AGE
nginx-deployment-fc894c564-8tfhn    1/1      Running   0             78s
nginx-deployment-fc894c564-l74km    1/1     Running   0             78s
[root@master~]# cat pod-3.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-1-deployment
spec:selector:matchLabels:appv1: nginxv1replicas: 2 # tells deployment to run 2 pods matching the templatetemplate: # create pods using pod definition in this templatemetadata:labels:appv1: nginxv1spec:containers:- name: nginximage: nginx
imagePullPolicy: IfNotPresentports:- containerPort: 80volumeMounts:- mountPath: "/ceph-data"name: ceph-datavolumes:- name: ceph-datapersistentVolumeClaim:claimName: ceph-pvc
[root@master~]# kubectl apply -f pod-3.yaml
[root@master~]# kubectl get pods -l appv1=nginxv1
NAME                                 READY   STATUS    RESTARTS   AGE
nginx-1-deployment-cd74b5dd4-jqvxj   1/1     Running   0          56s
nginx-1-deployment-cd74b5dd4-lrddc   1/1     Running   0          56s

通过上面实验可以发现pod是可以以ReadWriteOnce共享挂载相同的pvc的

注意:ceph rbd块存储的特点
ceph rbd块存储能在同一个node上跨pod以ReadWriteOnce共享挂载
ceph rbd块存储能在同一个node上同一个pod多个容器中以ReadWriteOnce共享挂载
ceph rbd块存储不能跨node以ReadWriteOnce共享挂载
如果一个使用ceph rdb的pod所在的node挂掉,这个pod虽然会被调度到其它node,但是由于rbd不能跨node多次挂载和挂掉的pod不能自动解绑pv的问题,这个新pod不会正常运行

Deployment更新特性:
deployment触发更新的时候,它确保至少所需 Pods 75% 处于运行状态(最大不可用比例为 25%)。故像一个pod的情况,肯定是新创建一个新的pod,新pod运行正常之后,再关闭老的pod。
默认情况下,它可确保启动的 Pod 个数比期望个数最多多出 25%

问题
结合ceph rbd共享挂载的特性和deployment更新的特性,我们发现原因如下:
由于deployment触发更新,为了保证服务的可用性,deployment要先创建一个pod并运行正常之后,再去删除老pod。而如果新创建的pod和老pod不在一个node,就会导致此故障。

解决办法
1,使用能支持跨node和pod之间挂载的共享存储,例如cephfs,GlusterFS等
2,给node添加label,只允许deployment所管理的pod调度到一个固定的node上。(不建议,这个node挂掉的话,服务就故障了)

2.8 基于storageclass动态生成pv
[root@master1-admin]# chmod 777  -R  /etc/ceph/*
[root@node1-monitor ~]# chmod 777  -R  /etc/ceph/*
[root@node2-osd]# chmod 777  -R  /etc/ceph/*
[root@master~]# chmod 777  -R  /etc/ceph/*
[root@master]# chmod 777  -R  /etc/ceph/*
[root@master1-admin]# mkdir /root/.ceph/
[root@master1-admin]# cp -ar /etc/ceph/ /root/.ceph/
[root@node1-monitor ~]#mkdir /root/.ceph/
[root@node1-monitor ~]#cp -ar /etc/ceph/ /root/.ceph/
[root@node2-osd]# mkdir /root/.ceph/
[root@node2-osd]# cp -ar /etc/ceph/ /root/.ceph/
[root@master~]#mkdir /root/.ceph/
[root@master~]#cp -ar /etc/ceph/ /root/.ceph/
[root@node1]# mkdir /root/.ceph/
[root@node1~]#cp -ar /etc/ceph/ /root/.ceph/

1、创建rbd的供应商provisioner

[root@master~]# cat rbd-provisioner.yaml 
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: rbd-provisioner
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"]- apiGroups: [""]resources: ["services"]resourceNames: ["kube-dns","coredns"]verbs: ["list", "get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: rbd-provisioner
subjects:- kind: ServiceAccountname: rbd-provisionernamespace: default
roleRef:kind: ClusterRolename: rbd-provisionerapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: rbd-provisioner
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get"]
- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: rbd-provisioner
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: rbd-provisioner
subjects:
- kind: ServiceAccountname: rbd-provisionernamespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:name: rbd-provisioner
spec:selector:matchLabels:app: rbd-provisionerreplicas: 1strategy:type: Recreatetemplate:metadata:labels:app: rbd-provisionerspec:containers:- name: rbd-provisionerimage: quay.io/xianchao/external_storage/rbd-provisioner:v1imagePullPolicy: IfNotPresentenv:- name: PROVISIONER_NAMEvalue: ceph.com/rbdserviceAccount: rbd-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:name: rbd-provisioner
[root@master~]# kubectl apply -f rbd-provisioner.yaml
[root@master~]# kubectl get pods -l app=rbd-provisioner
NAME                               READY   STATUS    RESTARTS   AGE
rbd-provisioner-685746688f-8mbz5   1/1     Running   0          111s

2、创建ceph-secret
创建pool池

[root@master1-admin ~]# ceph osd pool create k8stest1 6
[root@master~]# cat ceph-secret-1.yaml 
apiVersion: v1
kind: Secret
metadata:name: ceph-secret-1
type: "ceph.com/rbd"
data:key: QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ==[root@master~]# kubectl apply -f ceph-secret-1.yaml

3、创建storageclass

[root@master~]# cat storageclass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: k8s-rbd
provisioner: ceph.com/rbd
parameters:monitors: 192.168.75.161:6789adminId: adminadminSecretName: ceph-secret-1pool: k8stest1userId: adminuserSecretName: ceph-secret-1fsType: xfsimageFormat: "2"imageFeatures: "layering"[root@master~]# kubectl apply -f storageclass.yaml

注意:
k8s1.20版本通过rbd provisioner动态生成pv会报错:
[root@xianchaomaster1 ~]# kubectl logs rbd-provisioner-685746688f-8mbz
E0418 15:50:09.610071 1 controller.go:1004] provision “default/rbd-pvc” class “k8s-rbd”: unexpected error getting claim reference: selfLink was empty, can’t make reference,报错原因是1.20版本仅用了selfLink,解决方法如下;
编辑/etc/kubernetes/manifests/kube-apiserver.yaml
在这里:

spec:containers:- command:- kube-apiserver

添加这一行:
—feature-gates=RemoveSelfLink=false
在这里插入图片描述

[root@master~]# systemctl restart kubelet
[root@master~]# kubectl get pods -n kube-system
NAME                                       READY   STATUS             RESTARTS   AGE        
kube-apiserver-master                 1/1     Running                 

4、创建pvc

[root@master~]# cat rbd-pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: rbd-pvc
spec:accessModes:- ReadWriteOncevolumeMode: Filesystemresources:requests:storage: 1GistorageClassName: k8s-rbd
[root@xianchaomaster1 ~]# kubectl apply -f rbd-pvc.yaml
[root@xianchaomaster1 ~]# kubectl get pvc

创建pod,挂载pvc

[root@master~]# cat pod-sto.yaml 
apiVersion: v1
kind: Pod
metadata:labels:test: rbd-podname: ceph-rbd-pod
spec:containers:- name: ceph-rbd-nginximage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: ceph-rbdmountPath: /mntreadOnly: falsevolumes:- name: ceph-rbdpersistentVolumeClaim:claimName: rbd-pvc
[root@xianchaomaster1 ~]# kubectl apply -f pod-sto.yaml
[root@xianchaomaster1 ~]# kubectl get pods -l test=rbd-pod
NAME           READY   STATUS    RESTARTS   AGE
ceph-rbd-pod   1/1     Running   0          50s
2.9 k8s挂载cephfs
[root@master1-admin ~]# ceph fs ls
name: xianchao, metadata pool: cephfs_metadata, data pools: [cephfs_data ]

1、创建ceph子目录

为了别的地方能挂载cephfs,先创建一个secretfile

[root@master1-admin ~]# cat /etc/ceph/ceph.client.admin.keyring |grep key|awk -F" " '{print $3}' > /etc/ceph/admin.secret

挂载cephfs的根目录到集群的mon节点下的一个目录,比如xianchao_data,因为挂载后,我们就可以直接在xianchao_data下面用Linux命令创建子目录了。

[root@master1-admin ~]# mkdir ceph_data
[root@master1-admin ~]# mount -t ceph 192.168.75.161:6789:/ /root/ceph_data-o name=admin,secretfile=/etc/ceph/admin.secret[root@master1-admin ~]# df -h
192.168.40.201:6789:/    165G  106M  165G   1% /root/xianchao_data

在cephfs的根目录里面创建了一个子目录lucky,k8s以后就可以挂载这个目录

[root@master1-admin ~]# cd /root/ceph_data/
[root@master1-admin ceph_data]# mkdir data
[root@master1-admin ceph_data]# chmod 0777 data/

2、测试k8s的pod挂载cephfs

1)创建k8s连接ceph使用的secret

将/etc/ceph/ceph.client.admin.keyring里面的key的值转换为base64,否则会有问题

[root@master1-admin ceph_data]# echo "AQB/XudjVvj9BBAASX0b1EBKRrXc7tAOYAi0qQ==" | base64
QVFCL1h1ZGpWdmo5QkJBQVNYMGIxRUJLUnJYYzd0QU9ZQWkwcVE9PQo=
[root@master ceph]# cat cephfs-secret.yaml 
apiVersion: v1
kind: Secret
metadata:name: cephfs-secret
data:key: QVFCL1h1ZGpWdmo5QkJBQVNYMGIxRUJLUnJYYzd0QU9ZQWkwcVE9PQo=
[root@master ceph]# kubectl apply -f cephfs-secret.yaml
[root@master ceph]# cat cephfs-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:name: cephfs-pv
spec:capacity:storage: 1GiaccessModes:- ReadWriteManycephfs:monitors:- 192.168.75.161:6789path: /datauser: adminreadOnly: falsesecretRef:name: cephfs-secretpersistentVolumeReclaimPolicy: Recycle
[root@master ceph]# kubectl apply -f cephfs-pv.yaml
[root@master ceph]# cat cephfs-pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: cephfs-pvc
spec:accessModes:- ReadWriteManyvolumeName: cephfs-pvresources:requests:storage: 1Gi
[root@master ceph]# kubectl apply -f cephfs-pvc.yaml
[root@master ceph]# kubectl get pvc
NAME          STATUS   VOLUME                             CAPACITY   cephfs-pvc    Bound    cephfs-pv                        1Gi        RWX    

创建第一个pod,挂载cephfs-pvc

[root@master ceph]# cat cephfs-pod-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: cephfs-pod-1
spec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: test-v1mountPath: /mntvolumes:- name: test-v1persistentVolumeClaim:claimName: cephfs-pvc

创建第二个pod,挂载cephfs-pvc

[root@master ceph]# cat cephfs-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:name: cephfs-pod-2
spec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: test-v1mountPath: /mntvolumes:- name: test-v1persistentVolumeClaim:claimName: cephfs-pvc
[root@master ceph]# kubectl exec -it cephfs-pod-1 -- /bin/bash
root@cephfs-pod-1:/mnt# touch cephfs-1[root@master ceph]# kubectl exec -it cephfs-pod-2 -- /bin/bash
root@cephfs-pod-1:/mnt# touch cephfs-2

在这里插入图片描述
回到master1-admin上,可以看到在cephfs文件目录下已经存在内容了

相关文章:

基于云原生分布式存储ceph实现k8s数据持久化

文章目录1、初始化集群1.1 集群机器配置1.2 配置主机名1.3 配置hosts文件1.4、配置互信1.5、关闭防火墙1.6、关闭selinux1.7、配置Ceph安装源1.8、配置时间同步1.9、安装基础软件包2、安装ceph集群2.1 安装ceph-deploy2.2 创建monitor节点2.3 安装ceph-monitor2.4 部署osd服务2…...

SpringMVC获取请求参数

SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的报文对象。 RequestMapping("/testServletAPI") // request表示当前请求 public String testServletAPI(H…...

详解浏览器从输入URL到页面展示的过程

用户发出 URL 请求到页面开始解析的这个过程&#xff0c;就叫做导航。 1. 用户输入 当用户在地址栏中输入一个查询关键字时&#xff0c;地址栏会判断输入的关键字是搜索内容&#xff0c;还是请求的 URL。 当用户输入关键字并键入回车之后&#xff0c;这意味着当前页面即将要…...

【吉先生的Java全栈之路】

吉士先生Java全栈学习路线&#x1f9e1;第一阶段Java基础: 在第一阶段:我们要认真听讲,因为基础很重要!基础很重要!基础很重要!!! 重要的事情说三遍。在这里我们先学JavaSE路线&#xff1b;学完之后我们要去学第一个可视化组件编程《GUI》&#xff1b;然后写个《贪吃蛇》游戏耍…...

第二章 Opencv图像处理基本操作

目录1.读取图像1-1.imread()方法2.显示图像2-1.imshow()方法2-2.waitKey()方法2-3.destroyAllWindows()方法2-4.小总结3.保存图像3-1.imwrite()方法4.查看图像属性4-1.常见的三个图像属性1.读取图像 要对一幅图像进行处理&#xff0c;第一件事就是要读取这幅图像。 1-1.imread(…...

字节一面:在浏览器地址栏输入一个 URL 后回车,背后发生了什么?

近段时间&#xff0c;有小伙伴面试字节&#xff0c;说遇到一个面试题&#xff1a; 在浏览器地址栏输入一个 URL 后回车&#xff0c;背后发生了什么&#xff1f; 这里尼恩给大家做一下系统化、体系化的梳理&#xff0c;使得大家可以充分展示一下大家雄厚的 “技术肌肉”&#xf…...

推荐3dMax三维设计十大插件

3dMax是一款功能非常强大的三维设计软件&#xff0c;但无论它的功能多么强大&#xff0c;也不可能包含所有三维方面的功能&#xff0c;这时候&#xff0c;第三方插件可以很好的弥补和增强3dMax的基本功能&#xff0c;下面就给大家介绍十款非常不错的3dMax插件。 森林包&#xf…...

Arduino IDE 2.0.6中 ESP32开发环境搭建笔记

Arduino IDE 2.0.6中 ESP32开发环境搭建 Arduino IDE2.0 已上线一段时间&#xff0c;以后ESP32的学习转至新的IDE中 &#xff0c;需对开发环境进行。 Arduino IDE&#xff12;.&#xff10;与&#xff11;.&#xff10;有很大差异。原来环境搭建方法已完全不同。下文主要记录环…...

商品秒杀接口压测及优化

目录一、生成测试用户二、jmeter压测三、秒杀接口优化1、优化第一步&#xff1a;解决超卖2、优化第二步&#xff1a;Redis重复抢购3、优化第三步&#xff1a;Redis预减库存①商品初始化②预减库存一、生成测试用户 将UserUtils工具类导入到zmall-user模块中&#xff0c;运行生…...

NFC 项目前期准备工作

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 了解项目信息,FAE联系方式,驱动源码等驱动合入内核配置DTS驱动设备节点验证Push nf…...

(C语言)数据的存储

问&#xff1a;1. 数据类型有哪五大类&#xff1f;2. 数据类型的作用是什么与什么&#xff1f;3. 整型又可以具体分为哪五个&#xff1f;为什么字符char也归属于整型&#xff1f;4. 浮点型又可以具体分为哪两类&#xff1f;5. 构造类型就是什么&#xff1f;具体分为哪四类&…...

C语言深度剖析之文件操作

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注加关注 &#x1f31e; 什么是文件 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文…...

RNN神经网络初探

目录1. 神经网络与未来智能2. 回顾数据维度和神经网络1. 神经网络与未来智能 2. 回顾数据维度和神经网络 循环神经网络&#xff0c;主要用来处理时序的数据&#xff0c;它对每个词的顺序是有要求的。 循环神经网络如何保存记忆功能&#xff1f; 当前样本只有 3 个特征&#x…...

【flinkx】【hdfs】【ing】Cannot obtain block length for LocatedBlock

一. 任务描述 使用flinkx去跑HDFS到HIVE的任务时&#xff0c;出现如下报错&#xff1a; CannotObtainBlockLengthException com.dtstack.flinkx.throwable.FlinkxRuntimeException: cant get file size from hdfs, file hdfs://xxx/.data/540240453caeb6fe4b3f118410a05315_2…...

【Day6】合并两个排序链表与合并k个已排序的链表,java代码实现

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1f680;&#x1f680;&#x1f680;&#xff0c;今天与大家一起做两道牛客网的链表题&#xff0c;好久写关于链表题的博客了&#xff0c;这两道题可以帮大家巩固一下链表知识&#xff0c;我把两道题的链接放到下面&#xf…...

Swagger PHP

PHP使用Swagger生成好看的API文档不是不可能&#xff0c;而是非常简单。首先本人使用Laravel框架&#xff0c;所以在Laravel上安装swagger-php。一、安装swagger - phpcomposer require zircote/swagger-phpswagger-php提供了命令行工具&#xff0c;所以可以全局安装&#xff0…...

谷粒商城-品牌管理-JSR303数据校验

后端在处理前端传过来的数据时&#xff0c;尽管前端表单已经加了校验逻辑&#xff0c;但是作为严谨考虑&#xff0c;在后端对接口传输的数据做校验也必不可少。 开启校验&#xff1a; 实体类上增加校验注解&#xff0c;接口参数前增加Valid 开启校验 package com.xxh.product.…...

Java零基础教程——数组

目录数组静态初始化数组数组的访问数组的动态初始化元素默认值规则&#xff1a;数组的遍历数组遍历-求和冒泡排序数组的逆序交换数组 数组就是用来存储一批同种类型数据的容器。 20, 10, 80, 60, 90 int[] arr {20, 10, 80, 60, 90}; //位置 0 1 2 3 4数组的…...

AirServer在哪下载?如何免费使用教程

苹果手机投屏到电脑mac是怎么弄&#xff1f;你知道多少&#xff1f;相信大家对苹果手机投屏到电脑mac能在电脑上操作不是很了解&#xff0c;下面就让coco玛奇朵带大家一起了解一下教程。AIrServer是一款ios投屏到mac的专用软件&#xff0c;可将iOS上的音频&#xff0c;视频&…...

加载sklearn covtype数据集出错 fetch_covtype() HTTPError: HTTP Error 403: Forbidden解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

理论六:为什么基于接口而非实现编程?有必要为每个类定义接口么?

在上一节课中、我们讲了接口和抽象类&#xff0c;以及各种编程语言是如何支持、实现这两个语法概念的。今天&#xff0c;我们继续讲一个跟“接口”相知识点:基于接口而非实现编程。这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。为了让你…...

(HP)react日常开发技巧

高级特性 1&#xff0c;protals&#xff08;传送门&#xff09;&#xff1a;将子组件渲染到父组件之外。 实例场景&#xff1a;父组件的儿子是<Modal>组件&#xff0c;使用fixed定位虽然样式看着是在父组件之外了&#xff0c;但是打开控制台查看元素&#xff0c;Modal相…...

【20230211】【剑指1】搜索与回溯算法II

树的子结构递归思维&#xff1a;对称性递归什么是对称性递归&#xff1f;就是对一个对称的数据结构&#xff08;这里指二叉树&#xff09;从整体的对称性思考&#xff0c;把大问题分解成子问题进行递归&#xff0c;即不是单独考虑一部分(比如树的左子树)&#xff0c;而是同时考…...

STM32F103C8T6—库函数应用I2C/SPI驱动OLED显示中文、字符串

文章目录1. I2C与SPI通信协议对比2. 四脚OLED与六脚OLED3. I2C驱动OLED显示oled.h & oled.c&#xff1a;汉字取模 & oledfont.h&#xff1a;main.c 显示示例&#xff1a;连线方法&#xff1a;4. SPI驱动OLED显示1. I2C与SPI通信协议对比 I2C&#xff08;Inter-Integra…...

sql语句要注意的地方及常用查询语句

sql要注意的地方关键字不能被缩写&#xff0c;也不能分行小写大写不敏感&#xff0c;没区别使用缩进提高语句的可读性常用查询语句1.查询所有库SHOW DATABASES;2.选择数据库 use 数据库名USE myemployees;3.查看数据库中所有表show tables4.查看表中的内容 select 字段一&#…...

数组去重、伪数组和真数组的区别以及伪数组如何转换成真数组

1.数组去重 1&#xff09; 利用数组的indexOf下标属性来查询。 如果找到一个 item&#xff0c;则返回 item 的第一次出现的位置。开始位置的索引为 0。 如果在数组中没找到指定元素则返回 -1。 function unique4(arr) {var newArr []for (var i 0; i < arr.length; i) {i…...

JavaScript内置支持类Array

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>内置支持类Array</title> </head> <body bgcolor"antiquewhite"> <script type"text/javasc…...

GitLab CI-CD 学习笔记

概述 1. CI/CD CI&#xff08;持续集成&#xff09;指开发人员一天内进行多次合并和提交代码操作&#xff0c;并通过自动化测试&#xff0c;完成构建 CD&#xff08;持续部署&#xff09;指每次代码更改都会自动部署到对应环境 CI/CD 结合在一起&#xff0c;可以加快开发团…...

K8S安装

1.创建三台centos虚拟机 使用的官方最小镜像安装 CentOS-7-x86_64-Minimal-1804.iso 建议最小硬件配置&#xff1a;2核CPU、2G内存、20G硬盘 master配置详情 node1和node2配置详情 三台虚拟机在安装centos的时候在网络IPV4指定DHCP,配置IPV4固定地址&#xff0c;保证可以访问…...

【C++】模板初阶STL简介

今天&#xff0c;你内卷了吗&#xff1f; 文章目录一、泛型编程二、函数模板&#xff08;显示实例化和隐式实例化&#xff09;1.函数模板格式2.单参数模板3.多参数模板4.模板参数的匹配原则三、类模板&#xff08;没有推演的时机&#xff0c;统一显示实例化&#xff09;1.类模…...

自学网站开发/娱乐热搜榜今日排名

3G标准并不中立的技术中立论 2000年&#xff0c;我国有自主知识产权的TD-SCDMA标准与欧洲的WCDMA标准、美国的CDMA2000标准共同被国际电信联盟接受为3G的国际标准。由于当时其他两大标准已经进入产品实质研发&#xff0c;而TD-SCDMA标准处于理论方案阶段&#xff0c;因而市场前…...

web网页是什么/广东seo推广贵不贵

介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还需要掌握identity server4的基本用法,关于identity server4因为涉及到两个协议Oath2.0和openid conn…...

怎么用dw制作网站/下载百度极速版免费安装

在我的一个网站上,我创建了一个表单,用于收集人员姓名,电子邮件和他们想法的描述.我将描述的字符限制为500个字符,因为我不想阅读,我想出了如何在用户输入他们想要的内容之前将文本显示在textarea中.目前用户必须自己删除“你的想法的描述”,但我想添加占位符类,当它们点击text…...

网站建设研究背景/行业网站

首先进入官网下载&#xff0c;进入如下页面&#xff0c;选择适合自身版本的 Linux 的.deb 版本下载&#xff0c;也可以直接使用我们提供好的安装包。 下载完成之后&#xff0c;拷贝到 ubuntu 上&#xff0c;如下图所示&#xff1a; 然后使用以下命令进行安装&#xff1a; sudo …...

门户网站开发需求/seo自学网app

通过手机物理返回键实现弹出层的隐藏 <template><div class"popup"><h1 click"popup">返回键隐藏弹出层</h1><div class"pop" :class"{up: flag}">弹出层文本<--点击关闭实现弹出层隐藏--><sp…...

个人响应式网站建设/厦门人才网官方网站

很不错的hash 优化有两个方面&#xff1a;1.根据题目换一个更优化的算法 2.在算法运行过程中优化 这题除了暴力好像没别的办法了吧&#xff1f; 但是暴力也是有策略的&#xff01; 到第i只牛特征为j的总数为sum[i,j]; 找到最大的区间(l,r]使得sum[r,1]-sum[l,1]sum[r,2]-sum[l,…...