Kubernetes中分佈式存儲Rook-Ceph部署快速演練

最近在項目中有涉及到Kubernetes的分佈式存儲部分的內容,也抽空多瞭解了一些。項目主要基於Rook-Ceph運行,考慮到Rook-Ceph部署也不那麼簡單,官方文檔的步驟起點也不算低,所以,在整合官方文檔的某些步驟的基礎上,寫篇文章簡單總結一下。html

Rook-Ceph是Kubernetes中分佈式存儲的一種解決方案,Rook做爲一種開源的、雲原生的存儲編排器,爲各類存儲服務在雲原生的環境中實現無縫整合,提供了所必須的平臺、框架和服務;而Ceph則是Rook所支持的衆多存儲方案的一種,在Kubernetes環境裏,Ceph基於Rook可以爲應用程序提供塊存儲(Block Storage),對象存儲(Object Storage)以及共享文件系統(SFS)服務。此處就不對Rook Ceph進行太多的介紹,直接步入正題,一步一步地演練Rook-Ceph從安裝部署到使用的整個過程。node

注意:本文全部的yaml文件都是爲了配合整個演練過程而設計的,理論上不能直接用在生產環境。若有須要,在用在生產環境以前,請確保所需的參數都已正確配置。linux

安裝Kubernetes

安裝Kubernetes。安裝方法有不少,不怕麻煩能夠徒手安裝,也能夠直接使用雲供應商的託管服務,好比Azure AKS,也可使用Rancher RKE,在此就不贅述了。shell

安裝Rook Ceph Operator

這裏咱們基於Ceph來討論。事實上Rook支持Ceph、Cassandra、CockroachDB、EdgeFS、NFS以及YugabyteDB等多種存儲供應商(Storage Provider),針對不一樣的存儲供應商,Rook提供不一樣的Operator來進行資源的部署和管理。使用下面的命令來安裝Rook Ceph Operator:json

helm repo add rook-release https://charts.rook.io/release
kubectl create namespace rook-ceph
helm install --namespace rook-ceph rook-ceph rook-release/rook-ceph

安裝Ceph集羣(Ceph Cluster)

可使用下面的yaml文件:api

# ceph-cluster-deploy.yaml
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v15.2.7
    allowUnsupported: false
  dataDirHostPath: /var/lib/rook
  skipUpgradeChecks: false
  continueUpgradeAfterChecksEvenIfNotHealthy: false
  mon:
    count: 3
    allowMultiplePerNode: false
  mgr:
    modules:
    - name: pg_autoscaler
      enabled: true
  dashboard:
    enabled: true
    ssl: true
  monitoring:
    enabled: false
    rulesNamespace: rook-ceph
  network:
  crashCollector:
    disable: false
  cleanupPolicy:
    confirmation: ""
    sanitizeDisks:
      method: quick
      dataSource: zero
      iteration: 1
    allowUninstallWithVolumes: false
  annotations:
  labels:
  resources:
  removeOSDsIfOutAndSafeToRemove: false
    useAllNodes: true
    useAllDevices: false
    deviceFilter: nvme1n1
    config:
      osdsPerDevice: "1"
  disruptionManagement:
    managePodBudgets: false
    osdMaintenanceTimeout: 30
    pgHealthCheckTimeout: 0
    manageMachineDisruptionBudgets: false
    machineDisruptionBudgetNamespace: openshift-machine-api
  healthCheck:
    daemonHealth:
      mon:
        disabled: false
        interval: 45s
      osd:
        disabled: false
        interval: 60s
      status:
        disabled: false
        interval: 60s
    livenessProbe:
      mon:
        disabled: false
      mgr:
        disabled: false
      osd:
        disabled: false

而後使用如下命令建立Ceph集羣:bash

kubectl create -f ceph-cluster-deploy.yaml

命令執行成功以後,須要等待幾分鐘,以便OSD可以成功啓動。執行下面的命令能夠查看全部容器的狀態:app

kubectl -n rook-ceph get pod

正常狀況下,應該能夠看到相似如下的結果:框架

NAME                                                 READY   STATUS      RESTARTS   AGE
csi-cephfsplugin-provisioner-d77bb49c6-n5tgs         5/5     Running     0          140s
csi-cephfsplugin-provisioner-d77bb49c6-v9rvn         5/5     Running     0          140s
csi-cephfsplugin-rthrp                               3/3     Running     0          140s
csi-rbdplugin-hbsm7                                  3/3     Running     0          140s
csi-rbdplugin-provisioner-5b5cd64fd-nvk6c            6/6     Running     0          140s
csi-rbdplugin-provisioner-5b5cd64fd-q7bxl            6/6     Running     0          140s
rook-ceph-crashcollector-minikube-5b57b7c5d4-hfldl   1/1     Running     0          105s
rook-ceph-mgr-a-64cd7cdf54-j8b5p                     1/1     Running     0          77s
rook-ceph-mon-a-694bb7987d-fp9w7                     1/1     Running     0          105s
rook-ceph-mon-b-856fdd5cb9-5h2qk                     1/1     Running     0          94s
rook-ceph-mon-c-57545897fc-j576h                     1/1     Running     0          85s
rook-ceph-operator-85f5b946bd-s8grz                  1/1     Running     0          92m
rook-ceph-osd-0-6bb747b6c5-lnvb6                     1/1     Running     0          23s
rook-ceph-osd-1-7f67f9646d-44p7v                     1/1     Running     0          24s
rook-ceph-osd-2-6cd4b776ff-v4d68                     1/1     Running     0          25s
rook-ceph-osd-prepare-node1-vx2rz                    0/2     Completed   0          60s
rook-ceph-osd-prepare-node2-ab3fd                    0/2     Completed   0          60s
rook-ceph-osd-prepare-node3-w4xyz                    0/2     Completed   0          60s

須要注意幾點:curl

  • ceph-cluster-deploy.yaml並無包括全部的Ceph集羣建立的參數,能夠參考https://rook.io/docs/rook/v1.5/ceph-cluster-crd.html 來了解全部的配置信息
  • 這裏的deviceFilter: nvme1n1是用來指定在每一個Kubernetes節點上應該使用的卷(Volume)的名稱。這個Volume不能格式化成任何文件系統,不然Ceph將不會使用它做爲存儲卷。我在AWS上建立了獨立的EBS卷,而後直接Attach到Kubernetes節點的機器上,經過lsblk命令便可得到卷的名稱,將這個名稱填入deviceFilter設置便可

安裝Rook Toolbox

Rook Toolbox是一個運行在rook-ceph命名空間下的容器,經過它能夠執行一些Ceph的管理任務,建議安裝,仍是挺實用的。建立一個yaml文件:

# rook-toolbox.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rook-ceph-tools
  namespace: rook-ceph
  labels:
    app: rook-ceph-tools
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rook-ceph-tools
  template:
    metadata:
      labels:
        app: rook-ceph-tools
    spec:
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: rook-ceph-tools
        image: rook/ceph:v1.5.3
        command: ["/tini"]
        args: ["-g", "--", "/usr/local/bin/toolbox.sh"]
        imagePullPolicy: IfNotPresent
        env:
          - name: ROOK_CEPH_USERNAME
            valueFrom:
              secretKeyRef:
                name: rook-ceph-mon
                key: ceph-username
          - name: ROOK_CEPH_SECRET
            valueFrom:
              secretKeyRef:
                name: rook-ceph-mon
                key: ceph-secret
        volumeMounts:
          - mountPath: /etc/ceph
            name: ceph-config
          - name: mon-endpoint-volume
            mountPath: /etc/rook
      volumes:
        - name: mon-endpoint-volume
          configMap:
            name: rook-ceph-mon-endpoints
            items:
            - key: data
              path: mon-endpoints
        - name: ceph-config
          emptyDir: {}
      tolerations:
        - key: "node.kubernetes.io/unreachable"
          operator: "Exists"
          effect: "NoExecute"
          tolerationSeconds: 5

而後:

kubectl create -f rook-toolbox.yaml

接着能夠執行下面的命令,進入Rook Toolbox容器:

kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash

而後使用ceph status命令來查看集羣的狀態。正常的話應該能夠看到相似下面的結果:

$ ceph status
  cluster:
    id:     a0452c76-30d9-4c1a-a948-5d8405f19a7c
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,c (age 3m)
    mgr: a(active, since 2m)
    osd: 3 osds: 3 up (since 1m), 3 in (since 1m)

必定要確保health的狀態爲HEALTH_OK,若是不是HEALTH_OK,則須要排查緣由並解決。問題排查指南:https://rook.io/docs/rook/v1.5/ceph-common-issues.html。

部署塊存儲(Provisioning Block Storage)

使用下面的yaml:

# ceph-block-deploy.yaml
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph
  pool: replicapool
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
  csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Retain

而後:

Kubectl create -f ceph-block-deploy.yaml

在這個yaml中,同時定義了名爲rook-ceph-blockStorageClass,用以在pods啓動的時候可以動態建立基於Ceph的塊存儲(經過pool: replicapool的設置指定)。此外,在這個StorageClass中,設定了storageclass.kubernetes.io/is-default-class: "true"。所以,在PersistentVolumeClaim中即便沒有指定storageClassName,Kubernetes也會默認使用Ceph塊存儲來保存app的數據。

部署塊存儲的詳細內容能夠參考:https://rook.io/docs/rook/v1.5/ceph-block.html。

部署對象存儲(Provisioning Object Storage)

使用下面的yaml:

# ceph-s3-deploy.yaml
apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: my-store
  namespace: rook-ceph
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPool:
    failureDomain: host
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  preservePoolsOnDelete: true
  gateway:
    type: s3
    sslCertificateRef:
    port: 80
    # securePort: 443
    instances: 3
  healthCheck:
    bucket:
      disabled: false
      interval: 60s

而後:

kubectl create -f ceph-s3-deploy.yaml

等待幾分鐘後,執行下面的命令:

kubectl -n rook-ceph get pod -l app=rook-ceph-rgw

此時應該能夠在pod的列表中看到名字包含有rgw的pod處於Running狀態。
接下來就是要在對象存儲上建立Bucket。官方提供了基於StorageClass的建立方式。這裏介紹另外一種方式,就是借用MINIO的管理工具來建立。使用下面的shell腳本:

# setup-s3-storage.sh
#! /bin/bash
echo "Creating Ceph User"
CREATE_USER_OUTPUT=`kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- radosgw-admin user create --uid=system-user --display-name=system-user --system`
ACCESS_KEY=$(echo $CREATE_USER_OUTPUT | jq -r ".keys[0].access_key")
SECRET_KEY=$(echo $CREATE_USER_OUTPUT | jq -r ".keys[0].secret_key")
echo "User was created successfully"
echo "S3 ACCESS KEY = $ACCESS_KEY"
echo "S3 SECRET KEY = $SECRET_KEY"

echo "Creating Ceph S3 Bucket"
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- curl https://dl.min.io/client/mc/release/linux-amd64/mc --output mc
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- chmod +x mc
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ./mc config host add mys3 http://rook-ceph-rgw-signals-store/ "$ACCESS_KEY" "$SECRET_KEY"
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ./mc mb mys3/data
echo "Ceph S3 Bucket created successfully"
echo "S3 ACCESS KEY = $ACCESS_KEY"
echo "S3 SECRET KEY = $SECRET_KEY"

在確保了當前機器上安裝了jq後,執行:

chmod +x setup-s3-storage.sh
./setup-s3-storage.sh

此時會輸出S3的Access Key和Secret Key。建立的Bucket名爲data。
驗證Object Storage是否部署成功,首先執行下面的命令進入Rook Toolbox:

kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash

而後執行:

export AWS_HOST=<host>
export AWS_ENDPOINT=<endpoint>
export AWS_ACCESS_KEY_ID=<accessKey>
export AWS_SECRET_ACCESS_KEY=<secretKey>
  • 爲rgw Service的DNS主機名。若是你的Object Storage名爲my-store,那麼主機名就是 rook-ceph-rgw-my-store.rook-ceph
  • 爲rgw Service的端點。執行 kubectl -n rook-ceph get svc rook-ceph-rgw-my-store,而後將ClusterIP和端口號拼接起來做爲endpoint的值
  • accessKey:上一步得到的Access Key
  • secretKey:上一步得到的Secret Key
    如下是一個例子:
export AWS_HOST=rook-ceph-rgw-my-store.rook-ceph
export AWS_ENDPOINT=10.104.35.31:80
export AWS_ACCESS_KEY_ID=XEZDB3UJ6X7HVBE7X7MA
export AWS_SECRET_ACCESS_KEY=7yGIZON7EhFORz0I40BFniML36D2rl8CQQ5kXU6l

接下來,安裝一個s3cmd的工具:

yum --assumeyes install s3cmd

而後隨便寫一些內容到rookObj文件:

echo "Hello Rook" > /tmp/rookObj

而後經過s3cmd,將這個文件保存到S3:

s3cmd put /tmp/rookObj --no-ssl --host=${AWS_HOST} --host-bucket=  s3://data

注意--host-bucket=後的空格。
而後,使用s3cmd從Bucket將文件下載並另存爲另外一個文件:

s3cmd get s3://data/rookObj /tmp/rookObj-download --no-ssl --host=${AWS_HOST} --host-bucket=

最後,經過cat命令,查看下載下來的文件的內容是否正確:

cat /tmp/rookObj-download

若是可以看到Hello Rook的輸出字樣,表示一切正常。接下來就能夠在app中使用Ceph Block Storage和Ceph Object Storage了。

部署對象存儲的詳細內容能夠參考:https://rook.io/docs/rook/v1.5/ceph-object.html

下一步

以後我會使用Microsoft .NET 5,編寫一個Web API應用程序並部署到Kubernetes環境,演示如何在app中使用本文所部署的Ceph Block Storage和Ceph Object Storage。

相關文章
相關標籤/搜索