kubernetes K8S 挂载分布式存储 ceph

目录

一、Ceph简介

二、Ceph核心组件介绍

三、安装Ceph集群

1初始化实验环境

1.1、配置静态IP:

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.1 安装ceph-deploy)

[2.2 创建monitor节点](#2.2 创建monitor节点)

[2.3 安装ceph-monitor](#2.3 安装ceph-monitor)

[2.4 部署osd服务](#2.4 部署osd服务)

[2.5 创建ceph文件系统](#2.5 创建ceph文件系统)

[2.6 测试k8s挂载ceph rbd](#2.6 测试k8s挂载ceph rbd)

[2.7 基于ceph rbd生成pv](#2.7 基于ceph rbd生成pv)

[2.8 基于storageclass动态生成pv](#2.8 基于storageclass动态生成pv)

[2.9 k8s挂载cephfs](#2.9 k8s挂载cephfs)


文档中的YAML文件配置直接复制粘贴可能存在格式错误,故实验中所需要的YAML文件以及本地包均打包至网盘

链接:https://pan.baidu.com/s/1oKhAqeXvk8JYhtMNzUYciA

提取码:cpsg

一、Ceph简介

官方:

Ceph.io --- Home

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

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

包含以下几种存储类型:

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

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集群的这块区域中;

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

2.文件系统cephfs

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

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

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

3.对象存储

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

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

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

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

分布式存储的优点:

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

**高性能:**读写速度快

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

二、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存储集群带来巨大负担。

三、安装Ceph集群

1 初始化实验环境

机器配置:

Centos7.6

网络模式:NAT

准备三台机器,每台机器需要三个硬盘,配置4GiB/4vCPU/60G

master1-admin是管理节点 :192.168.40.200

node1-monitor是监控节点:192.168.40.201

node2-osd是对象存储节点:192.168.40.202

1 .1 、配置静态IP:

把虚拟机或者物理机配置成静态ip地址,这样机器重新启动后ip地址也不会发生改变。以master1-admin主机为例,修改静态IP:

修改/etc/sysconfig/network-scripts/ifcfg-ens33文件,变成如下:

TYPE=Ethernet

PROXY_METHOD=none

BROWSER_ONLY=no

BOOTPROTO=static

IPADDR=192.168.40.200

NETMASK=255.255.255.0

GATEWAY=192.168.40.2

DNS1=192.168.40.2

DEFROUTE=yes

IPV4_FAILURE_FATAL=no

IPV6INIT=yes

IPV6_AUTOCONF=yes

IPV6_DEFROUTE=yes

IPV6_FAILURE_FATAL=no

IPV6_ADDR_GEN_MODE=stable-privacy

NAME=ens33

DEVICE=ens33

ONBOOT=yes

#修改配置文件之后需要重启网络服务才能使配置生效,重启网络服务命令如下:

service network restart

注:/etc/sysconfig/network-scripts/ifcfg-ens33文件里的配置说明:

NAME=ens33 #网卡名字,跟DEVICE名字保持一致即可

DEVICE=ens33 #网卡设备名,大家ip addr可看到自己的这个网卡设备名,每个人的机器可能这个名字不一样,需要写自己的

BOOTPROTO=static #static表示静态ip地址

ONBOOT=yes #开机自启动网络,必须是yes

IPADDR=192.168.40.200 #ip地址,需要跟自己电脑所在网段一致

NETMASK=255.255.255.0 #子网掩码,需要跟自己电脑所在网段一致

GATEWAY=192.168.40.2 #网关,在自己电脑打开cmd,输入ipconfig /all可看到

DNS1=192.168.40.2 #DNS,在自己电脑打开cmd,输入ipconfig /all可看到

1. 2、配置主机名:

在192.168.40.200上执行如下:

hostnamectl set-hostname master1-admin && bash

在192.168.40.201上执行如下:

hostnamectl set-hostname node1-monitor && bash

在192.168.40.202上执行如下:

hostnamectl set-hostname node2-osd && bash

1. 3、配置hosts文件:

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

192.168.40.200 master1-admin

192.168.40.201 node1-monitor

192.168.40.202 node2-osd

1. 4、配置互信

生成ssh 密钥对

root@master1-admin \~\]# ssh-keygen -t rsa #一路回车,不输入密码 把本地的ssh公钥文件安装到远程主机对应的账户 \[root@master1-admin \~\]# ssh-copy-id node1-monitor ![](https://i-blog.csdnimg.cn/direct/f9b18e236c9b408ab88b65f82eaffc95.png) \[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上操作: #配置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\* #把ceph.repo上传到master1-admin、node1-monitor、node2-osd上 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.org

service 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\]# vim /etc/ceph/ceph.conf \[global

fsid = af5cd413-1c53-4035-90c6-95368eef5c78

mon_initial_members = node1-monitor

mon_host = 192.168.40.201

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 -s cluster cd296ab9-1f61-4b9f-8cc3-0a57dfab00eb health HEALTH_OK monmap e1: 3 mons at {master1-admin=192.168.40.200:6789/0,node1-monitor=192.168.40.201:6789/0,node2-osd=192.168.40.202:6789/0} election epoch 4, quorum 0,1,2 master1-admin,node1-monitor,node2-osd fsmap e7: 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 v51: 116 pgs, 3 pools, 2068 bytes data, 20 objects 323 MB used, 164 GB / 164 GB avail 116 active+clean HEALTH_OK表示ceph集群正常 ### ******2.6**** ****测试k**** ****8s**** ****挂载ceph**** ****rbd****** 需要有一套k8s环境 \[root@xianchaomaster1 \~\]# kubectl get nodes NAME STATUS ROLES AGE VERSION xianchaomaster1 Ready control-plane,master 24d v1.23.1 xianchaonode1 Ready worker 24d v1.23.1 xianchaomaster1节点ip:192.168.40.180 xianchaonode1节点ip:192.168.40.181 # kubernetes要想使用ceph,需要在k8s的每个node节点安装ceph-common,把ceph节点上的ceph.repo文件拷贝到k8s各个节点/etc/yum.repos.d/目录下,然后在k8s的各个节点yum install ceph-common -y \[root@master1-admin\]# scp /etc/yum.repos.d/ceph.repo 192.168.40.180:/etc/yum.repos.d/ \[root@master1-admin\]# scp /etc/yum.repos.d/ceph.repo 192.168.40.181:/etc/yum.repos.d/ \[root@xianchaomaster1 \~\]# yum install ceph-common -y \[root@xianchaonode1 \~\]# yum install ceph-common -y #将ceph配置文件拷贝到k8s的控制节点和工作节点 \[root@master1-admin \~\]# scp /etc/ceph/\* 192.168.40.180:/etc/ceph/ \[root@master1-admin \~\]# scp /etc/ceph/\* 192.168.40.181:/etc/ceph/ #创建ceph rbd \[root@master1-admin \~\]# ceph osd pool create k8srbd1 6 pool 'k8srbd' 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 #把nginx.tar.gz 上传到xianchaonode1上,手动解压 \[root@xianchaonode1 \~\]# docker load -i nginx.tar.gz \[root@xianchaomaster1 \~\]# vim 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.40.201:6789' - '192.168.40.200:6789' - '192.168.40.202:6789' pool: k8srbd1 image: rbda fsType: xfs readOnly: false user: admin keyring: /etc/ceph/ceph.client.admin.keyring #更新资源清单文件 \[root@xianchaomaster1 \~\]# kubectl apply -f pod.yaml #查看pod是否创建成功 \[root@xianchaomaster1 \~\]# kubectl get pods -o wide ![](https://i-blog.csdnimg.cn/direct/a6331d3359734d93b432279de3ffcc04.png) 注意: k8srbd1下的rbda被pod挂载了,那其他pod就不能占用这个k8srbd1下的rbda了 例:创建一个pod-1.yaml \[root@xianchaomaster1 \~\]# cat pod-1.yaml apiVersion: v1 kind: Pod metadata: name: testrbd1 spec: containers: - image: nginx name: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: testrbd mountPath: /mnt volumes: - name: testrbd rbd: monitors: - '192.168.40.201:6789' - '192.168.40.200:6789' - '192.168.40.202:6789' pool: k8srbd1 image: rbda fsType: xfs readOnly: false user: admin keyring: /etc/ceph/ceph.client.admin.keyring \[root@xianchaomaster1 \~\]# kubectl apply -f pod-1.yaml pod/testrbd1 created \[root@xianchaomaster1 \~\]# kubectl get pods NAME READY STATUS RESTARTS AGE testrbd 1/1 Running 0 51s testrbd1 0/1 Pending 0 15s #查看testrbd1详细信息 \[root@xianchaomaster1 \~\]# kubectl describe pods testrbd1 Warning FailedScheduling 48s (x2 over 48s) 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@xianchaomaster1 \~\]# cat ceph-secret.yaml apiVersion: v1 kind: Secret metadata: name: ceph-secret data: key: QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ== \[root@xianchaomaster1 \~\]# 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@xianchaomaster1 \~\]# cat pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: ceph-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce rbd: monitors: - '192.168.40.201:6789' - '192.168.40.200:6789' - '192.168.40.202:6789' pool: k8stest image: rbda user: admin secretRef: name: ceph-secret fsType: xfs readOnly: false persistentVolumeReclaimPolicy: Recycle \[root@xianchaomaster1 \~\]# kubectl apply -f pv.yaml persistentvolume/ceph-pv created \[root@xianchaomaster1 \~\]# kubectl get pv ![](https://i-blog.csdnimg.cn/direct/8c728ddc0ffb466e929e2be2e7cb1802.png) 5、创建pvc \[root@xianchaomaster1 \~\]# cat pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: ceph-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi \[root@xianchaomaster1 \~\]# kubectl apply -f pvc.yaml \[root@xianchaomaster1 ceph\]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE ceph-pvc Bound ceph-pv 1Gi RWO 6、测试挂载pvc \[root@xianchaomaster1 \~\]# 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@xianchaomaster1 \~\]# kubectl apply -f pod-2.yaml \[root@xianchaomaster1 \~\]# 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@xianchaomaster1 \~\]# cat pod-3.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-1-deployment spec: selector: matchLabels: appv1: nginxv1 replicas: 2 # tells deployment to run 2 pods matching the template template: # create pods using pod definition in this template metadata: labels: appv1: nginxv1 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@xianchaomaster1 \~\]# kubectl apply -f pod-3.yaml \[root@xianchaomaster1 \~\]# 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@xianchaomaster1\~\]# chmod 777 -R /etc/ceph/\* \[root@xianchaonode1\]# 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@xianchaomaster1\~\]#mkdir /root/.ceph/ \[root@xianchaomaster1 \~\]#cp -ar /etc/ceph/ /root/.ceph/ \[root@xianchaonode1\]# mkdir /root/.ceph/ \[root@xianchaonode1 \~\]#cp -ar /etc/ceph/ /root/.ceph/ 1、创建rbd的供应商provisioner #把rbd-provisioner.tar.gz上传到xianchaonode1上,手动解压 \[root@xianchaonode1 \~\]# docker load -i rbd-provisioner.tar.gz \[root@xianchaomaster1 \~\]# 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"]

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@xianchaomaster1 \~\]# kubectl apply -f rbd-provisioner.yaml \[root@xianchaomaster1 \~\]# 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@xianchaomaster1 \~\]# cat ceph-secret-1.yaml apiVersion: v1 kind: Secret metadata: name: ceph-secret-1 type: "ceph.com/rbd" data: key: QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ== \[root@xianchaomaster1 \~\]# kubectl apply -f ceph-secret-1.yaml 3、创建storageclass \[root@xianchaomaster1 \~\]# cat storageclass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: k8s-rbd provisioner: ceph.com/rbd parameters: monitors: 192.168.40.201:6789 adminId: admin adminSecretName: ceph-secret-1 pool: k8stest1 userId: admin userSecretName: ceph-secret-1 fsType: xfs imageFormat: "2" imageFeatures: "layering" \[root@xianchaomaster1 \~\]# 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 ![](https://i-blog.csdnimg.cn/direct/9ead7cde00534ac8ba239637955941c5.png) \[root@xianchaomaster1 \~\]# systemctl restart kubelet \[root@xianchaomaster1 \~\]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE kube-apiserver-xianchaomaster1 1/1 Running 4、创建pvc \[root@xianchaomaster1 \~\]# cat rbd-pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: rbd-pvc spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 1Gi storageClassName: k8s-rbd \[root@xianchaomaster1 \~\]# kubectl apply -f rbd-pvc.yaml \[root@xianchaomaster1 \~\]# kubectl get pvc ![](https://i-blog.csdnimg.cn/direct/4497448869ae41c6b764e93953044815.png) 创建pod,挂载pvc \[root@xianchaomaster1 \~\]# cat pod-sto.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@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**** ****k**** ****8s**** ****挂载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 xianchao_data \[root@master1-admin \~\]# mount -t ceph 192.168.40.201:6789:/ /root/xianchao_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/xianchao_data/ \[root@master1-admin xianchao_data\]# mkdir lucky \[root@master1-admin xianchao_data\]# chmod 0777 lucky/ 2、测试k8s的pod挂载cephfs 1)创建k8s连接ceph使用的secret 将/etc/ceph/ceph.client.admin.keyring里面的key的值转换为base64,否则会有问题 \[root@master1-admin xianchao_data\]# echo "AQBvBdZgsDSZKxAAan+5rnsjr2ziA/atqFnQOA==" \| base64 QVFCdkJkWmdzRFNaS3hBQWFuKzVybnNqcjJ6aUEvYXRxRm5RT0E9PQo= \[root@xianchaomaster1 ceph\]# cat cephfs-secret.yaml apiVersion: v1 kind: Secret metadata: name: cephfs-secret data: key: QVFCdkJkWmdzRFNaS3hBQWFuKzVybnNqcjJ6aUEvYXRxRm5RT0E9PQo= \[root@xianchaomaster1 ceph\]# kubectl apply -f cephfs-secret.yaml \[root@xianchaomaster1 ceph\]# cat cephfs-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: cephfs-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteMany cephfs: monitors: - 192.168.40.201:6789 path: /lucky user: admin readOnly: false secretRef: name: cephfs-secret persistentVolumeReclaimPolicy: Recycle \[root@xianchaomaster1 ceph\]# kubectl apply -f cephfs-pv.yaml \[root@xianchaomaster1 ceph\]# cat cephfs-pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: cephfs-pvc spec: accessModes: - ReadWriteMany volumeName: cephfs-pv resources: requests: storage: 1Gi \[root@xianchaomaster1 ceph\]# kubectl apply -f cephfs-pvc.yaml \[root@xianchaomaster1 ceph\]# kubectl get pvc NAME STATUS VOLUME CAPACITY cephfs-pvc Bound cephfs-pv 1Gi RWX 创建第一个pod,挂载cephfs-pvc \[root@xianchaomaster1 ceph\]# cat cephfs-pod-1.yaml apiVersion: v1 kind: Pod metadata: name: cephfs-pod-1 spec: containers: - image: nginx name: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: test-v1 mountPath: /mnt volumes: - name: test-v1 persistentVolumeClaim: claimName: cephfs-pvc \[root@xianchaomaster1 ceph\]# kubectl apply -f cephfs-pod-1.yaml 创建第二个pod,挂载cephfs-pvc \[root@xianchaomaster1 ceph\]# cat cephfs-pod-2.yaml apiVersion: v1 kind: Pod metadata: name: cephfs-pod-2 spec: containers: - image: nginx name: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: test-v1 mountPath: /mnt volumes: - name: test-v1 persistentVolumeClaim: claimName: cephfs-pvc \[root@xianchaomaster1 ceph\]# kubectl apply -f cephfs-pod-2.yaml \[root@xianchaomaster1 ceph\]# kubectl exec -it cephfs-pod-1 -- /bin/sh # cd /mnt # touch hello \[root@xianchaomaster1 ceph\]# kubectl exec -it cephfs-pod-2 -- /bin/sh # cd /mnt # touch welcome 回到master1-admin上,可以看到在cephfs文件目录下已经存在内容了 \[root@master1-admin lucky\]# pwd /root/xianchao_data/lucky \[root@master1-admin lucky\]# ls hello welcome

相关推荐
刘若水1 小时前
Linux: 进程信号初识
linux·运维·服务器
小刘爱喇石( ˝ᗢ̈˝ )1 小时前
玛卡巴卡的k8s知识点问答题(六)
云原生·容器·kubernetes
rider1891 小时前
【1】搭建k8s集群系列(二进制部署)之系统初始化
云原生·容器·kubernetes
阳小江2 小时前
Docker知识点
运维·docker·容器
阿里云云原生2 小时前
仅3步!即刻拥有 QwQ-32B,性能比肩全球最强开源模型
前端·云原生
浩浩kids2 小时前
Hadoop•踩过的SHIT
大数据·hadoop·分布式
松韬3 小时前
Spring + Redisson:从 0 到 1 搭建高可用分布式缓存系统
java·redis·分布式·spring·缓存
只是橘色仍温柔3 小时前
xshell可以ssh连接,但vscode不行
运维·vscode·ssh
IT里的交易员3 小时前
【系统】换硬盘不换系统,使用WIN PE Ghost镜像给电脑无损扩容换硬盘
运维·电脑
共享家95273 小时前
深入剖析Linux常用命令,助力高效操作
linux·运维·服务器