天天看點

如何在 Kubernetes 環境中搭建 MySQL(四):使用 StorageClass 挂接 RBD

如何在 Kubernetes 環境中搭建 MySQL(四):使用 StorageClass 挂接 RBD

MySQL + Kubernetes

1. 簡介

在系列文章的第三篇中,講到了如何使用 PV 和 PVC 挂載 RBD 上建立好的塊存儲鏡像,但這還是不足以滿足 cloud native 環境下的需求,試想如果部署一個應用,需要申請十個 RBD images,PV 和 PVC 的方式下,就需要先手動在 ceph 叢集上部署十個 image,這在實際操作時,是完全不可接受的,就算用 Webhook 機制調用腳本自動執行,也會存在一些問題,比如何時釋放 RBD image,而且這樣也增加了系統的複雜度,更易出錯,是以最好是有 Kubernetes 的原生的解決方案。而 Kubernetes 确實提供這樣的解決方案,就是本文要談到的 StorageClass。

我對 StorageClass 的了解是: 對系統提供的存儲能力進行抽象,并使用用戶端與存儲系統進行互動,來達到動态擷取存儲能力的目的。也就是說,用戶端是要和 StorageClass 配套使用的,用哪種類型的存儲,就需要啟動對應的用戶端,RBD 的用戶端叫做 rbd-provisioner。

2. 配置 StorageClass

首先需要擷取 ceph 的密鑰:

$ ceph auth get-key client.admin | base64
QVFCTnFzMWFuMDNoRGhBQUVrMjlXNlZzYnN6Yk13bWZvVmt0bkE9PQ==
           

然後建立名為 ceph-secret 的 secret,後面的 StorageClass 會用到。

$ cat ceph-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
type: "kubernetes.io/rbd"
data:
  key: QVFCTnFzMWFuMDNoRGhBQUVrMjlXNlZzYnN6Yk13bWZvVmt0bkE9PQ==
           

接下來看一下 StorageClass 配置檔案的執行個體:

$ cat storage-class.yaml 
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: rbd
provisioner: ceph.com/rbd
parameters:
  monitors: 192.168.250.91:6789
  adminId: admin
  adminSecretName: ceph-secret
  adminSecretNamespace: default
  pool: rbd
  userId: admin
  userSecretName: ceph-secret
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"
           

大部分的内容和 PV 裡的配置是一樣的,那麼就挑幾個之前沒有介紹過的參數說一下:

  • provisioner: 就是之前所說的用戶端,官方文檔中使用的 provisioner 是預設的 kubernetes.io/rbd,注意要改成 ceph.com/rbd,kubernetes.io/rbd 是無法正常使用的,原因是 kubernetes.io/rbd 會在 kube-controller-manager 鏡像中查找 RBD 可執行檔案,但預設的 kube-controller-manager 鏡像是沒有的,需要自己來定制鏡像,具體細節可參考該連結: Error creating rbd image: executable file not found in $PATH 。改為 "ceph.com/rbd" 後,使用的是外部的 RBD 可執行檔案,具體的做法會在下一節中介紹。
  • adminId | userId:連接配接 ceph 的權限,admin 已存在,如果有需要建立其他使用者,可以在 Ceph 叢集中建立,并賦予對應的權限,簡單使用的話,admin 也足夠了。
  • adminSecretName:Ceph admin 所使用的密鑰,複用之前建立的即可。
  • adminSecret。namespace:密鑰所在的命名空間,預設是 default,如果修改為其他的話,需要修改 ceph-secret.yaml,增加 namespace字段:namespace-name。

建立 StorageClass:

$ kubectl create -f storage-class.yaml
storageclass "rbd" created
$ kubectl get storageclass
NAME      TYPE
rbd       ceph.io/rbd
           

3. 配置 rbd-provisioner

首先要下載下傳 kubernetes-incubator git 庫,RBD 的内容存儲在 external-storage/ceph/rbd/deploy/ 目錄下。

$ git clone https://github.com/kubernetes-incubator/external-storage.git
$ tree external-storage/ceph/rbd/deploy/
├── README.md
├── non-rbac
│   └── deployment.yaml
└── rbac
    ├── clusterrole.yaml
    ├── clusterrolebinding.yaml
    ├── deployment.yaml
    └── serviceaccount.yaml
           

分為 RBAC 和 無 RBAC 兩種部署方式,RBAC 就是基于角色的權限控制,kubeadm 搭建的 Kubernetes 叢集預設開啟了 RBAC,是以本文選用 RBAC 方式。external-storage 中提供的方式是部署在 default namespace 中的,如果要部署在其他 namespace 中,需要做對應的修改。

接下來就把 RBD provisioner 啟動起來吧:

$ kubectl create -f external-storage/ceph/rbd/deploy/rbac/
clusterrole "rbd-provisioner" created
clusterrolebinding "rbd-provisioner" created
deployment "rbd-provisioner" created
serviceaccount "rbd-provisioner" create

$ kubectl get pod --selector app=rbd-provisioner
NAME                               READY     STATUS    RESTARTS   AGE
rbd-provisioner-6f4f7fcf5f-4gdmj   1/1       Running   0          6m
           

4. 挂載 StorageClass

一切就緒,接下來就試試能否動态的擷取 RBD 存儲空間吧。

先建立 PVC,看看 PVC 能否處于 bound 狀态。

$ cat dynamic-volume-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: rbd
  resources:
    requests:
      storage: 1Gi

$ kubectl create -f dynamic-volume-claim.yaml
NAME                 STATUS    VOLUME                                     CAPACITY   ACCESS MODES         STORAGECLASS    AGE
mysql-dynamic-pvc    Bound     pvc-65ddafb2-6f9d-11e8-b243-d09466144cbf   1Gi        RWO                  rbd             5d
           

接下來再将該 PVC 挂載到 MySQL 執行個體上。

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: ROOT_PASSWORD
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
          subPath: mysql
          readOnly: false
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-dynamic-pvc
           

至此完成 RBD 的動态挂載,下一篇文章來談一談如何使用 StatefulSet 部署主從同步的 MySQL 叢集。

5. 參考資料