k8s对接ceph

1、ceph简介

ceph是一种开源的分布式的存储系统

包含以下几种存储类型:

块存储(rbd),对象存储(RADOS Fateway),文件系统(cephfs)

1
2
3
4
官方:
https://ceph.com/en/

https://docs.ceph.com/en/latest/start/intro/

1.1 块存储(rbd)

块是一个字节序列(例如,512字节的数据块)。 基于块的存储接口是使用旋转介质(如硬盘,CD,软盘甚至传统的9轨磁带)存储数据的最常用方法;Ceph块设备是精简配置,可调整大小并存储在Ceph集群中多个OSD条带化的数据。 Ceph块设备利用RADOS功能,如快照,复制和一致性。 Ceph的RADOS块设备(RBD)使用内核模块或librbd库与OSD进行交互;Ceph的块设备为内核模块或QVM等KVM以及依赖libvirt和QEMU与Ceph块设备集成的OpenStack和CloudStack等基于云的计算系统提供高性能和无限可扩展性。 可以使用同一个集群同时运行Ceph RADOS Gateway,CephFS文件系统和Ceph块设备。

linux系统中,ls /dev/下有很多块设备文件,这些文件就是我们添加硬盘时识别出来的;

rbd就是由Ceph集群提供出来的块设备。可以这样理解,sda是通过数据线连接到了真实的硬盘,而rbd是通过网络连接到了Ceph集群中的一块存储区域,往rbd设备文件写入数据,最终会被存储到Ceph集群的这块区域中;

总结:块设备可理解成一块硬盘,用户可以直接使用不含文件系统的块设备,也可以将其格式化成特定的文件系统,由文件系统来组织管理存储空间,从而为用户提供丰富而友好的数据操作支持。

1.2 文件系统(cephfs)

Ceph文件系统(CephFS)是一个符合POSIX标准的文件系统,它使用Ceph存储集群来存储其数据。 Ceph文件系统使用与Ceph块设备相同的Ceph存储集群系统。

用户可以在块设备上创建xfs文件系统,也可以创建ext4等其他文件系统,Ceph集群实现了自己的文件系统来组织管理集群的存储空间,用户可以直接将Ceph集群的文件系统挂载到用户机上使用,Ceph有了块设备接口,在块设备上完全可以构建一个文件系统,那么Ceph为什么还需要文件系统接口呢?

主要是因为应用场景的不同,Ceph的块设备具有优异的读写性能,但不能多处挂载同时读写,目前主要用在OpenStack上作为虚拟磁盘,而Ceph的文件系统接口读写性能较块设备接口差,但具有优异的共享性。

1.3 对象存储

Ceph对象存储使用Ceph对象网关守护进程(radosgw),它是一个用于与Ceph存储集群交互的HTTP服务器。由于它提供与OpenStack Swift和Amazon S3兼容的接口,因此Ceph对象网关具有自己的用户管理。 Ceph对象网关可以将数据存储在用于存储来自Ceph文件系统客户端或Ceph块设备客户端的数据的相同Ceph存储集群中

使用方式就是通过http协议上传下载删除对象(文件即对象)。

老问题来了,有了块设备接口存储和文件系统接口存储,为什么还整个对象存储呢?

Ceph的块设备存储具有优异的存储性能但不具有共享性,而Ceph的文件系统具有共享性然而性能较块设备存储差,为什么不权衡一下存储性能和共享性,整个具有共享性而存储性能好于文件系统存储的存储呢,对象存储就这样出现了。

分布式存储的优点:

高可靠:既满足存储读取不丢失,还要保证数据长期存储。 在保证部分硬件损坏后依然可以保证数据安全

高性能:读写速度快

可扩展:分布式存储的优势就是“分布式”,所谓的“分布式”就是能够将多个物理节点整合在一起形成共享的存储池,节点可以线性扩充,这样可以源源不断的通过扩充节点提升性能和扩大容量,这是传统存储阵列无法做到的

2、ceph核心组件

在ceph集群中,不管你是想要提供对象存储,块设备存储,还是文件系统存储,所有Ceph存储集群部署都是从设置每个Ceph节点,网络和Ceph存储开始 的。 Ceph存储集群至少需要一个Ceph Monitor,Ceph Manager和Ceph OSD(对象存储守护进程)。 运行Ceph Filesystem客户端时也需要Ceph元数据服务器。

Monitors:Ceph监视器(ceph-mon)维护集群状态的映射,包括监视器映射,管理器映射,OSD映射和CRUSH映射。这些映射是Ceph守护进程相互协调所需的关键集群状态。监视器还负责管理守护进程和客户端之间的身份验证。冗余和高可用性通常至少需要三个监视器。

Managers:Ceph Manager守护程序(ceph-mgr)负责跟踪运行时指标和Ceph集群的当前状态,包括存储利用率,当前性能指标和系统负载。 Ceph Manager守护进程还托管基于python的模块来管理和公开Ceph集群信息,包括基于Web的Ceph Dashboard和REST API。高可用性通常至少需要两名Managers。

Ceph OSD:Ceph OSD(对象存储守护进程,ceph-osd)存储数据,处理数据复制,恢复,重新平衡,并通过检查其他Ceph OSD守护进程来获取心跳,为Ceph监视器和管理器提供一些监视信息。冗余和高可用性通常至少需要3个Ceph OSD。

MDS:Ceph元数据服务器(MDS,ceph-mds)代表Ceph文件系统存储元数据(即,Ceph块设备和Ceph对象存储不使用MDS)。 Ceph元数据服务器允许POSIX文件系统用户执行基本命令(如ls,find等),而不会给Ceph存储集群带来巨大负担。

3、安装ceph集群

3.1 规划

image-20221024095510570

3.2 初始化环境

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
#修改hosts文件
cat > /etc/hosts<<END
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.106.30 master1-admin
192.168.106.31 node1-monitor
192.168.106.32 node2-osd
END


#免密登录
ssh-keygen
ssh-copy-id master1-admin
ssh-copy-id node1-monitor
ssh-copy-id node2-osd


#关闭防火墙、selinux,优化ssh
systemctl disable firewalld --now
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
sed -i "s/^#ClientAliveInterval.*/ClientAliveInterval 600/" /etc/ssh/sshd_config
sed -i "s/^#ClientAliveCountMax.*/ClientAliveCountMax 10/" /etc/ssh/sshd_config
systemctl restart sshd


#配置时间同步
yum install chrony -y
sed -i 's/^server.*//' /etc/chrony.conf
sed -i 's/# Please.*/server ntp.aliyun.com iburst/' /etc/chrony.conf
systemctl enable chronyd --now


#安装基础软件包
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 vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack ntpdate telnet ipvsadm bash-completion rsync

3.3 配置ceph安装源

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
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*


cat >/etc/yum.repos.d/ceph.repo<<END
[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
END

3.4 安装ceph-deploy

在master1-admin节点安装ceph-deploy

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

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

1
2
3
[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

3.5 创建monitor节点

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

1
2
3
4
5
6
7
8
9
[root@master1-admin ceph]# ceph-deploy new master1-admin node1-monitor node2-osd

#Ceph配置文件、一个monitor密钥环和一个日志文件
[root@master1-admin ceph]# ls -l
total 24
-rw-r--r--. 1 root root 261 Oct 24 16:36 ceph.conf
-rw-r--r--. 1 root root 9876 Oct 24 16:36 ceph-deploy-ceph.log
-rw-------. 1 root root 73 Oct 24 16:36 ceph.mon.keyring
-rw-r--r--. 1 root root 92 Jul 10 2018 rbdmap

3.6 安装ceph-monitor

3.6.1 修改ceph.conf配置文件

mon clock drift allowed :监视器间允许的时钟漂移量默认值0.05

mon clock drift warn backoff :时钟偏移警告的退避指数。默认值5

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

1
2
3
4
5
6
7
8
9
10
11
[root@master1-admin ceph]# cat /etc/ceph/ceph.conf 
[global]
fsid = 9d9ebba3-7e0e-4153-b7d2-dcd4f0ffdc7e
mon_initial_members = master1-admin, node1-monitor, node2-osd
mon_host = 192.168.106.30,192.168.106.31,192.168.106.32
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
osd_pool_default_size = 2
mon clock drift allowed = 0.500
mon clock drift warn backoff = 10

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

1
2
3
4
5
6
7
8
9
10
11
[root@master1-admin ~]# cd /etc/ceph/
[root@master1-admin ceph]# ceph-deploy mon create-initial


[root@master1-admin ceph]# ls -l *.keyring
-rw-------. 1 root root 113 Oct 24 16:54 ceph.bootstrap-mds.keyring
-rw-------. 1 root root 71 Oct 24 16:54 ceph.bootstrap-mgr.keyring
-rw-------. 1 root root 113 Oct 24 16:54 ceph.bootstrap-osd.keyring
-rw-------. 1 root root 113 Oct 24 16:54 ceph.bootstrap-rgw.keyring
-rw-------. 1 ceph ceph 129 Oct 24 16:54 ceph.client.admin.keyring
-rw-------. 1 root root 73 Oct 24 16:36 ceph.mon.keyring

3.7 部署osd服务

3.7.1 准备osd

1
2
3
4
[root@master1-admin ~]# 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

3.7.2 激活osd

1
2
3
4
[root@master1-admin ~]# cd /etc/ceph/
[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

3.7.3 查看状态

1
2
[root@master1-admin ~]# cd /etc/ceph/
[root@master1-admin ceph]# ceph-deploy osd list master1-admin node1-monitor node2-osd

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

3.8 创建ceph文件系统

3.8.1 创建mds

1
2
[root@master1-admin ~]# cd /etc/ceph/
[root@master1-admin ceph]# ceph-deploy mds create master1-admin node1-monitor node2-osd

3.8.2 查看ceph当前文件系统

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

  1. 为metadata pool设置较高级别的副本级别,因为metadata的损坏可能导致整个文件系统不用

  2. 建议,metadata pool使用低延时存储,比如SSD,因为metadata会直接影响客户端的响应速度。

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

3.8.3 创建存储池

关于创建存储池

确定 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 取值变得更加重要,因为它显著地影响着集群的行为、以及出错时的数据持久性(即灾难性事件导致数据丢失的概率)。

1
2
3
4
5
[root@master1-admin ~]# cd /etc/ceph/
[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

3.8.4 创建文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@master1-admin ceph]# ceph fs new zy cephfs_metadata cephfs_data 
new fs with metadata pool 2 and data pool 1


[root@master1-admin ceph]# ceph fs ls
name: zy, metadata pool: cephfs_metadata, data pools: [cephfs_data ]


[root@master1-admin ceph]# ceph mds stat
e6: 1/1/1 up {0=node2-osd=up:active}, 2 up:standby


[root@master1-admin ceph]# ceph -s
cluster 9d9ebba3-7e0e-4153-b7d2-dcd4f0ffdc7e
health HEALTH_OK
monmap e1: 3 mons at {master1-admin=192.168.106.30:6789/0,node1-monitor=192.168.106.31:6789/0,node2-osd=192.168.106.32:6789/0}
election epoch 6, quorum 0,1,2 master1-admin,node1-monitor,node2-osd
fsmap e6: 1/1/1 up {0=node2-osd=up:active}, 2 up:standby
osdmap e20: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v49: 320 pgs, 3 pools, 2068 bytes data, 20 objects
326 MB used, 1483 GB / 1484 GB avail
320 active+clean

3.9 测试k8s挂载ceph rbd

3.9.1 安装软件

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

1
yum install ceph-common -y

3.9.2 将ceph的配置拷贝到k8s集群的各个节点

1
2
3
4
5
6
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.11:/etc/ceph/
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.12:/etc/ceph/
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.13:/etc/ceph/
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.21:/etc/ceph/
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.22:/etc/ceph/
[root@master1-admin ~]# scp /etc/ceph/* 192.168.106.23:/etc/ceph/

3.9.3 创建ceph rbd

1
2
3
4
5
6
7
8
9
10
[root@master1-admin ~]# ceph osd pool create k8srbd1 6
pool 'k8srbd1' created


#创建rbda块设备
[root@master1-admin ~]# rbd create rbda -s 1024 -p k8srbd1


#禁用掉一些ceph特性
[root@master1-admin ~]# rbd feature disable k8srbd1/rbda object-map fast-diff deep-flatten

3.9.4 测试nginx镜像挂载ceph rbda块设备

当一个pod使用此rbda块设备时,其他容器想要挂载是不能成功挂载的,此方式生成块设备用的不多,但是需要了解。

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
[root@master1 k8s-ceph]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
name: testrbd
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: testrbd
mountPath: /mnt
volumes:
- name: testrbd
rbd:
monitors:
- '192.168.106.30:6789'
- '192.168.106.31:6789'
- '192.168.106.32:6789'
pool: k8srbd1
image: rbda
fsType: xfs
readOnly: false
user: admin
keyring: /etc/ceph/ceph.client.admin.keyring


[root@master1 k8s-ceph]# kubectl get pods
NAME READY STATUS RESTARTS AGE
testrbd 1/1 Running 0 4m48s

3.10 基于ceph rbd生成pv

3.10.1 获取client.admin的keyring值

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

1
2
[root@master1-admin ceph]# ceph auth get-key client.admin | base64
QVFEY1VsWmpGM0h6S2hBQXlnc1k4a0F3eVMxOXJzVjhPaHFEaGc9PQ==

3.10.2 创建ceph的secret,在k8s的控制节点进行操作

1
2
3
4
5
6
7
8
9
10
11
[root@master1 k8s-ceph]# cat ceph_secret.yaml 
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
data:
key: QVFEY1VsWmpGM0h6S2hBQXlnc1k4a0F3eVMxOXJzVjhPaHFEaGc9PQ==


[root@master1 k8s-ceph]# kubectl apply -f ceph_secret.yaml
secret/ceph-secret created

3.10.3 回到ceph管理节点创建pool池

1
2
3
4
5
6
[root@master1-admin ceph]# ceph osd pool create k8stest 6
pool 'k8stest' created


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

3.10.4 到k8s控制节点创建pv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@master1 k8s-ceph]# cat ceph_pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
name: ceph-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
rbd:
monitors:
- '192.168.106.30:6789'
- '192.168.106.31:6789'
- '192.168.106.32:6789'
pool: k8stest
image: rbda
fsType: xfs
secretRef:
name: ceph-secret
readOnly: false
user: admin
persistentVolumeReclaimPolicy: Recycle

3.10.5 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@master1 k8s-ceph]# cat ceph_pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: ceph-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi


[root@master1 k8s-ceph]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ceph-pvc Bound ceph-pv 1Gi RWO 11m

3.10.6 测试挂载pvc

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
[root@master1 k8s-ceph]# cat pod-2.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/ceph-data"
name: ceph-data
volumes:
- name: ceph-data
persistentVolumeClaim:
claimName: ceph-pvc


[root@master1 k8s-ceph]# kubectl apply -f pod-2.yaml
deployment.apps/nginx-deployment created

总结: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挂掉的话,服务就故障了)

3.11 基于storageclass动态生成pv

3.11.1 设置/etc/ceph/目录的权限

1
2
3
4
5
6
7
8
9
[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@master1 ~]# chmod 777 -R /etc/ceph/*
[root@master2 ~]# chmod 777 -R /etc/ceph/*
[root@master3 ~]# chmod 777 -R /etc/ceph/*
[root@node1 ~]# chmod 777 -R /etc/ceph/*
[root@node2 ~]# chmod 777 -R /etc/ceph/*
[root@node3 ~]# chmod 777 -R /etc/ceph/*

3.11.2 创建/root/.ceph/目录

1
2
3
4
5
6
7
8
9
[root@master1-admin ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@node1-monitor ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@node2-osd ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@master1 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@master2 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@master3 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@node1 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@node2 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/
[root@node3 ~]# mkdir /root/.ceph/ ; cp -ar /etc/ceph/ /root/.ceph/

3.11.3 创建rbd-provisioner相关配置

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
[root@master1 k8s-ceph]# 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: ServiceAccount
name: rbd-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: rbd-provisioner
apiGroup: 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.io
kind: Role
name: rbd-provisioner
subjects:
- kind: ServiceAccount
name: rbd-provisioner
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rbd-provisioner
spec:
selector:
matchLabels:
app: rbd-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: rbd-provisioner
spec:
containers:
- name: rbd-provisioner
image: quay.io/xianchao/external_storage/rbd-provisioner:v1
imagePullPolicy: IfNotPresent
env:
- name: PROVISIONER_NAME
value: ceph.com/rbd
serviceAccount: rbd-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rbd-provisioner


[root@master1 k8s-ceph]# kubectl apply -f rbd-provisioner.yaml
clusterrole.rbac.authorization.k8s.io/rbd-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created
role.rbac.authorization.k8s.io/rbd-provisioner created
rolebinding.rbac.authorization.k8s.io/rbd-provisioner created
deployment.apps/rbd-provisioner created
serviceaccount/rbd-provisioner created


[root@master1 k8s-ceph]# kubectl get pods -l app=rbd-provisioner
NAME READY STATUS RESTARTS AGE
rbd-provisioner-685746688f-vs265 1/1 Running 0 3m53s

3.11.4 创建ceph-secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#在master1-admin节点创建pool池
[root@master1-admin ~]# ceph osd pool create k8stest1 6
pool 'k8stest1' created


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


#在master1(k8s控制节点)创建secret
[root@master1 k8s-ceph]# cat ceph_secret_1.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret-1
type: "ceph.com/rbd"
data:
key: QVFEY1VsWmpGM0h6S2hBQXlnc1k4a0F3eVMxOXJzVjhPaHFEaGc9PQ==

[root@master1 k8s-ceph]# kubectl apply -f ceph_secret_1.yaml
secret/ceph-secret-1 created

3.11.5 创建storageclass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@master1 k8s-ceph]# cat create_storageclass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: k8s-rbd
provisioner: ceph.com/rbd
parameters:
monitors: 192.168.106.31:6789
adminId: admin
adminSecretName: ceph-secret-1
pool: k8stest1
userId: admin
userSecretName: ceph-secret-1
fsType: xfs
imageFormat: "2"
imageFeatures: "layering"


[root@master1 k8s-ceph]# kubectl apply -f create_storageclass.yaml
storageclass.storage.k8s.io/k8s-rbd created

3.11.6 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@master1 k8s-ceph]# cat create_pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: k8s-rbd


[root@master1 k8s-ceph]# kubectl apply -f create_pvc.yaml
persistentvolumeclaim/rbd-pvc created


[root@master1 k8s-ceph]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ceph-pvc Bound ceph-pv 1Gi RWO 8h
rbd-pvc Bound pvc-3b3e02a1-d66e-4b93-b3ad-455b70a55bc3 1Gi RWO k8s-rbd 55s

3.11.7 测试挂载pvc

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
[root@master1 k8s-ceph]# cat storage_pvc_test_pod.yaml 
apiVersion: v1
kind: Pod
metadata:
labels:
test: rbd-pod
name: ceph-rbd-pod
spec:
containers:
- name: ceph-rbd-nginx
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: ceph-rbd
mountPath: /mnt
readOnly: false
volumes:
- name: ceph-rbd
persistentVolumeClaim:
claimName: rbd-pvc


[root@master1 k8s-ceph]# kubectl apply -f storage_pvc_test_pod.yaml
pod/ceph-rbd-pod created


[root@master1 k8s-ceph]# kubectl get pod | grep ceph-rbd-pod
ceph-rbd-pod 1/1 Running 0 40s


[root@master1 k8s-ceph]# kubectl describe pod ceph-rbd-pod | grep Volumes -A8
Volumes:
ceph-rbd:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: rbd-pvc
ReadOnly: false
default-token-rwxjq:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-rwxjq
Optional: false

3.12 k8s挂载cephfs

3.12.1 创建ceph子目录

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master1-admin ~]# mkdir ceph_data
[root@master1-admin ~]# mount -t ceph 192.168.106.31:6789:/ /root/ceph_data -o name=admin,secretfile=/etc/ceph/admin.secret
[root@master1-admin ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/centos-root xfs 8.0G 2.7G 5.4G 33% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 8.6M 3.9G 1% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 xfs 1014M 193M 822M 20% /boot
tmpfs tmpfs 799M 0 799M 0% /run/user/0
/dev/sdb1 xfs 495G 126M 495G 1% /var/lib/ceph/osd/ceph-0
192.168.106.31:6789:/ ceph 1.5T 388M 1.5T 1% /root/ceph_data

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

1
2
3
[root@master1-admin ~]# cd /root/ceph_data/
[root@master1-admin ceph_data]# mkdir lucky
[root@master1-admin ceph_data]# chmod 0777 lucky/

3.12.2 创建k8s连接ceph使用的secret

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master1-admin ~]# echo `cat /etc/ceph/ceph.client.admin.keyring | grep key | awk -F " " '{print $3}'` | base64QVFEY1VsWmpGM0h6S2hBQXlnc1k4a0F3eVMxOXJzVjhPaHFEaGc9PQo=


[root@master1 k8s-ceph]# cat cephfs_secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: cephfs-secret
data:
key: QVFEY1VsWmpGM0h6S2hBQXlnc1k4a0F3eVMxOXJzVjhPaHFEaGc9PQo=


[root@master1 k8s-ceph]# kubectl apply -f cephfs_secret.yaml
secret/cephfs-secret created

3.12.3 创建cephfs的pv

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
[root@master1 k8s-ceph]# cat cephfs_pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
cephfs:
monitors:
- 192.168.106.31:6789
path: /lucky
user: admin
readOnly: false
secretRef:
name: cephfs-secret
persistentVolumeReclaimPolicy: Recycle


[root@master1 k8s-ceph]# kubectl apply -f cephfs_pv.yaml
persistentvolume/cephfs-pv created


[root@master1 k8s-ceph]# kubectl get pv | grep cephfs
cephfs-pv 1Gi RWX Recycle Available 50s

3.12.4 创建cephfs的pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@master1 k8s-ceph]# cat cephfs_pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cephfs-pvc
spec:
accessModes:
- ReadWriteMany
volumeName: cephfs-pv
resources:
requests:
storage: 1Gi


[root@master1 k8s-ceph]# kubectl apply -f cephfs_pvc.yaml
persistentvolumeclaim/cephfs-pvc created


[root@master1 k8s-ceph]# kubectl get pvc | grep cephfs
cephfs-pvc Bound cephfs-pv 1Gi RWX 88s

3.12.5 创建pod,测试挂载cephfs-pvc

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
[root@master1 k8s-ceph]# cat cephfs_deploy_test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: cephfs-test
labels:
app: cephfs-test
spec:
replicas: 3
selector:
matchLabels:
app: cephfs-test
template:
metadata:
labels:
app: cephfs-test
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-v1
mountPath: /mnt
volumes:
- name: test-v1
persistentVolumeClaim:
claimName: cephfs-pvc


[root@master1 k8s-ceph]# kubectl apply -f cephfs_deploy_test.yaml
deployment.apps/cephfs-test created

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!