背景介绍

大家是否在为手动管理PV的创建和销毁而烦恼?

最近笔者就因为调试各种中间件集群,被手动维护折腾得够够的。又因为NFS做K8S后端存储存在单点故障问题,所以下定决心把ceph集群搭建出来,对接到k8s,从而实现pv的自动管理,释放重复操作的精力。

准备工作

准备3台虚拟机,笔者是共用了K8S的3个节点

安装python 3

安装 LVM2 用于提供存储设备

安装 docker,K8S节点已经自带

/etc/hosts

192.168.0.101  host01

192.168.0.102  host02

192.168.0.104  host03

软件版本说明

ubuntu 20.04.5

RKE部署的K8S 1.22.6

python 3.8

docker 20.10.22

ceph 18.2.2

部署ceph

安装cephadm

CEPH_RELEASE=18.2.2
curl --silent --remote-name --location https://download.ceph.com/rpm-${CEPH_RELEASE}/el9/noarch/cephadm
chmod +x cephadm
cp cephadm /usr/local/bin

运行引导命令

cephadm bootstrap --mon-ip 192.168.101

启用ceph命令行

cephadm shell #带你进入有ceph命令行的容器
ceph status #检查集群状态

添加主机

cephadm shell
ceph orch host label add host02 _admin #_admin的作用是可以在对应节点执行cephadm shell从而管理ceph,需要先安装cephadm
ceph orch host label add host03 _admin

添加更多的监控节点

推荐3或5,官方不建议7或更多

ceph orch daemon add mon host02:192.168.0.102
ceph orch daemon add mon host03:192.168.0.103

划分lv

#假设有一块空闲设备/dev/sdb
#我们来创建给osd用的设备
pvcreate /dev/sdb
vgcreate ceph-vg /dev/sdb
lvcreate -L 5G -n ceph-lv-01 ceph-vg
lvcreate -L 5G -n ceph-lv-02 ceph-vg
lvcreate -L 5G -n ceph-lv-03 ceph-vg
#lv操作到此,切记不可以格式化

添加存储osd

#host01
ceph orch daemon add osd host01:/dev/ceph-vg/ceph-lv01
ceph orch daemon add osd host01:/dev/ceph-vg/ceph-lv02
ceph orch daemon add osd host01:/dev/ceph-vg/ceph-lv03
#host02
ceph orch daemon add osd host02:/dev/ceph-vg/ceph-lv01
ceph orch daemon add osd host02:/dev/ceph-vg/ceph-lv02
ceph orch daemon add osd host02:/dev/ceph-vg/ceph-lv03
#host03
ceph orch daemon add osd host03:/dev/ceph-vg/ceph-lv01
ceph orch daemon add osd host03:/dev/ceph-vg/ceph-lv02
ceph orch daemon add osd host03:/dev/ceph-vg/ceph-lv03

注意检查集群状态,也可以登录ceph web页面查看。运行引导命令之后返回的信息有列出登录方式。

以RBD方式与K8S集成

创建一个存储池

ceph osd pool create kubernetes
rbd pool init kubernetes

配置ceph-csi

#设置ceph客户端认证
ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
#记录返回的信息
#比如
#[client.kubernetes]
#    key = AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==

#生成ceph-csi配置信息
ceph mon dump
#记录返回的信息
#比如
#<...>
#fsid b9127830-b0cc-4e34-aa47-9d1a2e9949a8
#<...>
#0: [v2:192.168.1.1:3300/0,v1:192.168.1.1:6789/0] mon.a
#1: [v2:192.168.1.2:3300/0,v1:192.168.1.2:6789/0] mon.b
#2: [v2:192.168.1.3:3300/0,v1:192.168.1.3:6789/0] mon.c
cat <<EOF > csi-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    [
      {
        "clusterID": "b9127830-b0cc-4e34-aa47-9d1a2e9949a8",
        "monitors": [
          "192.168.1.1:6789",
          "192.168.1.2:6789",
          "192.168.1.3:6789"
        ]
      }
    ]
metadata:
  name: ceph-csi-config
EOF
#根据ceph mon dump信息修改csi-config-map的内容
#clusterID和monitors的ip
#部署csi-config-map.yaml
kubectl apply -f csi-config-map.yaml

cat <<EOF > csi-kms-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    {}
metadata:
  name: ceph-csi-encryption-kms-config
EOF
kubectl apply -f csi-kms-config-map.yaml

cat <<EOF > ceph-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  ceph.conf: |
    [global]
    auth_cluster_required = cephx
    auth_service_required = cephx
    auth_client_required = cephx
  # keyring is a required key and its value should be empty
  keyring: |
metadata:
  name: ceph-config
EOF
kubectl apply -f ceph-config-map.yaml

#生成ceph-csi密钥并部署
cat <<EOF > csi-rbd-secret.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: default
stringData:
  userID: kubernetes
  userKey: AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==
EOF
kubectl apply -f csi-rbd-secret.yaml
#注意把这里的userKey用前面ceph auth那的key来替换

#配置ceph-csi插件
kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml
wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml
kubectl apply -f csi-rbdplugin-provisioner.yaml
wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin.yaml
kubectl apply -f csi-rbdplugin.yaml
#这里会出现镜像下载超时问题,可以docker search一下超时的image名称,寻找替代品

#创建存储类
cat <<EOF > csi-rbd-sc.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: b9127830-b0cc-4e34-aa47-9d1a2e9949a8
   pool: kubernetes
   imageFeatures: layering
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: default
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: default
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
   - discard
EOF
kubectl apply -f csi-rbd-sc.yaml
#此处务必修改clusterID,从ceph mon dump的返回消息获取

动态创建和绑定PV测试

#创建基于文件系统挂载的pvc
cat <<EOF > pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc
EOF
kubectl apply -f pvc.yaml

#创建挂载上面pvc的pod
cat <<EOF > pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
        - name: mypvc
          mountPath: /var/lib/www/html
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false
EOF
kubectl apply -f pod.yaml

实践感想

1、多看官方文档,英文不要惧怕,开启页面翻译,翻译不好理解的地方切回英文看。

2、官方文档边看边动手操作,有的地方要灵活变化修改着用。

3、多看此软件领域的老司机博客。

参考资料

ceph集群部署的官方文档地址

rbd方式与k8s集成的官方文档地址

自我激励

偷懒让人思考,思考让人行动,行动让人进步!

感谢

如果觉得有帮助,请帮笔者点个赞。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐