不管是白痴还是白痴-这就是问题



本月初,即5月3日,宣布了“ Kubernetes中的分布式数据仓库管理系统”的主要版本-Rook 1.0.0 。 一年多以前,我们已经发布了 Rook的概述。 然后,我们被要求谈论其在实践中的使用经验 -现在,在项目历史如此重要的里程碑之时,我们很高兴分享我们积累的印象。

简而言之,Rook是Kubernetes的一组运营商 ,可以完全控制存储解决方案(例如Ceph,EdgeFS,Minio,Cassandra,CockroachDB)的部署,管理和自动恢复。

目前,最成熟(且稳定阶段)的解决方案是rook-ceph-operator

注意 :在与Ceph相关的Rook 1.0.0版本中的重大更改中,可以注意到Ceph Nautilus支持以及将NFS用于CephFS或RGW存储桶的能力。 在其他方面,EdgeFS对beta版本的支持“日趋成熟”。

因此,在本文中,我们:

  • 回答我们使用Rook在Kubernetes集群中部署Ceph时会看到哪些优势的问题;
  • 分享在生产中使用Rook的经验和印象;
  • 我们将告诉您为什么我们对Rook以及对他的计划说“是!”。

让我们从一般的概念和理论开始。

“我在一个白痴中占有优势!” (未知的棋手)




Rook的主要优势之一是通过Kubernetes机制与数据仓库进行交互。 这意味着您不再需要将用于配置Ceph的命令从传单复制到控制台。

-是否要部署在CephFS集群中? 只需编写一个Yaml文件!
-什么? 是否要使用S3 API部署对象存储? 只需编写第二个yaml文件!

Rook由典型操作员的所有规则创建。 与它的交互是在CRD(自定义资源定义)的帮助下发生的,我们在其中描述了所需的Ceph实体的特征(由于这是唯一的稳定实现,因此,除非另有明确说明,否则默认情况下,本文将介绍Ceph) 。 根据指定的参数,操作员将自动执行设置所需的命令。

让我们使用创建对象存储(或更确切地说CephObjectStoreUser的示例来查看具体CephObjectStoreUser

 apiVersion: ceph.rook.io/v1 kind: CephObjectStore metadata: name: {{ .Values.s3.crdName }} namespace: kube-rook spec: metadataPool: failureDomain: host replicated: size: 3 dataPool: failureDomain: host erasureCoded: dataChunks: 2 codingChunks: 1 gateway: type: s3 sslCertificateRef: port: 80 securePort: instances: 1 allNodes: false --- apiVersion: ceph.rook.io/v1 kind: CephObjectStoreUser metadata: name: {{ .Values.s3.crdName }} namespace: kube-rook spec: store: {{ .Values.s3.crdName }} displayName: {{ .Values.s3.username }} 

清单中指示的参数是相当标准的,不太可能需要注释,但是您应该特别注意模板变量中突出显示的参数。

一般的工作方案归结为以下事实:通过YAML文件,我们对资源进行“排序”,操作员为此对资源执行必要的命令,并向我们返回“不真实”的机密,以便我们可以继续工作(请参见下文) 。 根据上面指示的变量,将组成命令和密码的名称。

这是什么样的队伍? 创建用于对象存储的用户时,pod中的Rook语句将执行以下操作:

 radosgw-admin user create --uid="rook-user" --display-name="{{ .Values.s3.username }}" 

该命令的结果将是JSON结构:

 { "user_id": "rook-user", "display_name": "{{ .Values.s3.username }}", "keys": [ { "user": "rook-user", "access_key": "NRWGT19TWMYOB1YDBV1Y", "secret_key": "gr1VEGIV7rxcP3xvXDFCo4UDwwl2YoNrmtRlIAty" } ], ... } 

Keys是将来的应用程序通过S3 API访问对象存储所需要的。 Rook运算符会选择它们并将它们作为秘密放入名称空间中,名称为rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}

要使用此机密中的数据,只需将它们作为环境变量添加到容器中即可。 作为示例,我将为Job提供一个模板,在该模板中,我们将自动为每个用户环境创建存储桶:

 {{- range $bucket := $.Values.s3.bucketNames }} apiVersion: batch/v1 kind: Job metadata: name: create-{{ $bucket }}-bucket-job annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "2" spec: template: metadata: name: create-{{ $bucket }}-bucket-job spec: restartPolicy: Never initContainers: - name: waitdns image: alpine:3.6 command: ["/bin/sh", "-c", "while ! getent ahostsv4 rook-ceph-rgw-{{ $.Values.s3.crdName }}; do sleep 1; done" ] - name: config image: rook/ceph:v1.0.0 command: ["/bin/sh", "-c"] args: ["s3cmd --configure --access_key=$(ACCESS-KEY) --secret_key=$(SECRET-KEY) -s --no-ssl --dump-config | tee /config/.s3cfg"] volumeMounts: - name: config mountPath: /config env: - name: ACCESS-KEY valueFrom: secretKeyRef: name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }} key: AccessKey - name: SECRET-KEY valueFrom: secretKeyRef: name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }} key: SecretKey containers: - name: create-bucket image: rook/ceph:v1.0.0 command: - "s3cmd" - "mb" - "--host=rook-ceph-rgw-{{ $.Values.s3.crdName }}" - "--host-bucket= " - "s3://{{ $bucket }}" ports: - name: s3-no-sll containerPort: 80 volumeMounts: - name: config mountPath: /root volumes: - name: config emptyDir: {} --- {{- end }} 

该工作中列出的所有活动都没有超出Kubernetes的范围。 YAML文件中描述的结构被折叠到Git存储库中并重复使用。 在此,我们为DevOps工程师和整个CI / CD流程带来了巨大的收益。

随着Rook和Rados的喜悦


使用一堆Ceph + RBD对将体积安装到Pod施加了一定的限制。

特别是,名称空间必须具有访问Ceph的秘密,以便有状态的应用程序可以运行。 如果您的命名空间中有2-3个环境也可以:您可以手动复制机密。 但是,如果每个开发人员功能都使用自己的名称空间创建一个单独的环境怎么办?

我们在shell-operator的帮助下解决了这个问题,该操作器自动将机密复制到新的命名空间中( 本文描述了这种钩子的示例)。

 #! /bin/bash if [[ $1 == “--config” ]]; then cat <<EOF {"onKubernetesEvent":[ {"name": "OnNewNamespace", "kind": "namespace", "event": ["add"] } ]} EOF else NAMESPACE=$(kubectl get namespace -o json | jq '.items | max_by( .metadata.creationTimestamp ) | .metadata.name') kubectl -n ${CEPH_SECRET_NAMESPACE} get secret ${CEPH_SECRET_NAME} -o json | jq ".metadata.namespace=\"${NAMESPACE}\"" | kubectl apply -f - fi 

但是,使用Rook时,根本不存在此问题。 挂载过程使用您自己的基于FlexvolumeCSI的驱动程序(仍处于beta版)进行,因此不需要秘密。

Rook自动解决了许多问题,这鼓励我们在新项目中使用它。

新兵围困


我们通过部署Rook和Ceph来完成实践部分,以便进行我们自己的实验。 为了攻入这座坚不可摧的塔楼,这很容易,开发商准备了头盔包。 让我们下载它:

 $ helm fetch rook-master/rook-ceph --untar --version 1.0.0 

rook-ceph/values.yaml可以在rook-ceph/values.yaml文件中找到许多不同的设置。 最重要的是,指定代理和搜索的容忍度。 为什么您可以使用污点/公差机制,我们在本文中进行了详细介绍

简而言之,我们不希望将带有客户端应用程序的容器放置在用于存储数据的磁盘所在的相同节点上。 原因很简单:Rook代理的工作方式不会影响应用程序本身。

因此, rook-ceph/values.yaml喜欢的编辑器打开文件rook-ceph/values.yaml并在末尾添加以下代码块:

 discover: toleration: NoExecute tolerationKey: node-role/storage agent: toleration: NoExecute tolerationKey: node-role/storage mountSecurityMode: Any 

对于每个保留用于数据存储的节点,请添加相应的污点:

 $ kubectl taint node ${NODE_NAME} node-role/storage="":NoExecute 

然后使用以下命令安装Helm-chart:

 $ helm install --namespace ${ROOK_NAMESPACE} ./rook-ceph 

现在,您需要创建一个集群并指示OSD的位置:

 apiVersion: ceph.rook.io/v1 kind: CephCluster metadata: clusterName: "ceph" finalizers: - cephcluster.ceph.rook.io generation: 1 name: rook-ceph spec: cephVersion: image: ceph/ceph:v13 dashboard: enabled: true dataDirHostPath: /var/lib/rook/osd mon: allowMultiplePerNode: false count: 3 network: hostNetwork: true rbdMirroring: workers: 1 placement: all: tolerations: - key: node-role/storage operator: Exists storage: useAllNodes: false useAllDevices: false config: osdsPerDevice: "1" storeType: filestore resources: limits: memory: "1024Mi" requests: memory: "1024Mi" nodes: - name: host-1 directories: - path: "/mnt/osd" - name: host-2 directories: - path: "/mnt/osd" - name: host-3 directories: - path: "/mnt/osd" 

检查Ceph状态-希望看到HEALTH_OK

 $ kubectl -n ${ROOK_NAMESPACE} exec $(kubectl -n ${ROOK_NAMESPACE} get pod -l app=rook-ceph-operator -o name -o jsonpath='{.items[0].metadata.name}') -- ceph -s 

同时,检查带有客户端应用程序的Pod没有到达为Ceph保留的节点:

 $ kubectl -n ${APPLICATION_NAMESPACE} get pods -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName 

配置了其他可选组件。 有关它们的更多信息,请参见文档 。 对于管理,我们强烈建议安装仪表板和工具箱。

白痴:白痴足以应付一切吗?


如您所见,Rook的开发如火如荼。 但是仍然存在一些问题,使我们无法完全放弃Ceph的手动配置:

  • 没有Rook驱动程序可以导出有关已安装块的使用情况的度量标准,这使我们无法进行监视。
  • Flexvolume和CSI 不知道如何调整卷大小(与同一个RBD不同),因此Rook失去了一个有用的(有时是非常必要的!)工具。
  • Rook仍然不如常规Ceph灵活。 如果我们要配置用于将CephFS元数据存储在SSD上的池,并将数据本身存储在HDD上,则需要在CRUSH映射中手动注册各个设备组。
  • 尽管rook-ceph-operator被认为是稳定的,但是当将Ceph从版本13更新到14时,目前仍然存在某些问题。

结论


“现在,Rook通过典当与外界隔绝,但我们相信有一天她将在聚会中起决定性作用!” (为该文章专门发明了一个报价)

Rook项目无疑赢得了我们的心-我们相信[具有所有优点和缺点]它绝对值得您关注。

我们的进一步计划归结为使rook-ceph成为addon-operator的模块,这将使其在我们的许多Kubernetes集群中的使用更加简单和方便。

聚苯乙烯


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN451818/


All Articles