基于 Kubernetes 的容器化 Vertica

Kubernetes 是一个开源容器协调平台,可自动管理基础架构资源并为容器化应用程序大规模调度任务。Kubernetes 通过将应用程序与基础架构分离的声明性模型实现自动化。管理员向 Kubernetes 提供应用程序的所需状态,Kubernetes 部署应用程序并努力维护其所需状态。这使管理员可以随着业务需求的发展而更新应用程序,而不必担心实施细节。

应用程序由资源组成,这些资源是您从 Kubernetes 资源类型创建的有状态对象。Kubernetes 通过 Kubernetes API 提供对资源类型的访问权限,该 API 是一种将资源类型公开为端点的 HTTP API。创建资源的最常见方法是使用 YAML 格式的清单文件,该文件定义资源的所需状态。您可以使用 kubectl 命令行工具从 Kubernetes API 请求该类型的资源实例。除了默认资源类型之外,您还可以扩展 Kubernetes API 并将自己的资源类型定义为自定义资源定义 (CRD)。

为了管理基础架构,Kubernetes 使用主机来运行控制平面,并指定一个或多个主机作为工作节点。控制平面是服务和控制器的集合,它们维护 Kubernetes 对象的所需状态并在工作节点上调度任务。工作节点完成控制平面分配的任务。正如可以创建 CRD 来扩展 Kubernetes API 一样,您可以创建自定义控制器来维护从 CRD 创建的自定义资源 (CR) 的状态。

Vertica 自定义资源定义和自定义控制器

Vertica CRD 扩展了 Kubernetes API,以便您可以创建将 Eon 模式数据库部署为 StatefulSet 的自定义资源。此外,Vertica 还提供了 VerticaDB 操作器,这是一个自定义控制器,可维护 CR 的所需状态并自动执行生命周期任务。其结果是一个自我修复、高可用性和可扩展的 Eon 模式数据库,该数据库需要极少的人工干预。

为了简化部署,Vertica 将 CRD 和操作器打包在 Helm 图表中。Helm 图表将清单文件捆绑到单个包中,以使用单个命令创建多个资源类型对象。

自定义资源定义架构

Vertica CRD 创建一个 StatefulSet,它是一种使用临时 Kubernetes 对象持久存储数据的工作负载资源类型。下图描述了 Vertica CRD 架构:

VerticaDB 操作器

操作器是一种命名空间范围的自定义控制器,它维护自定义对象的状态并自动执行管理员任务。操作器监视对象,并将其当前状态与自定义资源中声明的所需状态进行比较。当前状态与所需状态不匹配时,操作器会努力将对象还原到所需状态。

除了状态维护,操作器还执行以下操作:

  • 安装 Vertica

  • 创建 Eon 模式数据库

  • 升级 Vertica

  • 恢复现有的 Eon 模式数据库

  • 重新启动和重新安排 DOWN pod 以维持仲裁

  • 规模子群集

  • 管理 pod 的服务

  • 监控 pod 运行状况

  • 处理内部和外部流量的负载均衡

为了验证对自定义资源的更改,操作器查询准入控制器,这是一个为自定义资源中的可变状态提供规则的 webhook。

Vertica 使操作器和准入控制器通过 OperatorHub.io 或以 Helm 图表形式提供。有关以这两种方式安装操作器和准入控制器的详细信息,请参阅安装 Vertica DB 操作器

Vertica pod

pod 本质上是一个或多个逻辑分组容器的包装器。这些容器在共享的执行环境中消耗主机节点资源。除了共享资源之外,pod 还扩展容器以与 Kubernetes 服务交互。例如,您可以分配标签以将 pod 与其他对象关联,并且您可以实施亲和性规则以在特定主机节点上调度 pod。

DNS 名称提供了 pod 生命周期之间的连续性。为每个 pod 都分配了一个有序且稳定的 DNS 名称,该名称在其群集中是唯一的。当 Vertica pod 发生故障时,重新调度的 pod 使用与其前身相同的 DNS 名称。如果 pod 需要在生命周期之间持久存储数据,您可以在其文件系统中挂载自定义卷

重新调度的 pod 需要有关环境的信息才能成为群集的一部分。此信息由 Downward API 提供。环境信息(例如超级用户密码 Secret)挂载在 /etc/podinfo 目录下。

sidecar 容器

pod 运行多个容器以紧密耦合参与同一进程的容器。Vertica pod 允许使用 sidecar,它是一个实用程序容器,可用于访问和执行 Vertica 服务器进程的实用程序任务。

例如,日志记录是一项常见的实用程序任务。惯用的 Kubernetes 实践是从主机节点上的标准输出和标准错误中检索日志以进行日志聚合。为了促成这种实践,Vertica 提供了 vlogger sidecar 映像,该映像可将 vertica.log 的内容发送到主机节点上的标准输出。

如果 sidecar 需要持久存储数据,您可以在 sidecar 文件系统中挂载自定义卷

有关实施的详细信息,请参阅创建自定义资源

持久存储

pod 是一个短暂的不可变对象,需要访问外部存储才能在生命周期之间持久存储数据。为了持久存储数据,操作器使用以下 API 资源类型:

  • StorageClass:表示外部存储提供程序。您必须从自定义资源单独创建一个 StorageClass 对象,并使用 local.storageClassName 配置参数设置此值。

  • PersistentVolume (PV):挂载在 pod 中以持久存储数据的存储单元。您可以动态或静态配置 PV。每个 PV 引用一个 StorageClass。

  • PersistentVolumeClaim (PVC):pod 用于描述其 StorageClass 和存储要求的资源类型。

pod 在其文件系统中挂载一个 PV 来持久存储数据,但默认情况下 PV 不与 pod 关联。不过,pod 与在存储要求中包含 StorageClass 的 PVC 相关联。当 pod 使用 PVC 请求存储时,操作器会观察此请求,然后搜索可满足存储要求的 PV。如果操作器找到 PV,它会将 PVC 绑定到该 PV,并将该 PV 作为卷挂载到 pod 中。如果操作器没有找到 PV,则它必须动态配置一个 PV,或者管理员必须手动配置一个 PV,然后操作器才能将其绑定到 pod。

PV 持久存储数据,因为它们独立于 pod 生命周期而存在。当 pod 发生故障或重新调度时,对 PV 没有影响。有关 StorageClass、PersistentVolume 和 PersistentVolumeClaim 的更多详细信息,请参阅 Kubernetes 文档

StorageClass 要求

StorageClass 影响 Vertica 服务器环境和操作器的工作方式。若要获得最佳性能,请考虑以下事项:

  • 如果未设置 local.storageClassName 配置参数,则操作器使用默认的存储类。如果您使用默认存储类,请确认它满足生产工作负载的存储要求。

  • 选择一种将推荐的存储格式类型用作其 fsType 的 StorageClass。

  • 使用动态卷配置。操作器需要按需卷配置以根据需要创建 PV。

本地卷挂载

操作器在每个 pod 的 /home/dbadmin/local-data/ 目录中挂载一个 PVC 来持久存储数据。以下每个子目录都是支持 PVC 的卷的子路径

  • /data:存储编录和任何临时文件。您可以使用 local.dataPath 参数自定义此路径。

  • /depot:改善了重新调度的 pod 中的存储库预热。您可以使用 local.depotPath 参数自定义此路径。

  • /opt/vertica/config:在重新启动之间持久存储配置目录的内容。

  • /opt/vertica/log:在 pod 重新启动之间持久存储日志文件。

默认情况下,挂载在 /local-data 目录中的每个路径都归 dbadmin 用户和 verticadb 组所有。有关详细信息,请参阅关于 Vertica 创建的 Linux 用户及其权限

自定义卷挂载

在以下任一情况下,您可能需要在 pod 生命周期之间持久存储数据:

  • 外部进程执行一个需要长期访问 Vertica 服务器数据的任务。

  • 您的自定义资源在 Vertica pod 中包含一个 sidecar 容器

您可以在 Vertica pod 或 sidecar 文件系统中挂载自定义卷。要在 Vertica pod 中挂载自定义卷,请在 CR 的 spec 部分添加定义。要在 sidecar 中挂载自定义卷,请将其添加到 sidecars 数组的元素中。

CR 要求您为每个自定义卷提供卷类型和名称。CR 接受任何 Kubernetes 卷类型。volumeMounts.name 值标识 CR 中的卷,且具有以下要求和限制:

  • 它必须与 volumes.name 参数设置相匹配。

  • 它在 /local-data/podinfo/licensing 挂载目录中的所有卷中必须是唯一的。

有关如何在 Vertica 服务器容器或 sidecar 中挂载自定义卷的说明,请参阅创建自定义资源

服务对象

基于 Kubernetes 的 Vertica 提供两个服务对象:无头服务(无需进行配置即可维护每个 pod 的 DNS 记录和有序名称)和负载均衡服务(用于管理群集中 pod 的内部流量和外部客户端请求)。

负载均衡服务

每个子群集使用一个负载均衡服务对象。您可以使用自定义资源中的 subclusters[i].serviceName 参数手动为负载均衡服务对象分配名称。当您要执行以下操作时,分配名称非常有用:

  • 将流量从单个客户端定向到多个子群集。

  • 更灵活地按工作负载扩展子群集。

  • 通过自定义服务对象名称标识子群集。

要配置服务对象的类型,请使用自定义资源中的 subclusters[i].serviceType 参数来定义 Kubernetes 服务类型。Vertica 支持以下服务类型:

  • ClusterIP:默认服务类型。此服务提供内部负载均衡,并设置仅可从子群集内部访问的稳定 IP 和端口。

  • NodePort:提供外部客户端访问。您可以为子群集中的每个主机节点指定一个端口号,以便为客户端连接打开。

  • LoadBalancer:使用云提供商负载均衡器根据需要创建 NodePort 和 ClusterIP 服务。有关实施的详细信息,请参阅 Kubernetes 文档 和云提供商文档。

由于本机 Vertica 负载均衡会干扰 Kubernetes 服务对象,因此 Vertica 建议您允许 Kubernetes 服务管理子群集的负载均衡。您可以在 Kubernetes 群集中配置本机 Vertica 负载均衡器,但会收到意外结果。例如,如果您将 Vertica 负载均衡策略设置为 ROUNDROBIN,则负载均衡显示为随机。

有关 Kubernetes 服务的更多详细信息,请参阅 Kubernetes 官方文档

安全注意事项

基于 Kubernetes 的 Vertica 支持将 TLS 和 mTLS 用于资源对象之间的通信。您必须在您的环境中手动配置 TLS。有关详细信息,请参阅TLS 协议

准入控制器 webhook TLS 证书

VerticaDB 操作器 Helm 图表包含一个准入控制器 webhook,该 webhook 用于验证对自定义资源所做的更改。该 webhook 需要使用 TLS 证书进行数据加密。

您用于安装 VerticaDB 操作器的方法决定了您如何管理准入控制器的 TLS 证书。如果您使用 Operator Lifecycle Manager (OLM) 并通过 OperatorHub.io 安装 VerticaDB 操作器,则 OLM 会为 webhook 创建并挂载一个自签名证书,这不需要额外的操作。如果您使用 Helm 图表安装 VerticaDB 操作器,则必须使用以下选项之一手动管理准入控制器 TLS 证书:

  • cert-manager。此 Kubernetes 加载项为您的资源对象生成和管理证书。它在 Kubernetes 中具有内置支持。有关安装的详细信息,请参阅安装 Vertica DB 操作器

  • 自定义证书。要使用自定义证书,您必须将证书凭据和 PEM 编码的 CA 捆绑包作为参数传递给 Helm 图表。有关详细信息,请参阅“安装 Vertica DB 操作器”和“Helm 图表参数”。

默认情况下,Helm 图表安装使用 cert-manager,除非您提供自定义证书。如果您未安装 cert-manager 或未向 Helm 图表提供自定义证书,则在安装 Helm 图表时会收到错误消息。

自定义 TLS 证书

您的自定义资源可能需要多个自定义 TLS 证书来保护内部和外部通信。例如,您可能需要自签名证书颁发机构 (CA) 捆绑包来向支持的存储位置进行身份验证,并为不同的客户端连接提供多个证书。您可以使用 certSecrets 自定义资源参数在 Vertica 服务器容器中挂载一个或多个自定义证书。每个证书都挂载在位于 /certs/cert-name/key 的容器中。

操作器管理对证书的更改。如果您更新现有证书,操作器将替换 Vertica 服务器容器中的证书。如果您添加或删除证书,操作器将使用新配置重新调度 pod。

有关将自定义证书添加到自定义资源的详细信息,请参阅创建自定义资源

系统配置

最佳实践是在主机节点上进行系统配置,以便 pod 从主机节点继承这些设置。有了这种策略,无需为每个 pod 提供特许安全上下文以在主机上进行系统配置。

要手动配置主机节点,请参考以下部分:

dbadmin 帐户必须使用 Dbadmin 身份验证访问中描述的身份验证技术之一。