Bootstrap

在Kubernets Cluster中部署LVM类型的StorageClass -下

安装lvm provisioner

在确保已经在worker node安装lvm后,接下来的重要步骤就是要安装CSI插件了,这个要安装的CSI插件将作为controller或者provisioner以协助k8s在worker node上与lvm系统交互,创建lvm的逻辑卷并进行格式化后作为k8s的PV, 供PVC绑定到pod上使用。此provisioner也是以deamenset方式运行在k8s集群内。
最常见的k8s lvm provisioner是Topolvm, github 地址: 这里 helm chart: 这里

以下为安装步骤:

  helm repo add topolvm https://topolvm.github.io/topolvm  #添加topolvm的repo
  helm repo update
  kubectl create namespace topolvm-system #给要装的topolvm单独先创建一个namespace
  # 两个label操作来自官网要求
  kubectl label namespace topolvm-system topolvm.io/webhook=ignore
  kubectl label namespace kube-system topolvm.io/webhook=ignore
  helm install --namespace=topolvm-system topolvm topolvm/topolvm #报错了,原来topolvm需要cert-manager的支持
  #按官网要求先安装cert-manager
  kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/1.16.1/cert-manager.crds.yaml
  helm install --namespace=topolvm-system topolvm topolvm/topolvm --set cert-manager.enabled=true #正式安装。这里还需要一个value去设定vg为vg-k8s-test,也就是我在worker node上创建的vg的名字。我没指定,后续用了较多精力去排错了。
  kubectl get sc # 安装完成后会自动生成StorageClass!
NAME                  PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
topolvm-provisioner   topolvm.io    Delete          WaitForFirstConsumer   true                   43h
 kubectl get pods -n topolvm-system
NAME                                               READY   STATUS             RESTARTS          AGE
topolvm-cert-manager-5d479bcccb-hvlgd              1/1     Running            0                 44h
topolvm-cert-manager-cainjector-699cbfbf96-m269h   1/1     Running            0                 44h
topolvm-cert-manager-webhook-f44fc4d4b-8d7bn       1/1     Running            0                 44h
topolvm-controller-76b555479b-4wpd7                5/5     Running            1 (5h22m ago)     44h
topolvm-controller-76b555479b-w5ml4                5/5     Running            0                 44h
topolvm-lvmd-0-knlsx                               1/1     Running            0                 21h
topolvm-lvmd-0-w2xzm                               0/1     CrashLoopBackOff   75 (5m2s ago)     21h
topolvm-node-7pzkd                                 3/3     Running            289 (21h ago)     44h
topolvm-node-r29c4                                 1/3     CrashLoopBackOff   433 (4m36s ago)   44h
# 这个正常,因为我两个worker node,只有一个安装了lvm做测试,所以有一个node上是跑不起来的。看起来controller运行在master上,lvmd和node分别以ds模式运行在了worker上。
#用get ds 确认下。
kubectl get ds -n topolvm-system
NAME             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
topolvm-lvmd-0   2         2         1       2            1           <none>          44h
topolvm-node     2         2         1       2            1           <none>          44h

这样基本上就完成了。 让Chatgpt给我写了个配置文件,调用这个名字叫”topolvm-provisioner“ 的StorageClass生成PVC测试下效果。

root@master:/opt/k8sconfig# cat topolvm-sc-test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: storage-test
  labels:
    app: storage-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: storage-test
  template:
    metadata:
      labels:
        app: storage-test
    spec:
      nodeSelector:
        kubernetes.io/hostname: slave2 #因为我只在slave2这个worker node上装了lvm,所以要确保生成的pod被调度到正确的地方
      containers:
      - name: storage-test
        image: busybox
        command: ["/bin/sh", "-c"]
        args:
          - while true; do
              echo "$(date) - Writing to /data/testfile" >> /data/testfile;
              sleep 5;
            done;
        volumeMounts:
        - name: test-storage
          mountPath: /data
      volumes:
      - name: test-storage
        persistentVolumeClaim:
          claimName: test-pvc
---
apiVersion: v1 # 这里定义PVC, 引用我们要测试的StorageClass
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: topolvm-provisioner #就是你了

运行这个yaml后看下效果

kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS          VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-82dddf08-b127-4e17-89b2-8a85936cfe5f   1Gi        RWO            Delete           Bound    default/test-pvc   topolvm-provisioner   <unset>                          20h
#可以看到pv已经生成,并成功的绑定到了pod上。 整个lvm在vg上创建lv,并格式化lv成可用磁盘的过程全部后台自动化处理了,完美。

再回到slave2 这个worker node上运行lvs 或者lvdisplay 确认下实际效果:

 sudo lvdisplay
  --- Logical volume ---
  LV Path                /dev/vg-k8s-test/d51c509e-217b-4956-8879-5c15fda8167b
  LV Name                d51c509e-217b-4956-8879-5c15fda8167b
  VG Name                vg-k8s-test
  LV UUID                jMxM4f-ilDm-x7DA-7jB7-P0fe-9CwD-GqmQLa
  LV Write Access        read/write
  LV Creation host, time slave2, 2025-01-24 21:06:56 -0400
  LV Status              available
  # open                 1
  LV Size                1.00 GiB
  Current LE             256
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:0
#符合预期,完美。

排错

我遇到了几个小错误,通过查看容器的错误日志并结合helm官网的这个chart的value是默认值设置 很快就解决了。
比如values:
lvmd.deviceClasses list [{“default”:true,“name”:“ssd”,“spare-gb”:10,“volume-group”:“myvg1”}] Specify the device-class settings.
这个就是说默认会用volume-group的名字是 myvg1, 那我更改下已经安装好的默认值为vg-k8s-test 就可用了。
大致步骤:

helm get values topolvm -n topolvm-system --all > topolvm-values.yaml #--all表示全部,不加--all只会得到你install时 --set的特定值。现在我们将所有的value都保存到topolvm-values.yaml
vim topolvm-values.yaml # 变更vg的值,同时也可用变更格式化的磁盘格式从默认的xfs到ext4.
helm upgrade topolvm topolvm/topolvm -n topolvm-system -f topolvm-values.yaml #让变更生效

以上。

;