随着K8S存储接口逐渐成熟并顺势推出CSI接口规范后,原来“in-tree”(树内)模式的很多存储插件也逐步迁移到了“out-of-tree”(树外)模式的CSI插件上,甚至有些原来支持的存储卷类型都被直接移除了(例如在K8S v1.26上直接移除了 glusterfs 卷类型),查阅了一下K8S官方最新版本的存储相关(Storage/Volumes)的说明,综合最新存储支持情况,我们选择Ceph作为K8S集群的存储提供者。

  首先,进入Ceph官网文档查看其安装部署方法,主要看下是否有基于K8S的安装方法,最后在官网“Installing ceph>Recommended methods”(推荐的Ceph安装方法)果然发现了基于K8S的安装方法:

  Ceph官方推荐在K8S集群上使用Rook来部署和管理Ceph集群!

  我们进入Rook官网看看,从官网可以看出Rook是为K8S量身定制的,那就它了:

  Ceph是一个在大规模生产集群中提供文件、块和对象存储的分布式存储系统,而Rook是一个专门支持Ceph与云原生环境集成的开源云原生存储协调器。Rook利用K8S的Operator机制推出了自己的Rook operator,实现自动化的Ceph部署和管理。Rook作为云原生存储平台已经从CNCF顺利毕业!

  以上是对Rook简要说明,接下来借助Rook在K8S集群上部署和管理Ceph。

  Rook支持K8S v1.19+的版本,CPU架构为amd64、x86_64或arm64均可,除此之外部署Ceph存储集群还必须至少满足以下先决条件之一

  • 每个节点至少有一块裸设备(Raw devices,未分区未进行文件系统格式化)
  • 裸分区(Raw partitions,未进行文件系统格式化)
  • LVM逻辑卷(LVM Logical Volumes,未进行文件系统格式化)
  • block模式下存储类(storage class)中可用的持久卷(PV)

  这里我们选择为K8S集群每个工作节点添加一块额外的未格式化磁盘(裸设备),步骤见以下截图:

  将新增的磁盘设置成独立模式(模拟公有云厂商提供的独立磁盘),然后启动K8S集群虚拟机,在工作节点上使用以下命令检查一下磁盘条件是否符合Ceph部署要求:

[root@node1 ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sdb
sr0 iso9660 CentOS 7 x86_64 2020-11-04-11-36-43-00
sda
├─sda2 LVM2_member 45inUD-qJ4O-Fq9E-L6KD-8eJV-mofD-BuJDq6
│ └─centos_node1-root
xfs 704f37f0-ae59-4995-80ec-58cba66e023b /
└─sda1 xfs 67243cc8-c3fb-490f-b0da-cc439371d5e1 /boot

  上述命令输出中 sdb 磁盘就是我们为工作节点新添加的裸设备(它的FSTYPE为空),我们可以把它分配给Ceph使用。

  需要在K8S集群中启用Rook准入控制器,用于验证使用自定义资源(CR)正确地配置了Rook。该准入控制器在身份认证和授权之后并在持久化对象之前,拦截发往K8S API Server的请求以进行验证。我们在安装Rook之前,使用以下命令在K8S集群中安装Rook准备入控制器:

#在master1节点直接应用在线yaml文件
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml #在master1将cert-manager.yaml下载到本地的方式(推荐)
kubectl apply -f /etc/kubernetes/rook/cert-manager.yaml
......
service/cert-manager created
service/cert-manager-webhook created
deployment.apps/cert-manager-cainjector created
deployment.apps/cert-manager created
deployment.apps/cert-manager-webhook created
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

  另外,Ceph OSD在以下情况下需要依赖于LVM(逻辑卷,OSD是Ceph用于在各个存储节点实现存储功能的组件)

  • 在裸设备或裸分区上创建OSD
  • 如果启用了加密(在集群CR中设置了encryptedDevice: "true")
  • 指定了元数据设备(metadata device)

  在以下情况下OSD不需要LVM

  • 在使用 storageClassDeviceSets 的PVC上创建OSD

  目前大多数Linux发生版的LVM由lvm2包提供,在K8S集群中运行Ceph OSD的所有存储节点上都需要有这个包。虽然没有这个包Rook也能够成功创建Ceph OSD,但是当相应的节点(node)重启之后,其上运行的OSD pod将会启动失败。所以需要确保作为存储节点的操作系统上安装了LVM(从上面磁盘条件查验的结果中看到我们是有LVM卷的),CentOS可以使用以下命令安装LVM:

sudo yum install -y lvm2

  Ceph需要一个带有RBD模块的Linux内核。大多数Linux发行版都有这个模块,但不是所有,你可以在K8S集群的存储节点上运行  lsmod|grep rbd 命令检测一下,如果该命令返回空,那说明当前系统内核没有加载RBD模块,可以使用以下命令尝试加载RBD模块:

#将RBD模块加载命令放入开机加载项里
cat > /etc/sysconfig/modules/rbd.modules << EOF
#!/bin/bash
modprobe rbd
EOF #为上述为脚本添加执行权限
chmod +x /etc/sysconfig/modules/rbd.modules #执行上述脚本(如果返回'not found',你可能需要安装一个新的内核、或重新编译一个带有RBD模块的内核、或换一个带有RBD的Linux 发行版)
/bin/bash /etc/sysconfig/modules/rbd.modules #查看RBD模块是否加载成功
lsmod|grep rbd

  Rook默认的RBD配置只指定了分层特性,以便与较旧的内核广泛兼容。如果K8S节点运行在5.4+的系统内核上,则可以启用其他功能特性。例如特别有用的 fast-diff 和 object-map 特性,主要的功能特性如下(在进行块存储的StorageClass定义时指定):

imageFeatures: layering,fast-diff,object-map,deep-flatten,exclusive-lock

  如果你将来会从Ceph共享文件系统(CephFS)创建卷(volume),那么需要使用4.17+的系统内核,PVC请求的存储配额只在高于该版本的内核上生效。

------------------------------- 以上为使用Rook在K8S集群部署Ceph存储的前提条件 -------------------------------

  接下来正式使用Rook在K8S集群部署Ceph存储集群!

  首先在K8S所有集群节点上安装Git客户端(用于拉取Rook部署组件清单):

#安装Git
yum install -y git #查看Git版本
git --version git version 1.8.3.1

  使用Rook官方提供的示例部署组件清单(manifests)部署一个简单的Ceph集群(测试环境够用了):

#使用git将部署组件清单示例下载到本地(慢或无法接通的话自己想法办FQ)
git clone --single-branch --branch v1.10.11 https://github.com/rook/rook.git #进入到本地部署组件清单示例目录
cd rook/deploy/examples #执行以下命令将Rook和Ceph相关CRD资源和通用资源创建到K8S集群(其中psp.yaml是K8S集群受Pod安全策略保护的情况下的可选资原文件)
kubectl create -f crds.yaml -f common.yaml -f psp.yaml

  接下来部署Rook Operator组件,该组件为Rook与Kubernetes交互的组件,整个集群只需要一个副本,特别注意 Rook Operator 的配置在Ceph集群安装后不能修改,否则Rook会删除Ceph集群并重建,所以部署之前一定要做好规划,修改好operator.yaml的相关配置:

修改 rook/deploy/examples/operator.yaml文件中的以下内容:

#修改镜像地址为华中科技大学和阿里云的(可以使用docker pull <url>验证一下,原来的地址很难下载)
ROOK_CSI_CEPH_IMAGE: "quay.mirrors.ustc.edu.cn/cephcsi/cephcsi:v3.7.2"
ROOK_CSI_REGISTRAR_IMAGE: "registry.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.7.0"
ROOK_CSI_RESIZER_IMAGE: "registry.aliyuncs.com/google_containers/csi-resizer:v1.7.0"
ROOK_CSI_PROVISIONER_IMAGE: "registry.aliyuncs.com/google_containers/csi-provisioner:v3.4.0"
ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.aliyuncs.com/google_containers/csi-snapshotter:v6.2.1"
ROOK_CSI_ATTACHER_IMAGE: "registry.aliyuncs.com/google_containers/csi-attacher:v4.1.0" #生产环境一般都会将裸设备自动发现开关设为true(方便后面追加设备)
ROOK_ENABLE_DISCOVERY_DAEMON: "true" #打开CephCSI 提供者的节点(node)亲和性(去掉前面的注释即可,会同时作用于CephFS和RBD提供者,如果要分开这两者的调度,可以继续打开后面专用的节点亲和性)
CSI_PROVISIONER_NODE_AFFINITY: "role=storage-node; storage=rook-ceph" #如果CephFS和RBD提供者的调度亲各性要分开,则在上面的基础上继打开它们专用的开关(去除下面两行前端的#即可)
# CSI_RBD_PROVISIONER_NODE_AFFINITY: "role=rbd-node"
# CSI_CEPHFS_PROVISIONER_NODE_AFFINITY: "role=cephfs-node" #打开CephCSI 插件的节点(node)亲和性(去掉前面的注释即可,会同时作用于CephFS和RBD插件,如果要分开这两者的调度,可以继续打开后面专用的节点亲和性)
CSI_PLUGIN_NODE_AFFINITY: "role=storage-node; storage=rook-ceph" #如果CephFS和RBD提供者的调度亲各性要分开,则在上面的基础上继打开它们专用的开关(去除下面两行前端的#即可)
# CSI_RBD_PLUGIN_NODE_AFFINITY: "role=rbd-node"
# CSI_CEPHFS_PLUGIN_NODE_AFFINITY: "role=cephfs-node" #rook-ceph-operator的Deployment中的容器镜像地址rook/ceph:v1.10.11 可以不用换,下载还是很快的! #生产环境一般还会打开裸设备自动发现守护进程(方便后期增加设备)
ROOK_ENABLE_DISCOVERY_DAEMON: "true"
#同时开打发现代理的节点亲和性环境变量
- name: DISCOVER_AGENT_NODE_AFFINITY
value: "role=storage-node; storage=rook-ceph"

  确认修改完成后,在master1节点上执行以下命令进行Rook Ceph Operator的部署:

#执行以下命令在K8S集群中部署Rook Ceph Operator(镜像拉取可能需要一定时间,耐心等待,可用后一条命令监控相关Pod部署情况)
kubectl create -f operator.yaml
#使用以下命令监控Rook Ceph Operator相关Pod的部署情况(rook-ceph为默认Rook Ceph Operator部署命名空间)
watch kubectl get pods -n rook-ceph

  确保rook-ceph-operator相关Pod都运行正常的情况下,修改 rook/deploy/examples/cluster.yaml文件中的以下内容:

# enable prometheus alerting for cluster(为集群打开prometheus告警)
monitoring:
# requires Prometheus to be pre-installed
enabled: true #打开节点亲和性调度和污点容忍
# To control where various services will be scheduled by kubernetes, use the placement configuration sections below.
# The example under 'all' would have all services scheduled on kubernetes nodes labeled with 'role=storage-node' and
# tolerate taints with a key of 'storage-node'.
placement:
all:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: role
operator: In
values:
- storage-node
# podAffinity:
# podAntiAffinity:
# topologySpreadConstraints:
# tolerations:
# - key: storage-node
# operator: Exists #将存储设置为我们三个工作节点新加的sdb裸盘
storage: # cluster level storage configuration and selection
useAllNodes: false
useAllDevices
: false
#deviceFilter:
config:
# crushRoot: "custom-root" # specify a non-default root label for the CRUSH map
# metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.
# databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB
# journalSizeMB: "1024" # uncomment if the disks are 20 GB or smaller
# osdsPerDevice: "1" # this value can be overridden at the node or device level
# encryptedDevice: "true" # the default value for this option is "false"
# Individual nodes and their config can be specified as well, but 'useAllNodes' above must be set to false. Then, only the named
# nodes below will be used as storage resources. Each node's 'name' field should match their 'kubernetes.io/hostname' label.
nodes:
- name: "node1"
devices: # specific devices to use for storage can be specified for each node
- name: "sdb"
- name: "node2"
devices: # specific devices to use for storage can be specified for each node
- name: "sdb"
- name: "node3"
devices: # specific devices to use for storage can be specified for each node
- name: "sdb"
# - name: "nvme01" # multiple osds can be created on high performance devices
# config:
# osdsPerDevice: "5"
# - name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # devices can be specified using full udev paths
# config: # configuration can be specified at the node level which overrides the cluster level config
# - name: "172.17.4.301"
# deviceFilter: "^sd."
# when onlyApplyOSDPlacement is false, will merge both placement.All() and placement.osd
onlyApplyOSDPlacement: false

  修改完后,根据我们在operator.yaml和cluster.yaml上的节点标签亲和性设置,为三个工作节点打上对应的标签

kubectl label nodes node1 node2 node3 role=storage-node
kubectl label nodes node1 node2 node3 storage=rook-ceph
#确保工作节点打上对应标签,并且cluster文件修改好后,就可以使用cluster.yaml部署Ceph存储集群了(部署需要一定的时间,可用后一条命令监控)
kubectl create -f cluster.yaml
#使用以下命令监控Ceph Cluster相关Pod的部署情况(rook-ceph为默认部署命名空间)
watch kubectl get pods -n rook-ceph

  未完待续...

为K8S集群准备Ceph存储的更多相关文章

  1. 通过Heketi管理GlusterFS为K8S集群提供持久化存储

    参考文档: Github project:https://github.com/heketi/heketi MANAGING VOLUMES USING HEKETI:https://access.r ...

  2. k8s 集群管理和微服务 适合做啥

    k8s 集群管理和微服务 适合做啥 都知道k8s是集群 适合微服务 有很多教程 但你可以先了解他能干啥 traefix 是负载均衡工具 k8s 适合部署无状态依赖的微服务 可以按需求开启多个微服务 管 ...

  3. 大规模 K8s 集群管理经验分享 · 上篇

    11 月 23 日,Erda 与 OSCHINA 社区联手发起了[高手问答第 271 期 -- 聊聊大规模 K8s 集群管理],目前问答活动已持续一周,由 Erda SRE 团队负责人骆冰利为大家解答 ...

  4. 使用kubeadm快速部署一套K8S集群

    一.Kubernetes概述 1.1 Kubernetes是什么 Kubernetes是Google在2014年开源的一个容器集群管理系统,Kubernetes简称K8S. K8S用于容器化应用程序的 ...

  5. 使用KubeOperator扩展k8s集群的worker节点

    官方文档网址:https://kubeoperator.io/docs/installation/install/ 背景说明 原先是一个三节点的k8s集群,一个master,三个woker(maste ...

  6. 在k8s集群中安装rook-ceph 1.8版本步骤

    官方文档地址:https://rook.io/docs/rook/v1.8/quickstart.html Kubernetes 最小版本号 Kubernetes 最小版本号:Kubernetes v ...

  7. k8s集群中安装rook-ceph

    容器的持久化存储 容器的持久化存储是保存容器存储状态的重要手段,存储插件会在容器里挂载一个基于网络或者其他机制的远程数据卷,使得在容器里创建的文件,实际上是保存在远程存储服务器上,或者以分布式的方式保 ...

  8. China Azure中部署Kubernetes(K8S)集群

    目前China Azure还不支持容器服务(ACS),使用名称"az acs create --orchestrator-type Kubernetes -g zymtest -n kube ...

  9. k8s重要概念及部署k8s集群(一)--技术流ken

    重要概念 1. cluster cluster是 计算.存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用. 2.master master是cluster的大脑,他的主要职责是调度,即决 ...

  10. K8S集群 NOT READY的解决办法 1.13 错误信息:cni config uninitialized

    今天给同事 一个k8s 集群 出现not ready了 花了 40min 才搞定 这里记录一下 避免下载 再遇到了 不清楚. 错误现象:untime network not ready: Networ ...

随机推荐

  1. 查看、校验、归档…带你掌握openGauss账本数据库

    ​摘要:账本数据库融合了区块链思想,将用户操作记录至两种历史表中:用户历史表和全局区块表. 本文分享自华为云社区<openGauss账本数据库,你不知道的那些事儿>,作者:Gauss松鼠会 ...

  2. mindxdl--common--validators.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common this file ...

  3. 封装适用于CentOS7的MySQL离线包

    1 构建一个centos7.6.1810的docker镜像,用于下载MySQL+xtrabackup所需安装包 7.6.1810的docker镜像,低版本最小安装,会尽可能把所需的包拉齐. Docke ...

  4. SpringCloud -Netflix 总结·

    springcloud 核心组件 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.智能路由.消息 ...

  5. java面试题-常用框架

    Spring Spring 是什么 一个开发框架,一个容器,主要由面向切面AOP 和依赖注入DI两个方面,外加一些工具 AOP和IOC AOP 面向切面 AOP是一种编程思想,主要是逻辑分离, 使业务 ...

  6. MySQL的安装与配置,图形化软件安装,以及IDEA上的配置操作

    1. MySQL安装详细教程 注意:本次安装例为随笔发布时最新的8.0.31版本教程,由于您所希望安装的版本不同可能会导致一些问题,请谅解. 进入官网下载界面 https://www.mysql.co ...

  7. Qt网络编程-书接上文,浅谈TCP文件收发,以及心跳包

    qt网络编程-书接上文,浅谈文件收发 上文Qt网络编程-从0到多线程编程中谈到 在qt中的qtcpsocket通讯的用法,接下来浅谈一下关于tcp通讯的实际应用,当然了由于是浅谈,也不能保证其功能的完 ...

  8. 玩转 Go 生态|Hertz WebSocket 扩展简析

    WebSocket 是一种可以在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层.WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 W ...

  9. 前缀树(Tire)—Python

    核心思想 空间换时间,是一种用于快速减速的多叉树结构,利用字符串的公共前缀来降低时间 优缺点: 优点:查询效率高,减少字符比较 缺点:内存消耗较大 每次都会从头向下一直到字符串结尾 前缀树 1 单个字 ...

  10. 【运维笔录】局域网实现HTTPS访问,只需Nginx + mkcert

    1)下载安装mkcert wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1 ...