这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

容器化 Vertica

Vertica Eon 模式利用容器技术来满足现代应用程序开发和运营工作流的需求,这些工作流必须快速高效地跨各种基础架构交付软件。容器化 Vertica [通过自动化工具支持 Kubernetes](/zh-cn/containerized/containerized-on-k8s/),以帮助维护您的环境状态,同时最大限度地减少中断和人工干预。

容器化 Vertica 具有以下优势:

  • 性能:Eon 模式将计算与存储分开,它为有状态的容器化应用程序提供了最佳架构。Eon 模式子群集可以面向特定的工作负载并根据当前的计算需求进行弹性扩展。

  • 高可用性:Vertica 容器提供了一个一致的、可重复的环境,您可以快速部署该环境。如果数据库主机或服务出现故障,您可以轻松更换资源。

  • 资源利用:容器是一个运行时环境,它将应用程序及其依赖项打包在独立的进程中。这种隔离允许容器化应用程序在不产生干扰的情况下共享硬件,从而提供精细的资源控制和成本节约。

  • 灵活性:Kubernetes 是事实上的容器协调平台。它由公有云和私有云提供商的大型生态系统提供支持。

容器化 Vertica 生态系统

Vertica 为生产和开发环境提供各种工具和工件。容器化 Vertica 生态系统包括以下内容:

  • Vertica Helm 图表Helm 是 Kubernetes 包管理器,它将用来部署 Kubernetes 对象的 YAML 清单捆绑到一个包中。从 Vertica Helm 图表存储库下载 Vertica Helm 图表。

  • 自定义资源定义 (CRD):CRD 是共享的全局对象,它使用您的自定义资源类型扩展 Kubernetes API。使用 CRD 实例化自定义资源 (CR),这是一个可部署的对象,用于定义 Kubernetes 上 Eon 模式数据库的状态。

  • VerticaDB 操作器:该操作器是一个自定义控制器,用于监控您的 CR 状态并自动执行管理员任务。如果当前状态与声明的状态不同,则操作器会努力纠正当前状态。

  • 准入控制器:准入控制器使用一个 webhook,操作器通过查询该 webhook 来验证对 CR 中可变状态的更改。

  • VerticaDB vlogger:vlogger 是用于部署 sidecar 实用程序容器的轻量级映像。sidecar 将日志从 Vertica 服务器容器中的 vertica.log 发送到主机节点上的标准输出,以简化日志聚合。

  • Vertica Community Edition (CE) 映像:CE 映像是受限企业模式 Vertica 社区版 (CE) 许可证的容器化版本。CE 映像提供了一个由示例数据库和开发人员工具组成的测试环境。

    除了预先构建的 CE 映像之外,您还可以使用 Vertica one-node-ce GitHub 存储库中提供的工具构建自定义 CE 映像。

  • 公共存储选项:Vertica 支持各种公有云和私有云存储提供程序。有关受支持的存储提供程序的列表,请参阅容器化环境

  • UDx 开发工具:UDx-container GitHub 存储库提供了构建容器的工具,该容器对创建 C++ Vertica 用户定义扩展所需的二进制文件、库和编译器进行打包。有关在 C++ 中扩展 Vertica 的更多详细信息,请参阅 C++ SDK

Vertica 映像

下表描述了 Vertica 为服务器和自动化工具提供的映像:

创建自定义 Vertica 映像

Vertica 集成者指南中的创建 Vertica 映像教程提供了 GitHub 上承载的 Dockerfile 的逐行说明。您可以添加依赖项来复制您的开发和生产环境。

1 - 基于 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 身份验证访问中描述的身份验证技术之一。

2 - Vertica 数据库操作器

Vertica 操作器可自动执行基于 Kubernetes 的 Vertica 管理员必须手动执行的、容易出错且耗时的任务。操作器:

  • 安装 Vertica

  • 创建 Eon 模式数据库

  • 升级 Vertica

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

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

  • 规模子群集

  • 管理 pod 的服务

  • 监控 pod 运行状况

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

Vertica 操作器是使用 SDK 操作器框架的 Go 二进制文件。它在自己的 pod 中运行,并且是命名空间范围内的,可将对象的任何故障限制在其命名空间中。

有关安装和升级操作器的详细信息,请参阅安装 Vertica DB 操作器

监控所需状态

每个命名空间都允许有一个操作器 pod,它充当自定义控制器并监控该命名空间内自定义资源对象的状态。操作器使用控制循环机制来协调状态更改,方法是调查源于自定义资源实例的状态更改通知并定期对当前状态与所需状态进行比较。

如果操作器检测到所需状态的更改,它会确定发生了什么更改并将当前状态与新的所需状态相协调。例如,如果用户从自定义资源实例中删除了一个子群集并成功保存了更改,则操作器将删除 Kubernetes 中相应的子群集对象。

验证状态更改

verticadb-operator Helm 图表包含一个准入控制器,它使用 webhook 来防止对自定义资源进行无效的状态更改。当您保存对自定义资源的更改时,准入控制器 webhook 会查询一个为自定义资源中的可变状态提供规则的 REST 端点。如果所做的更改违反了状态规则,准入控制器会阻止更改并返回错误。例如,如果您尝试保存违反 K-Safety 的更改,则会返回错误。

限制

操作器有以下限制:

  • 您必须手动配置 TLS。有关详细信息,请参阅基于 Kubernetes 的容器化 Vertica

  • 资源类型名称不能包含下划线字符。资源类型名称用于完全限定域名 (FQDN),并且 FQDN 不允许使用下划线字符。您必须提供一个符合 Kubernetes 准则 的有效名称。

    例如,Vertica 服务器生成的默认子群集名称为 default_subcluster。此名称对 Kubernetes 资源类型无效。

  • Vertica 建议不要使用大型群集功能。如果某一个控制节点发生故障,可能会导致一半以上的数据库节点发生故障。这会导致数据库失去仲裁。

  • 备份和还原是一个手动过程。

  • 不支持自动缩放

  • 在 Kubernetes 之外的群集之间导入和导出数据要求您公开具有 NodePort 或 LoadBalancer 服务类型的服务并正确配置网络。

2.1 - 安装 Vertica DB 操作器

自定义资源定义 (CRD)、VerticaDB 操作器和准入控制器协同维护环境状态并自动执行任务:

  • CRD 扩展 Kubernetes API 以提供自定义对象。它用作自定义资源 (CR) 实例的蓝图,用于指定环境的所需状态。

  • VerticaDB 操作器是一个自定义控制器,用于监控 CR 实例以维护 VerticaDB 对象的所需状态。您可以为每个命名空间部署一个 VerticaDB 操作器,该操作器仅监控此命名空间内的 VerticaDB 对象。

  • 准入控制器是一个 webhook,它查询 REST 端点以验证对 CR 实例中可变状态的更改。

先决条件

安装选项

Vertica 提供了两个单独的选项来安装 VerticaDB 操作器和准入控制器:

使用 OperatorHub.io 安装

OperatorHub.io 是允许供应商共享 Kubernetes 操作器的注册表。每个供应商都必须遵守包装指南以简化用户采用。

要从 OperatorHub.io 安装 VerticaDB 操作器,请导航到 Vertica 操作器页面,按照安装说明进行操作。

使用 Helm 图表安装

Vertica 将 VerticaDB 操作器和准入控制器打包在 Helm 图表中。基于 Kubernetes 的 Vertica 允许每个命名空间有一个操作器实例。

为准入控制器配置 TLS

在安装 VerticaDB Helm 图表之前,必须为准入控制器配置 TLS。准入控制器使用一个需要借助于 TLS 证书进行数据加密的 webhook。选择以下数据加密选项之一:

  • cert-manager(用于生成和管理证书)。对于使用自签名证书颁发机构 (CA) 的环境,Vertica 建议使用 cert-manager。

  • 自定义证书

默认情况下,自定义资源使用 cert-manager,除非您提供自定义证书。如果您不安装 cert-manager 或不提供自定义证书,则无法安装 VerticaDB 操作器 Helm 图表。

安装 cert-manager

cert-manager 在 GitHub 存储库中作为 YAML 清单提供。

  1. 使用 kubectl 安装 cert-manager:

    $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
    

    安装可能耗费几分钟时间。

  2. 验证 cert-manager 安装:

    $ kubectl get pods --namespace cert-manager
    NAME                                       READY   STATUS    RESTARTS   AGE
    cert-manager-7dd5854bb4-skks7              1/1     Running   5          12d
    cert-manager-cainjector-64c949654c-9nm2z   1/1     Running   5          12d
    cert-manager-webhook-6bdffc7c9d-b7r2p      1/1     Running   5          12d
    

有关 cert-manager 安装验证的更多详细信息,请参阅 cert-manager 文档

定义自定义证书

自定义证书需要 TLS 密钥,该密钥使用准入控制器 webhook 的完全限定域名 (FDQN) 来设置使用者备用名称 (SAN)。您可以使用以下格式在配置文件中设置 SAN:

[alt_names]
DNS.1 = verticadb-operator-webhook-service.namespace.svc
DNS.2 = verticadb-operator-webhook-service.namespace.svc.cluster.local

有关 TLS 和 Vertica 的详细信息,请参阅 TLS 协议

在安装 VerticaDB 操作器和准入控制器 Helm 图表时,您可以传递参数以自定义 Helm 图表。在将自定义证书作为参数传递之前,将它们隐藏在 Secret 中。以下命令创建用于存储 TLS 密钥、TLS 证书和 CA 证书的 Secret:

$ kubectl create secret generic tls-secret --from-file=tls.key=/path/to/tls.key --from-file=tls.crt=/path/to/tls.crt --from-file=ca.crt=/path/to/ca.crt

安装 VerticaDB 操作器和准入控制器 Helm 图表时使用 tls-secret。有关详细示例,请参阅 Helm 图表参数

授予操作器权限

您必须具有群集管理员权限才能安装操作器 Helm 图表。在某些情况下,您可能希望为具有较低权限的用户授权,以在特定命名空间中安装操作器。您可以使用预配置的 Kubernetes 服务帐户授予这些操作器权限。

Vertica 利用 Kubernetes RBAC 向服务帐户授予执行操作器操作的权限。您可以将操作器权限授予 Role 资源类型,然后定义将该 Role 与服务帐户相关联的 RoleBinding 资源类型。任何用户都可以使用 serviceAccountOverride 参数将服务帐户名称传递给 helm install 命令并安装操作器。

以下步骤使用 YAML 文件 operator-rbac.yaml。此示例文件定义了 ServiceAccount、Role 和 RoleBinding 以向服务帐户授予所需的权限。它在 vertica-kubernetes GitHub 存储库中提供:

  1. 将 operator-rbac.yaml 应用于命名空间:

    $ kubectl apply -n namespace -f https://github.com/vertica/vertica-kubernetes/releases/latest/download/operator-rbac.yaml
    
  2. 使用 kubectl get 验证所做的更改:

    • 服务帐户:

      $ kubectl get serviceaccounts
      NAME                                    SECRETS   AGE
      default                                 1         71m
      verticadb-operator-controller-manager   1         69m
      
    • 正确命名空间中的 Role:

      $ kubectl get roles -n namespace
      NAME                                      CREATED AT
      verticadb-operator-leader-election-role   2022-04-14T16:26:53Z
      verticadb-operator-manager-role           2022-04-14T16:26:53Z
      
    • 正确命名空间中的 RoleBinding:

      $ kubectl get rolebinding -n namespace
      NAME                                             ROLE                                           AGE
      verticadb-operator-leader-election-rolebinding   Role/verticadb-operator-leader-election-role   73m
      verticadb-operator-manager-rolebinding           Role/verticadb-operator-manager-role           73m
      

安装 Helm 图表

在安装 Helm 图表之前,必须使用以下选项之一为准入控制器配置 TLS:

以下安装步骤使用自定义证书:

  1. 将 Vertica Helm 图表添加到您的存储库。以下命令安装 CRD Helm 图表并将其命名为 vertica-charts 以供将来参考:

    $ helm repo add vertica-charts https://vertica.github.io/charts
    
  2. 更新 Helm 存储库以确保您使用的是最新版本的存储库:

    $ helm repo update
    
  3. 安装操作器 Helm 图表。以下示例演示了最常见的 Helm 图表配置。有关 Helm 图表选项和参数的详细信息,请参阅 Helm 图表参数

    输入以下命令之一以自定义 Helm 图表安装:

    • 默认配置。以下命令需要群集管理员权限:

      $ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator
      
    • 自定义证书。使用 webhook.caBundlewebhook.tlsSecret 传递自定义证书。以下命令需要群集管理员权限,并使用定义自定义证书中创建的 tls-secret Secret:

      $ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator \
          --set webhook.caBundle=$(cat /path/to/root.pem | base64 --wrap 0) \
          --set webhook.tlsSecret=tls-secret
      
    • 服务帐户覆盖。使用服务帐户允许没有群集管理员权限的用户安装操作器。使用 serviceAccountNameOverride 参数传递服务帐户:

      $ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator \
          --set serviceAccountNameOverride=service-account-name
      

      有关详细信息,请参阅授予操作器安装权限

    • 不安装准入控制器 webhook。部署 webhook 需要群集范围的权限,而安装操作器不需要这些权限。如果为您使用的服务帐户授予了安装操作器(而不是 webhook)所需的权限,请为该服务帐户提供 serviceAccountNameOverride,并将 webhook.enable 设置为 false 以仅部署操作器:

      $ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator \
          --set serviceAccountNameOverride=service-account-name
          --set webhook.enable=false
      

有关 helm install的更多详细信息,请参阅官方文档

升级操作器

安装 Helm 图表时包含 CRD,但 helm install 命令不会覆盖现有 CRD。要升级操作器,您必须使用 GitHub 存储库中的清单更新 CRD。使用 CRD 升级操作器需要以下先决条件:

此外,必须升级 VerticaAutoscaler 自定义资源,即使您在您的环境中不使用它也是如此。VerticaAutoscaler CR 随操作器一起安装,并作为单独的 YAML 清单进行维护。升级 VerticaAutoscaler CR 以确保您的操作器完全升级。

使用 kubectl apply 升级 VerticaDB 操作器和 VerticaAutoscaler 的 CRD:

  1. 升级 VerticaDB 操作器 CRD:

    $ kubectl apply -f https://github.com/vertica/vertica-kubernetes/releases/latest/download/verticadbs.vertica.com-crd.yaml
    
  2. 升级 VerticaAutoscaler CRD:

    $ kubectl apply -f https://github.com/vertica/vertica-kubernetes/releases/latest/download/verticaautoscalers.vertica.com-crd.yaml
    

2.2 - Helm 图表参数

下表描述了 VerticaDB 操作器和准入控制器 Helm 图表的可用设置。

2.3 - Red Hat OpenShift 集成

Red Hat OpenShift 是一个混合云平台,可提供增强的安全功能并更好地控制 Kubernetes 群集。此外,OpenShift 还提供了 OperatorHub,它是一个满足 OpenShift 要求的操作器编录。

有关 OpenShift 平台的全面说明,请参阅 Red Hat OpenShift 官方文档

具有安全上下文约束的增强安全性

OpenShift 要求每个部署都使用安全上下文约束 (SCC) 来实施增强的安全措施。SCC 使管理员可以控制群集中 pod 的权限。例如,您可以在多用户环境中限制特定用户的命名空间访问权限。

默认 SCC

OpenShift 提供默认 SCC,无需手动配置即可提供一系列安全功能。基于 Kubernetes 的 Vertica 支持privileged SCC,这是最严格的默认 SCC。privileged SCC 允许 Vertica 将用户和组 ID 分配给群集中的 Kubernetes 对象。此外,privileged SCC 具有下列可用于在 pod 之间启用内部 SSH 通信的 Linux 功能:

  • SYS_CHROOT

  • AUDIT_WRITE

anyuid-extra 自定义 SCC

Vertica 提供了一个名为 anyuid-extra 的自定义 SCC,您可以通过创建该自定义 SCC 来扩展 anyuid SCC。如果您希望 Vertica 的运行环境比privileged SSC 允许的环境宽松,请使用 anyuid-extra SCC。例如,如果您无权授予privileged SCC,则可以创建 anyuid-extra SCC 并将其添加到您的 Vertica 工作负载服务帐户。

有关安装的详细信息,请参阅使用 anyuid-extra 创建自定义 SCC

安装操作器

VerticaDB 操作器是由 Vertica 维护的社区操作器。OperatorHub 中可用的每个操作器都必须遵守 Operator Lifecycle Manager (OLM) 定义的要求。为了满足这些要求,供应商必须为每个操作器提供群集服务版本 (CSV) 清单。Vertica 为 OpenShift OperatorHub 中可用的每个 VerticaDB 操作器版本提供一个 CSV。

VerticaDB 操作器支持 OpenShift 4.8 及更高版本。

您必须拥有 OpenShift 帐户的群集管理员权限才能安装 VerticaDB 操作器。有关详细的安装说明,请参阅 OpenShift 文档

在多个 OpenShift 命名空间中安装操作器

默认情况下,OpenShift 用户界面 (UI) 将 VerticaDB 操作器安装在单个 OpenShift 命名空间中。在某些情况下,您可能需要操作器跨多个 OpenShift 命名空间监视和管理资源对象。

先决条件

以下步骤将 VerticaDB 操作器添加到其他命名空间:

  1. 创建 YAML 格式的 OperatorGroup 对象文件。以下示例创建了名为 operatorgroup.yaml 的文件:

    apiVersion: operators.coreos.com/v1alpha2
    kind: OperatorGroup
    metadata:
      name: vertica-operatorgroup
      namespace: $NAMESPACE
    spec:
      targetNamespaces:
      - $NAMESPACE
    

    在前面的命令中,$NAMESPACE 是您要安装操作器的命名空间。

  2. 创建 OperatorGroup 对象:

    $ oc apply -f operatorgroup.yaml
    
  3. 创建 YAML 格式的 Subscription 对象文件,以订阅操作器命名空间。以下示例创建了名为 sub.yaml 的文件:

    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: verticadb-operator
      namespace: $NAMESPACE
    spec:
      channel: stable
      name: verticadb-operator
      source: community-operators
      sourceNamespace: openshift-marketplace
    
  4. 创建 Subscription 对象:

    $ oc apply -f sub.yaml
    

    创建 Subscription 对象后,OLM 能够识别该操作器。

  5. 使用 kubectl get 在单独的 shell 中查看安装进度:

    $ kubectl get -n $NAMESPACE clusterserviceversion -w --selector operators.coreos.com/verticadb-operator.$NAMESPACE
    

安装完成后,您可以从 UI 管理操作器。

使用 anyuid-extra 创建自定义 SCC

在创建操作器之前,您必须创建 anyuid-extra SCC 并将其添加到您的 Vertica 工作负载服务帐户。Vertica anyuid-extra SCC 清单可在 Vertica GitHub 存储库中获得。

  1. 使用 anyuid-extra YAML 格式的清单创建自定义 SCC:

    $ kubectl apply -f https://github.com/vertica/vertica-kubernetes/releases/download/v1.4.0/custom-scc.yaml
    

    有关详细信息,请参考 OpenShift 文档

  2. 执行以下命令将自定义 SCC 添加到您的 Vertica 工作负载服务帐户:

    $ oc adm policy add-scc-to-user -n $NAMESPACE -z verticadb-operator-controller-manager anyuid-extra
    

    在前面的命令中,$NAMESPACE 是安装了操作器的命名空间。

默认情况下,anyuid-extra 的优先级设置为 10,因此会自动选择该 SCC(而非择默认的privileged SCC)。有关优先级设置的更多详细信息,请参阅 OpenShift 文档

在 OpenShift 上部署 Vertica

安装 VerticaDB 操作器并将受支持的 SCC 添加到您的 Vertica 工作负载服务帐户后,您可以在 OpenShift 上部署 Vertica。

有关在受支持的环境中安装 OpenShift 的详细信息,请参阅 OpenShift 容器平台安装概述

在 OpenShift 上部署 Vertica 之前,请创建所需的 Secret 以存储敏感信息。有关 Secret 和 OpenShift 的详细信息,请参阅 OpenShift 文档。有关部署 Vertica 自定义资源的指导,请参阅创建自定义资源

2.4 - Prometheus 集成

基于 Kubernetes 的 Vertica 与 Prometheus 集成以捕获有关 VerticaDB 操作器的时间序列指标。这些指标会随着时间的推移创建应用程序的详细模型,从而提供有价值的性能和故障排除见解。Prometheus 使用 HTTP 端点公开这些指标,以促进微服务和容器化架构中的内部和外部通信和服务发现。

Prometheus 要求您设置目标 — 您想要监控的指标。每个目标都公开在操作器的 /metrics 端点上,Prometheus 会定期捕获该端点以收集目标数据。操作器支持操作器 SDK 框架,该框架要求授权代理服务器实施基于角色的访问控制 (RBAC) 来访问操作器指标。为了提高灵活性,Vertica 提供以下选项以使用 Prometheus 访问 /metrics 端点:

  • 使用 sidecar 容器作为 RBAC 代理服务器来授权连接。

  • /metrics 端点公开给没有 RBAC 的外部连接。

  • 完全禁用 Prometheus。

Vertica 提供 Helm 图表参数和 YAML 清单来配置每个选项。

Prometheus 操作器集成(可选)

基于 Kubernetes 的 Vertica 与 Prometheus 操作器集成,该操作器提供了可简化目标指标的自定义资源 (CR)。Vertica 支持自动发现 VerticaDB 操作器的 ServiceMonitor CR。

ServiceMonitor CR 在 GitHub 存储库作为发布工件提供。有关 prometheus.createServiceMonitor 参数的详细信息,请参阅 Helm 图表参数

先决条件

使用 RBAC 访问指标

操作器 SDK 框架要求操作器使用授权代理服务器来访问指标。由于操作器仅将指标发送到 localhost,因此 Vertica 使用具有 localhost 访问权限的 sidecar 容器(该容器强制执行 RBAC)来满足这些要求。

RBAC 规则是群集范围的,sidecar 对来自某些客户端的连接进行授权,这些客户端与具有正确 ClusterRole 和 ClusterRoleBindings 的服务帐户关联。Vertica 提供以下示例清单:

有关 ClusterRoles 和 ClusterRoleBindings 的更多详细信息,请参阅 Kubernetes 文档

以下步骤创建 ClusterRole 和 ClusterRoleBindings 对象,这些对象授予对非 Kubernetes 资源(例如 Prometheus)的 /metrics 端点的访问权限。由于 RBAC 规则是群集范围的,因此您必须创建 ClusterRoleBinding 或添加到现有 ClusterRoleBinding:

  1. 创建 ClusterRoleBinding,以将 RBAC sidecar 代理服务器的角色与服务帐户绑定:

    • 要创建新的 ClusterRoleBinding:

      $ kubectl create clusterrolebinding verticadb-operator-proxy-rolebinding --clusterrole=verticadb-operator-proxy-role --serviceaccount=namespace:verticadb-operator-controller-manager
      
    • 要将服务帐户添加到现有 ClusterRoleBinding:

      $ kubectl patch clusterrolebinding verticadb-operator-proxy-rolebinding --type='json' -p='[{"op": "add", "path": "/subjects/-", "value": {"kind": "ServiceAccount", "name": "verticadb-operator-controller-manager","namespace": "namespace" } }]'
      
  2. 创建 ClusterRoleBinding,以将非 Kubernetes 对象的角色绑定到 RBAC sidecar 代理服务器服务帐户:

    • 要创建新的 ClusterRoleBinding:

      $ kubectl create clusterrolebinding verticadb-operator-metrics-reader --clusterrole=verticadb-operator-metrics-reader --serviceaccount=namespace:serviceaccount
      
    • 要将服务帐户绑定到现有 ClusterRoleBinding:

      $ kubectl patch clusterrolebinding verticadb-operator-metrics-reader --type='json' -p='[{"op": "add", "path": "/subjects/-", "value": {"kind": "ServiceAccount", "name": "serviceaccount","namespace": "namespace" } }]'
      

当您安装 Helm 图表时,会自动创建 ClusterRole 和 ClusterRoleBindings。默认情况下,prometheus.expose 参数设置为 EnableWithProxy,它会创建服务对象并公开操作器的 /metrics 端点。

有关创建 sidecar 容器的详细信息,请参阅创建自定义资源

服务对象

Vertica 提供名为 verticadb-operator-metrics-service 的服务对象以访问 Prometheus /metrics 端点。VerticaDB 操作器不管理该服务对象。默认情况下,该服务对象使用 ClusterIP 服务类型来支持 RBAC。

使用以下路径连接到端口 8443 处的 /metrics 端点:

https://verticadb-operator-metrics-service.namespace.svc.cluster.local:8443/metrics

在没有 RBAC 的情况下访问指标

您可能有一个不需要对 Prometheus 指标进行特许访问的环境。例如,您可以在 Kubernetes 之外运行 Prometheus。

要允许使用 HTTP 从外部访问 /metrics 端点,请将 prometheus.expose 设置为 EnableWithoutAuth。示例命令如下所示:

$ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator \
    --set prometheus.expose=EnableWithoutAuth

服务对象

Vertica 提供名为 verticadb-operator-metrics-service 的服务对象以访问 Prometheus /metrics 端点。VerticaDB 操作器不管理该服务对象。默认情况下,该服务对象使用 ClusterIP 服务类型,因此您必须更改 serviceType 以供外部客户端访问。该服务对象的完全限定域名 (FQDN) 如下所示:

verticadb-operator-metrics-service.namespace.svc.cluster.local

使用以下路径连接到端口 8443 处的 /metrics 端点:

http://verticadb-operator-metrics-service.namespace.svc.cluster.local:8443/metrics

禁用 Prometheus

要禁用 Prometheus,请将 prometheus.expose Helm 图表参数设置为 Disable。示例命令如下所示:

$ helm install operator-name --namespace namespace --create-namespace vertica-charts/verticadb-operator \
    --set prometheus.expose=Disable

有关 Helm 安装命令的详细信息,请参阅安装 Vertica DB 操作器

3 - 配置公共存储

基于 Kubernetes 的 Vertica 支持各种公共存储提供程序来满足您的存储需求。配置每个存储提供程序需要您创建一个 SecretConfigMap 来存储敏感信息,以便您可以在自定义资源 (CR) 中声明这些信息而不暴露任何字面量值。

Amazon Web Services (AWS) S3 或兼容 S3 的存储

基于 Kubernetes 的 Vertica 支持 AWS 公共存储位置和私有云 S3 存储,例如 MinIO

要连接到与 S3 兼容的存储位置,请创建一个 Secret 来存储您的公共访问权限和密钥凭证。然后,将 Secret、路径和 S3 端点添加到 CR 规范。

  1. 以下命令将 S3 兼容的公共访问权限和密钥凭证存储在名为 s3-creds 的秘密中:

    $ kubectl create secret generic s3-creds --from-literal=accesskey=accesskey --from-literal=secretkey=secretkey
    
  2. 将 Secret 添加到 CR 规范的 communal 部分:

    spec:
      ...
      communal:
        credentialSecret: s3-creds
        endpoint: https://path/to/s3-endpoint
        path: s3://bucket-name/key-name
        ...
    

有关与 S3 兼容的存储实施的详细描述,请参阅创建自定义资源。有关 Vertica 和 AWS 的更多详细信息,请参阅 用于 Amazon Web Services 的 Vertica

Google Cloud Storage

向 Google Cloud Storage (GCS) 进行身份验证需要您的基于哈希的消息身份验证代码 (HMAC) 访问权限和密钥,以及 GCS 存储桶的路径。有关 HMAC 密钥的详细信息,请参阅GCP 上 Eon 模式的先决条件

  1. 以下命令将您的 HMAC 访问权限和密钥存储在名为 gcs-creds 的 Secret 中:

    $ kubectl create secret generic gcs-creds --from-literal=accesskey=accessKey --from-literal=secretkey=secretkey
    
  2. 将 Secret 和包含 Vertica 数据库的 GCS 存储桶的路径添加到 CR 规范的 communal 部分:

    spec:
      ...
      communal:
        credentialSecret: gcs-creds
        path: gs://bucket-name/path/to/database-name
        ...
    

有关 Vertica 和 GCS 的更多详细信息,请参阅用于 Google Cloud Platform 的 vertica

Azure Blob 存储

Micosoft Azure 提供了多种选项来向 Azure Blob 存储位置进行身份验证。根据您的环境,您可以使用以下组合之一将凭据存储在 Secret 中:

  • accountName 和 accountKey

  • accountName 和共享访问签名 (SAS)

如果在测试环境中使用诸如 Azurite 之类的 Azure 存储模拟器,则可以使用 accountName 和 blobStorage 值进行身份验证。

  1. 以下命令将 accountName 和 accountKey 存储在名为 azb-creds 的 Secret 中:

    $ kubectl create secret generic azb-creds --from-literal=accountKey=accessKey --from-literal=accountName=accountName
    

    或者,可以将您的 accountName 和 SAS 凭据存储在 azb-creds 中:

    $ kubectl create secret generic azb-creds --from-literal=sharedAccessSignature=sharedAccessSignature --from-literal=accountName=accountName
    
  2. 将 Secret 和包含 AZB 存储桶的路径添加到 CR 规范的 communal 部分:

    spec:
      ...
      communal:
        credentialSecret: azb-creds
        path: azb://accountName/bucket-name/database-name
        ...
    

有关 Vertica 和向 Microsoft Azure 进行身份验证的详细信息,请参阅Azure 上的 Eon 模式数据库

Hadoop 文件存储

使用标准 webhdfs 方案或用于线路加密的 swebhdfs 方案连接到 Hadoop 分布式文件系统 (HDFS) 公共存储。此外,您必须将 HDFS 配置文件添加到 ConfigMap 中,它是一个以键值对形式存储数据的 Kubernetes 对象。您可以选择配置 Kerberos 以验证与 HDFS 存储位置的连接。

以下示例使用 swebhdfs 线路加密方案,该方案需要 CR 规范中的证书颁发机构 (CA) 捆绑包。

  1. 以下命令将 PEM 编码的 CA 捆绑包存储在名为 hadoop-cert 的密钥中:

    $ kubectl create secret generic hadoop-cert --from-file=ca-bundle.pem
    
  2. HDFS 配置文件位于 /etc/hadoop 目录中。以下命令创建一个名为 hadoop-conf 的 ConfigMap:

    $ kubectl create configmap hadoop-conf --from-file=/etc/hadoop
    
  3. 将配置值添加到规范的 communalcertSecrets 部分:

    spec:
      ...
      communal:
        path: "swebhdfs://path/to/database"
        hadoopConfig: hadoop-conf
        caFile: /certs/hadoop-cert/ca-bundle.pem
      certSecrets:
        - name: hadoop-cert
      ...
    

    前面的示例定义了以下内容:

    • communal.path:使用线路加密方案的数据库路径。将路径括在双引号中。

    • communal.hadoopConfig:用于存储 /etc/hadoop 目录内容的 ConfigMap。

    • communal.caFile:包含用于创建 hadoop-cert Secret 的 CA 捆绑包的容器文件系统中的挂载路径。

    • certSecrets.name:包含 CA 捆绑包的 Secret。

有关 HDFS 和 Vertica 的更多详细信息,请参阅 Apache Hadoop 集成

Kerberos 身份验证(可选)

Vertica 使用 Kerberos 对与 HDFS 的连接进行身份验证。基于 Kubernetes 的 Vertica 之间的 Kerberos 配置与标准 Eon 模式数据库和 Kerberos 之间的配置相同,如 Kerberos 身份验证中所述。

  1. 以下命令将 krb5.confkrb5.keytab 文件存储在名为 krb5-creds 的 Secret 中:

    $ kubectl create secret generic krb5-creds --from-file=kerberos-conf=/etc/krb5.conf --from-file=kerberos-keytab=/etc/krb5.keytab
    

    在基于 Kubernetes 的 Vertica 中管理 krb5.confkrb5.keytab 文件时,请考虑以下事项:

    • 每个 pod 使用相同的 krb5.keytab 文件,因此您必须在开始任何扩展操作之前更新 krb5.keytab 文件。

    • 当您更新 krb5.keytab 文件的内容时,操作器会自动更新挂载的文件,这个过程不需要重新启动 pod。

    • krb5.conf 文件必须包含将 Kubernetes 群集域映射到 Kerberos 领域的 [domain_realm] 部分。以下示例将默认 .cluster.local 域映射到名为 EXAMPLE.COM 的 Kerberos 领域:

      [domain_realm]
        .cluster.local = EXAMPLE.COM
      
  2. 将 Secret 和其他 Kerberos 配置信息添加到 CR:

    spec:
      ...
      communal:
        path: "swebhdfs://path/to/database"
        hadoopConfig: hadoop-conf
        kerberosServiceName: verticadb
        kerberosRealm: EXAMPLE.COM
      kerberosSecret: krb5-creds
      ...
    

前面的示例定义了以下内容:

  • communal.path:使用线路加密方案的数据库路径。将路径括在双引号中。

  • communal.hadoopConfig:用于存储 /etc/hadoop 目录内容的 ConfigMap。

  • communal.kerberosServiceName:Vertica 主体的服务名称。

  • communal.kerberosRealm:主体的领域部分。

  • kerberosSecret:包含 krb5.confkrb5.keytab 文件的 Secret。

有关前面每个值的完整定义,请参阅自定义资源定义参数

4 - 创建自定义资源

自定义资源定义 (CRD) 是共享的全局对象,它将 Kubernetes API 扩展到标准资源类型之外。CRD 用作自定义资源 (CR) 实例的蓝图。您创建用来指定所需环境状态的 CR,操作器监控 CR 以维护其命名空间内对象的状态。

为方便起见,此示例 CR 使用 YAML 格式的文件。有关所有可用 CR 设置的详细信息,请参阅自定义资源参数

先决条件

创建 Secret

使用 kubectl 命令行工具创建 Secret 以将敏感信息存储在您的自定义资源中,而不会暴露敏感信息所代表的值。

  1. 为 Vertica 许可证创建一个名为 vertica-license 的 Secret:

    $ kubectl create secret generic vertica-license --from-file=license.dat=/path/to/license.dat
    

    默认情况下,Helm 图表使用免费的社区版许可证。此许可证仅限于 3 个节点和 1 TB 数据。

  2. 创建名为 su-passwd 的 Secret 来存储您的超级用户密码。如果不添加超级用户密码,则没有与数据库关联的密码:

    $ kubectl create secret generic su-passwd --from-literal=password=secret-password
    
  3. 以下命令将 S3 兼容的公共访问权限和密钥凭证存储在名为 s3-creds 的秘密中:

    $ kubectl create secret generic s3-creds --from-literal=accesskey=accesskey --from-literal=secretkey=secretkey
    
  4. 本教程配置一个证书颁发机构 (CA) 捆绑包,该捆绑包对与自定义资源的、与 S3 兼容的连接进行身份验证。创建名为 aws-cert 的 Secret:

    $ kubectl create secret generic aws-cert --from-file=root-cert.pem
    
  5. 您可以在 Vertica 服务器文件系统中挂载多个证书。以下命令在名为 mtls 的 Secret 中为您的 mTLS 证书创建一个 Secret:

    $ kubectl create secret generic mtls --from-file=mtls=/path/to/mtls-cert
    

必填字段

VerticaDB 定义以用来描述版本、资源类型和元数据的必填字段开头:

apiVersion: vertica.com/v1beta1
kind: VerticaDB
metadata:
  name: verticadb

前面的示例定义了以下内容:

  • apiVersionapi-group/version 格式的 API 组和 Kubernetes API 版本。

  • kind:资源类型。VerticaDB 是 Vertica 自定义资源类型的名称。

  • metadata:标识命名空间中的对象的数据。

    • name:此 CR 对象的名称。

规范定义

spec 字段定义了 CR 的所需状态。在控制循环期间,操作器将规范值与当前状态进行比较并协调任何差异。

以下部分将值嵌套在 spec 字段下,以定义自定义资源对象的所需状态。

映像管理

每个自定义资源实例都需要访问 Vertica 服务器映像以及有关多久下载一次新映像的说明:

spec:
  image: vertica/vertica-k8s:latest
  imagePullPolicy: Always

前面的示例定义了以下内容:

  • image:要在 Vertica 服务器容器 pod 中运行的映像,在此处以 docker-registry-hostname/image-name:tag 格式定义。有关可用 Vertica 映像的完整列表,请参阅 Vertica Dockerhub 注册表

  • imagePullPolicy:控制操作器何时从容器注册表中提取 image。当您使用 latest 标记时,请将此项设置为 Alwayslatest 标记会被每个新版本覆盖,因此您应该检查映像注册表以确保使用正确的最新映像。

群集描述值

此部分对用来配置数据库及其操作方式的字段进行逻辑分组:

spec:
  ...
  initPolicy: Create
  kSafety: "1"
  licenseSecret: vertica-license
  superuserPasswordSecret: su-passwd

前面的示例定义了以下内容:

  • initPolicy:指定如何初始化数据库。 Create 为自定义资源初始化一个新数据库。

  • kSafety:确定子群集的容错。对于三 Pod 子群集,将 kSafety 设置为 1。

  • licenseSecretSecret 包含您的 Vertica 许可证密钥。许可证挂载在 /home/dbadmin/licensing/mnt 目录中。

  • superuserPasswordSecretSecret 包含数据库超级用户密码。

挂载自定义 TLS 证书

certSecrets 是一个列表,其中包含您为了对 CR 的内部和外部通信加密而创建的每个 Secret。使用 name 键添加每个证书:

spec:
  ...
  certSecrets:
    - name: mtls
    - name: aws-cert

certSecrets 接受无限数量的 name 值。如果您更新现有证书,操作器将替换 Vertica 服务器容器中的证书。如果您添加或删除证书,操作器将使用新配置重新调度 pod。

每个 certSecret 都挂载在 /certs/certSecrets.name 目录中的 Vertica 服务器容器中。例如,aws-cert Secret 挂载在 certs/aws-cert 目录中。

配置公共存储

以下示例为 S3 端点配置公共存储。有关支持的公共存储位置的列表,请参阅容器化环境。有关每个公共存储位置的实施详细信息,请参阅配置公共存储

communal 部分中提供存储位置的位置和凭据:

spec:
  ...
  communal:
    credentialSecret: s3-creds
    endpoint: https://path/to/s3-endpoint
    path: s3://bucket-name/key-name
    caFile: /certs/aws-cert/root_cert.pem
    region: aws-region

前面的示例定义了以下内容:

  • credentialSecret:包含您的公共访问权限和密钥凭据的 Secret

  • endpoint:S3 端点 URL。

  • path:S3 存储桶的位置,采用 S3 存储桶表示法。在您创建自定义资源之前,此存储桶必须存在。创建自定义资源后,您不能更改此值。

  • caFile:在服务器容器文件系统中挂载证书文件,以验证与自定义资源的、与 S3 兼容的连接。CA 文件与挂载自定义 TLS 证书中添加的 aws-cert Secret 挂载在同一目录中。

  • region:公共存储资源的地理位置。

添加 sidecar 容器

sidecar 是一个实用程序容器,它与 Vertica 服务器容器在同一个 pod 中运行,并为 Vertica 服务器进程执行任务。例如,您可以使用 vertica-logger 映像添加一个 sidecar,将日志从 vertica.log 发送到主机节点上的标准输出以进行日志聚合。

sidecars 接受一个 sidecar 定义列表,其中每个元素定义以下值:

spec:
  ...
  sidecars:
    - name: sidecar-container
      image: sidecar-image:latest

前面的示例定义了以下内容:

  • name:sidecar 的名称。 name 指示 sidecar 元素的开头。

  • image:sidecar 容器的映像。

与 Vertica 服务器进程共享信息的 sidecar 必须在 pod 生命周期之间持久存储数据。以下部分在 sidecar 文件系统中挂载自定义卷。

挂载自定义卷

如果外部服务需要长期访问您的 Vertica 服务器数据,您可能需要挂载自定义卷以在 pod 生命周期之间持久存储数据。

使用 volumeMounts.* 参数挂载一个或多个自定义卷。要为 Vertica 服务器容器挂载自定义卷,请直接在规范下添加 volumeMounts.* 值。要为 sidecar 容器挂载自定义卷,请将 volumeMounts.* 值嵌套在 sidecars 数组中,作为单个 sidecar 元素定义的一部分。

volumes.* 参数使自定义卷可供 CR 挂载到相应的容器文件系统中。将 volumes 缩进到与其对应的 volumeMounts 条目相同的级别。以下示例为 Vertica 服务器容器和 sidecar 实用程序容器挂载自定义卷:

spec:
  ...
  volumeMounts:
  - name: tenants-vol
    mountPath: /path/to/tenants-vol
  volumes:
    - name: tenants-vol
      persistentVolumeClaim:
        claimName: vertica-pvc
    - name: sidecar-vol
      emptyDir: {}
  ...
  sidecars:
    - name: sidecar-container
      image: sidecar-image:latest
      volumeMounts:
        - name: sidecar-vol
          mountPath: /path/to/sidecar-vol

前面的示例定义了以下内容:

  • volumes:接受自定义卷和卷类型的列表以持久存储容器的数据。

  • volumes.name:持久存储数据的自定义卷的名称。此值必须与对应的 volumeMounts.name 值匹配。

  • persistentVolumeClaimemptyDir:卷类型和名称。Vertica 自定义资源接受任何 Kubernetes 卷类型。

本地容器信息

每个容器在 PersistentVolume (PV) 中持久存储编录、存储库、配置和日志数据。您必须为 pod 重新调度等操作提供有关数据和存储库位置的信息:

spec:
  ...
  local:
    dataPath: /data
    depotPath: /depot
    requestSize: 500Gi

前面的示例定义了以下内容:

  • dataPath/data 目录挂载在容器文件系统中的位置。/data 目录存储本地编录和临时文件。

  • depotPath:存储库挂载在容器文件系统中的位置。Eon 模式数据库将数据缓存在存储库本地,从而缩短从公共存储中获取数据以执行操作所需的时间。

  • requestSize:将 PV 绑定到 pod 时可用的本地数据卷的最小大小。

您必须将配置 StorageClass 为把 pod 绑定到 PersistentVolumeClaim (PVC)。有关详细信息,请参阅基于 Kubernetes 的容器化 Vertica

分片计数

shardCount 设置指定数据库中的分片数:

spec:
  ...
  shardCount: 12

实例化 CR 后不能更改此值。当您更改子群集中的 pod 数量,或者添加或移除子群集时,操作器自动重新平衡分片数

有关选择分片计数的指导,请参阅为 Eon 模式配置 Vertica 群集

子群集定义

subclusters 部分是元素列表,其中每个元素代表一个子群集及其属性。每个 CR 都需要一个主子群集,否则它会返回错误:

spec:
  ...
  subclusters:
  - isPrimary: true
    name: primary-subcluster
    size: 3

前面的示例定义了以下内容:

  • isPrimary:将子群集指定为主群集或辅助群集。每个 CR 都需要一个主子群集,否则它会返回错误。有关详细信息,请参阅子群集

  • name:子群集的名称。

  • size:子群集中的 pod 数量。

子群集服务对象

每个子群集通过服务对象与外部客户端和内部 pod 进行通信:

spec:
  ...
  subclusters:
    ...
    serviceName: connections
    serviceType: LoadBalancer
    serviceAnnotations:
      service.beta.kubernetes.io/load-balancer-source-ranges: 10.0.0.0/24

在前面的示例中:

  • serviceName:为服务对象分配自定义名称,以便您可以在需要时将相同的服务对象用于多个子群集。

    服务对象名称使用 metadata.name-serviceName 命名约定。此示例创建名为 verticadb-connections 的服务对象。

  • serviceType:定义子群集服务对象。

    默认情况下,子群集使用 ClusterIP serviceType,它设置只能从 Kubernetes 内部访问的稳定 IP 和端口。在许多情况下,外部客户端应用程序需要连接到针对特定工作负载进行微调的子群集。对于外部客户端访问,将 serviceType 设置为 NodePortLoadBalancer

    LoadBalancer 服务类型由您的云提供商管理。有关实施详细信息,请参阅 Kubernetes 文档和云提供商文档。

  • serviceAnnotations:为服务分配自定义注释。此注释定义了可以访问网络负载均衡器 (NLB) 的 CIDR。有关其他详细信息,请参阅 AWS 负载均衡器控制器文档。

有关 Vertica 和服务对象的详细信息,请参阅基于 Kubernetes 的容器化 Vertica

pod 资源限制和请求

设置每个主机节点为 Vertica 服务器 pod 分配的 CPU 和内存资源量,以及每个 pod 可以请求的资源量:

spec:
  ...
  subclusters:
    ...
    resources:
      limits:
        cpu: 32
        memory: 96Gi
      requests:
        cpu: 32
        memory: 96Gi

在前面的示例中:

  • resources:每个 pod 从其主机节点请求的资源量。当您更改资源设置时,Kubernetes 会使用更新的资源配置重新启动每个 pod。

  • limits:每个服务器 pod 可消耗的最大 CPU 和内存量。

  • requests:每个 pod 从 PV 请求的 CPU 和内存资源量。

    有关设置生产限制和请求的指导,请参阅关于调整 Vertica 节点和群集大小的建议

    最佳实践是,将资源请求和限制设置为相等的值,以便将它们分配给保证的 QoS 类。相等设置还可以提供在受限环境中针对内存不足 (OOM) 终止程序的最佳防护。

节点亲和性

Kubernetes 提供了亲和性和反亲和性设置来控制操作器使用哪些资源来调度 pod。最佳实践是,设置 affinity 以确保单个节点不为两个 Vertica pod 提供服务:

spec:
  ...
  subclusters:
    ...
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
              - vertica
          topologyKey: "kubernetes.io/hostname"

在前面的示例中:

  • affinity:使用标签提供对 pod 和主机调度的控制。

  • podAntiAffinity:使用 pod 标签来防止对某些资源进行调度。

  • requiredDuringSchedulingIgnoredDuringExecution:在将 pod 调度到主机节点之前,必须满足此语句下定义的规则。

  • labelSelector:标识受此亲和性规则影响的 pod。

  • matchExpressions:包含 keyoperatorvalues 定义的 pod 选择器要求的列表。此 matchExpression 规则检查主机节点是否正在运行另一个使用 vertica 标签的 pod。

  • topologyKey:定义规则的范围。由于使用 hostname 拓扑标签,因此会根据 pod 和主机节点应用规则。

完整的文件参考

下面是可供参考的完整 CR YAML 文件:

apiVersion: vertica.com/v1beta1
kind: VerticaDB
metadata:
  name: verticadb
spec:
  image: vertica/vertica-k8s:latest
  imagePullPolicy: Always
  initPolicy: Create
  kSafety: "1"
  licenseSecret: vertica-license
  superuserPasswordSecret: su-passwd
  communal:
    credentialSecret: s3-creds
    endpoint: https://path/to/s3-endpoint
    path: s3://bucket-name/key-name
    caFile: /certs/aws-certs/root_cert.pem
    region: aws-region
  volumeMounts:
  - name: tenants-vol
    mountPath: /path/to/tenants-vol
  volumes:
    - name: tenants-vol
      persistentVolumeClaim:
        claimName: vertica-pvc
    - name: sidecar-vol
      emptyDir: {}
  sidecars:
    - name: sidecar-container
      image: sidecar-image:latest
      volumeMounts:
        - name: sidecar-vol
          mountPath: /path/to/sidecar-vol
  certSecrets:
    - name: mtls
    - name: aws-cert
  local:
    dataPath: /data
    depotPath: /depot
    requestSize: 500Gi
  shardCount: 12
  subclusters:
  - isPrimary: true
    name: primary-subcluster
    size: 3
    serviceName: connections
    serviceType: LoadBalancer
    serviceAnnotations:
      service.beta.kubernetes.io/load-balancer-source-ranges: 10.0.0.0/24
    resources:
      limits:
        cpu: 32
        memory: 96Gi
      requests:
        cpu: 32
        memory: 96Gi
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
              - vertica
          topologyKey: "kubernetes.io/hostname"

5 - 自定义资源定义参数

下表描述了 Vertica 自定义资源定义的可用设置。

6 - 基于 Kubernetes 的子群集

Eon 模式使用子群集进行工作负载隔离和扩展。Vertica 操作器提供了工具以将外部客户端通信定向到特定子群集,以及在不停止数据库的情况下自动扩展。

自定义资源定义 (CRD) 提供参数,允许您针对特定工作负载微调每个子群集。例如,您可以增加子群集 size 设置以增加吞吐量,或调整资源请求和限制以管理计算能力。当您创建自定义资源实例时,操作器将每个子群集部署为 StatefulSet。每个 StatefulSet 都有一个服务对象,它允许外部客户端连接到特定子群集。

Kubernetes 使用子群集名称来派生子群集 StatefulSet、服务对象和 pod 的名称。这种命名约定将子群集对象紧密耦合在一起,以帮助 Kubernetes 有效地管理群集。如果要重命名子群集,则必须将其从 CRD 中删除并重新定义,以便操作器可以使用派生名称创建新对象。

外部客户端连接

外部客户端可以将特定的子群集作为目标,这些子群集在经过微调之后可以处理外部客户端的工作负载。每个子群集都有一个用来处理外部连接的服务对象。要将多个子群集作为单个服务对象的目标,请在自定义资源 (CR) 中为每个子群集分配相同的 spec.subclusters.serviceName 值。有关实施的详细信息,请参阅创建自定义资源

操作器执行运行状况监控,检查 Vertica 守护程序是否在每个 pod 上运行。如果是,则操作器允许服务对象将流量路由到 pod。

默认情况下,服务对象从自定义资源名称和关联的子群集派生其名称,并使用 customResourceName-subclusterName 格式。使用 subclusters[i].serviceName CR 参数 覆盖默认命名格式并使用 metadata.name-serviceName 格式。

Vertica 支持以下服务对象类型:

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

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

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

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

管理内部和外部工作负载

Vertica StatefulSet 与外部服务对象相关联。所有外部客户端请求都通过此服务对象发送,并在群集中的 pod 之间进行负载均衡。

导入和导出

在 Kubernetes 之外的群集之间导入和导出数据要求您公开具有 NodePortLoadBalancer 服务类型的服务并正确配置网络。

6.1 - 扩展子群集

操作器使您能够自动扩展子群集的数量以及每个子群集的 pod 数量。这使您可以根据工作负载的即时需求来利用或节省资源。

以下部分说明如何为新工作负载扩展资源。有关为现有工作负载扩展资源的详细信息,请参阅 VerticaAutoscaler 自定义资源

先决条件

扩展子群集的数量

调整自定义资源中的子群集数量,以针对短期运行的仪表板查询微调资源。例如,增加子群集的数量以提高吞吐量。有关详细信息,请参阅使用子群集提高查询吞吐量

  1. 使用 kubectl edit 打开默认文本编辑器并更新指定的自定义资源的 YAML 文件。以下命令打开名为 vdb 的自定义资源进行编辑:

    $ kubectl edit vdb
    
  2. 在自定义资源的 spec 部分中,找到 subclusters 子部分。从 isPrimary 字段开始定义新的子群集。

    isPrimary 字段接受一个布尔值,以指定子群集是主群集还是辅助群集。用于自定义资源中已经有一个主子群集,因此输入 false

    spec:
    ...
      subclusters:
      ...
      - isPrimary: false
    
  3. 按照创建自定义资源中的步骤完成子群集定义。以下已完成的示例为仪表板查询添加了一个辅助子群集:

    spec:
    ...
      subclusters:
      - isPrimary: true
        name: primary-subcluster
      ...
      - isPrimary: false
        name: dashboard
        nodePort: 32001
        resources:
          limits:
            cpu: 32
            memory: 96Gi
          requests:
            cpu: 32
            memory: 96Gi
        serviceType: NodePort
        size: 3
    
  4. 保存并关闭自定义资源文件。成功更新文件后,您会收到类似如下的消息:

    verticadb.vertica.com/vertica-db 已编辑 (verticadb.vertica.com/vertica-db edited)

  5. 使用 kubectl wait 命令监控新 pod 何时准备就绪:

    $ kubectl wait --for=condition=Ready pod --selector app.kubernetes.io/name=vertica-db --timeout 180s
    pod/vdb-dashboard-0 condition met
    pod/vdb-dashboard-1 condition met
    pod/vdb-dashboard-2 condition met
    

扩展子群集中的 pod

对于长时间运行的分析查询,增加子群集的 pod 计数。请参阅使用 Elastic Crunch Scaling 提高查询性能

  1. 使用 kubectl edit 打开默认文本编辑器并更新指定的自定义资源的 YAML 文件。以下命令打开名为 vdb 的自定义资源进行编辑:

    $ kubectl edit vertica-db
    
  2. subclusters.size 值更新为 6:

    spec:
    ...
      subclusters:
      ...
      - isPrimary: false
        ...
        size: 6
    

    分片会自动重新平衡。

  3. 保存并关闭自定义资源文件。成功更新文件后,您会收到类似如下的消息:

    verticadb.vertica.com/vertica-db 已编辑 (verticadb.vertica.com/vertica-db edited)

  4. 使用 kubectl wait 命令监控新 pod 何时准备就绪:

    $ kubectl wait --for=condition=Ready pod --selector app.kubernetes.io/name=vertica-db --timeout 180s
    pod/vdb-subcluster1-3 condition met
    pod/vdb-subcluster1-4 condition met
    pod/vdb-subcluster1-5 condition met
    

移除子群集

当不再需要子群集或为了保留资源时,移除子群集。

  1. 使用 kubectl edit 打开默认文本编辑器并更新指定的自定义资源的 YAML 文件。以下命令打开名为 vdb 的自定义资源进行编辑:

    $ kubectl edit vertica-db
    
  2. spec 下嵌套的 subclusters 子部分中,找到要删除的子群集。删除子群集数组中代表要删除的子群集的元素。每个元素由连字符 (-) 标识。

  3. 删除子群集并保存后,您会收到类似如下的消息:

    verticadb.vertica.com/vertica-db 已编辑 (verticadb.vertica.com/vertica-db edited)

6.2 - VerticaAutoscaler 自定义资源

VerticaAutoscaler 自定义资源 (CR) 是一个 HorizontalPodAutoscaler,它使用以下策略之一自动扩展现有子群集的资源:

  • 运行时间较短的仪表板查询的子群集扩展。

  • 用于运行时间较长的分析查询的 Pod 扩展。

VerticaAutoscaler CR 使用资源或自定义指标进行扩展。Vertica 按工作负载管理子群集,这有助于您确定最佳指标以触发扩展事件。为了保持数据完整性,除非与 pod 的所有连接都已耗尽且会话已关闭,否则运算符不会缩减规模。

有关确定 VerticaAutoscaler 何时扩展的算法的详细信息,请参阅 Kubernetes 文档

此外,VerticaAutoscaler 提供了一个 webhook 来验证状态更改。默认情况下,此 webhook 已启用。您可以使用 webhook.enableHelm 图表参数配置此 webhook。

参数

示例

此部分中的示例使用以下 VerticaDB 自定义资源。每个示例都使用 CPU 来触发扩展:

apiVersion: vertica.com/v1beta1
kind: VerticaDB
metadata:
  name: dbname
spec:
  communal:
    path: "path/to/communal-storage"
    endpoint: "path/to/communal-endpoint"
    credentialSecret: credentials-secret
  subclusters:
    - name: primary1
      size: 3
      isPrimary: true
      serviceName: primary1
      resources:
        limits:
          cpu: "8"
        requests:
          cpu: "4"

先决条件

  • 为触发扩展的指标设置一个值。例如,如果要按 CPU 利用率进行扩展,则必须设置 CPU 限制和请求

子群集扩展

自动调整自定义资源中的子群集数量,以针对运行时间较短的仪表板查询优化资源。例如,增加子群集的数量以提高吞吐量。有关详细信息,请参阅使用子群集提高查询吞吐量

所有子群集共享相同的服务对象,因此无需更改外部服务对象。新子群集中的 Pod 由现有服务对象进行负载均衡。

以下示例创建了一个 VerticaAutoscaler 自定义资源,当 VerticaDB 使用 50% 的节点可用 CPU 时,该资源将按子群集进行扩展:

  1. 在 YAML 格式的清单中定义 VerticaAutoscaler 自定义资源:

    apiVersion: vertica.com/v1beta1
    kind: VerticaAutoscaler
    metadata:
      name: autoscaler-name
    spec:
      verticaDBName: dbname
      scalingGranularity: Subcluster
      serviceName: primary1
    
  2. 使用 kubectl autoscale 命令创建 VerticaAutoscaler:

    $ kubectl autoscale verticaautoscaler autoscaler-name --cpu-percent=50 --min=3 --max=12
    

    上一命令创建了一个 HorizontalPodAutoscaler 对象:

    • 将目标 CPU 利用率设置为 50%。

    • 扩展到一个子群集中至少有三个 pod,四个子群集中至少有 12 个 pod。

Pod 扩展

对于长时间运行的分析查询,增加子群集的 pod 计数。有关 Vertica 和分析查询的其他信息,请参阅使用 Elastic Crunch Scaling 提高查询性能

在 Eon 模式数据库中扩展 pod 时,必须考虑对数据库分片的影响。有关详细信息,请参阅分片和订阅

以下示例创建了一个 VerticaAutoscaler 自定义资源,当 VerticaDB 占用 50% 的节点可用 CPU 时,该资源将按 pod 进行扩展:

  1. 在 YAML 格式的清单中定义 VerticaAutoScaler 自定义资源:

    apiVersion: vertica.com/v1beta1
    kind: VerticaAutoscaler
    metadata:
      name: autoscaler-name
    spec:
      verticaDBName: dbname
      scalingGranularity: Pod
      serviceName: primary1
    
  2. 使用 kubectl autoscale 命令创建 autoscaler 实例:

    $ kubectl autoscale verticaautoscaler autoscaler-name --cpu-percent=50 --min=3 --max=12
    

    上一命令创建了一个 HorizontalPodAutoscaler 对象:

    • 将目标 CPU 利用率设置为 50%。

    • 扩展到一个子群集中至少有三个 pod,四个子群集中至少有 12 个 pod。

事件监控

要查看 VerticaAutoscaler 对象,请使用 kubectl describe hpa 命令:

$ kubectl describe hpa autoscaler-name
Name:                                                  as
Namespace:                                             vertica
Labels:                                                <none>
Annotations:                                           <none>
CreationTimestamp:                                     Tue, 12 Apr 2022 15:11:28 -0300
Reference:                                             VerticaAutoscaler/as
Metrics:                                               ( current / target )
  resource cpu on pods  (as a percentage of request):  0% (9m) / 50%
Min replicas:                                          3
Max replicas:                                          12
VerticaAutoscaler pods:                                3 current / 3 desired
Conditions:
  Type            Status  Reason              Message
  ----            ------  ------              -------
  AbleToScale     True    ReadyForNewScale    recommended size matches current size
  ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)
  ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range

当发生扩展事件时,您可以查看 admintools 命令来扩展群集。使用 kubectl 查看 StatefulSets:

$ kubectl get statefulsets
NAME                                                   READY   AGE
db-name-as-instance-name-0                             0/3     71s
db-name-primary1                                       3/3     39m

使用 kubectl describe 查看正在执行的命令:

$ kubectl describe vdb dbname | tail
  Upgrade Status:
Events:
  Type    Reason                   Age   From                Message
  ----    ------                   ----  ----                -------
  Normal  ReviveDBStart            41m   verticadb-operator  Calling 'admintools -t revive_db'
  Normal  ReviveDBSucceeded        40m   verticadb-operator  Successfully revived database. It took 25.255683916s
  Normal  ClusterRestartStarted    40m   verticadb-operator  Calling 'admintools -t start_db' to restart the cluster
  Normal  ClusterRestartSucceeded  39m   verticadb-operator  Successfully called 'admintools -t start_db' and it took 44.713787718s
  Normal  SubclusterAdded          10s   verticadb-operator  Added new subcluster 'as-0'
  Normal  AddNodeStart             9s    verticadb-operator  Calling 'admintools -t db_add_node' for pod(s) 'db-name-as-instance-name-0-0, db-name-as-instance-name-0-1, db-name-as-instance-name-0-2'

7 - 在 Kubernetes 上升级 Vertica

操作员自动执行自定义资源 (CR) 的 Vertica 服务器版本升级。使用 CR 中的 upgradePolicy 设置来确定您的群集在版本升级期间是保持联机还是脱机。

先决条件

在开始之前,请完成以下操作:

制定策略

upgradePolicy CR 参数设置确定操作员如何升级 Vertica 服务器版本。它提供以下选项:

设置协调循环迭代时间

在升级期间,操作员运行协调循环以将对象的实际状态与 CR 中定义的期望状态进行比较。操作员将任何未完成的工作重新排队,协调循环将状态与每次协调迭代之间的设定时间段进行比较。设置 upgradeRequeueTime 参数 以确定每次协调循环迭代之间的时间量。

联机升级期间路由客户端流量

在联机升级期间,操作员首先升级主子群集中的 Vertica 服务器版本,以构成具有新版本的群集。当操作员重新启动主节点时,会将辅助子群集置于只读模式。接下来,操作员一次升级任何一个辅助子群集。在任何子群集的升级过程中,所有客户端连接都被耗尽,流量重新路由到现有子群集或临时子群集。

联机升级需要多个子群集,以便操作员可以在升级时重新路由子群集的客户端流量。默认情况下,操作员使用以下规则选择哪个子群集接收重新路由的流量:

  • 为主子群集重新路由流量时,操作员选择 CR 中定义的第一个辅助子群集。

  • 升级后重新启动第一个辅助子群集时,操作员选择 CR 中定义的第一个已启动的子群集。

  • 如果不存在辅助子群集,则无法执行联机升级。操作员选择 CR 中定义的第一个主子群集并执行脱机升级。

将客户端流量路由到现有子群集

由于子群集容量或许可限制,您可能希望控制哪些子群集处理重新路由的客户端流量。您可以设置 temporarySubclusterRouting.names 参数以指定现有的子群集接收重新路由的流量:

spec:
  ...
  temporarySubclusterRouting:
    names:
      - subcluster-2
      - subcluster-1

在前面的示例中,当另一个 subcluster-1 脱机时,subcluster-2 接受流量。当 subcluster-2 关闭时,subcluster-1 接受它的流量。

将客户端流量路由到临时子群集

要创建在升级过程中存在的临时子群集,请使用 temporarySubclusterRouting.template 参数为临时子群集提供名称和大小:

spec:
  ...
  temporarySubclusterRouting:
    template:
      name: transient
      size: 3

如果选择使用临时子群集进行升级,请确保您拥有必要的资源。

升级 Vertica 服务器版本

设置 upgradePolicy 并选择配置临时子群集路由后,使用 kubectl 命令行工具执行升级并监控其进度。

以下步骤执行联机版本升级:

  1. 设置升级策略以下命令使用 kubectl patch 命令将 upgradePolicy 值设置为 Online:

    $ kubectl patch verticadb cluster-name --type=merge --patch '{"spec": {"upgradePolicy": "Online"}}'
    
  2. kubectl patch 更新 CR 中的映像值:

    $ kubectl patch verticadb cluster-name --type=merge --patch '{"spec": {"image": "vertica/vertica-k8s:new-version"}}'
    
  3. 使用 kubectl wait 等待操作员确认新映像并开始升级模式:

    $ kubectl wait --for=condition=ImageChangeInProgress=True vdb/cluster-name –-timeout=180s
    
  4. 使用 kubectl wait 等待操作员离开升级模式:

    $ kubectl wait --for=condition=ImageChangeInProgress=False vdb/cluster-name –-timeout=800s
    

查看升级过程

要查看升级过程的当前阶段,请使用 kubectl get 检查 upgradeStatus 状态字段:

$ kubectl get vdb -n namespacedatabase-name -o jsonpath='{.status.upgradeStatus}{"\n"}'
Restarting cluster with new image

要查看整个升级过程,请使用 kubectl describe 列出操作员在升级过程中生成的事件:

$ kubectl describe vdb cluster-name

...
Events:
  Type    Reason                   Age    From                Message
  ----    ------                   ----   ----                -------
  Normal  UpgradeStart             5m10s  verticadb-operator  Vertica server upgrade has started.  New image is 'vertica-k8s:new-version'
  Normal  ClusterShutdownStarted   5m12s  verticadb-operator  Calling 'admintools -t stop_db'
  Normal  ClusterShutdownSucceeded 4m08s  verticadb-operator  Successfully called 'admintools -t stop_db' and it took 56.22132s
  Normal  ClusterRestartStarted    4m25s  verticadb-operator  Calling 'admintools -t start_db' to restart the cluster
  Normal  ClusterRestartSucceeded  25s    verticadb-operator  Successfully called 'admintools -t start_db' and it took 240s
  Normal  UpgradeSucceeded         5s     verticadb-operator  Vertica server upgrade has completed successfully

8 - 混合 Kubernetes 群集

Eon 模式数据库可以独立于数据库和在 Kubernetes 内运行主机。此架构在您想要执行以下操作的情况下很有用:

  • 利用 Kubernetes 工具快速为数据库创建辅助子群集。

  • 创建隔离的沙盒环境以在公共数据集上运行即席查询。

  • 在未将主子群集迁移到 Kubernetes 的情况下,试验基于 Kubernetes 的 Vertica 的性能开销。

使用自定义资源定义混合架构的 Kubernetes 部分。自定义资源无法识别与自定义资源分开存在的 Vertica 主机。这限制了操作器的功能,要求您手动完成操作器针对基于 Kubernetes 的 Vertica 标准自定义资源自动执行的一些任务。

要求和限制

混合 Kubernetes 架构有以下要求和限制:

  • 混合 Kubernetes 群集需要启用边界网关协议 (BGP) 的工具,以便您的本地子群集可以访问 pod 以进行外部通信。例如,您可以使用 Calico CNI 插件来启用 BGP

  • 您不能在 Kubernetes pod 和本地群集之间使用网络地址转换 (NAT)。

操作器限制

在混合架构中,操作器在自定义资源之外没有可见性。这种有限的可见性意味着操作器无法与 Eon 模式数据库或主子群集进行交互。在自定义资源的范围内,操作器仅自动执行以下操作:

  • 根据清单调度 pod。

  • 为子群集创建服务对象。

  • 创建持久存储每个 pod 的数据的 PersistentVolumeClaim (PVC)。

  • 如果 Vertica 服务器进程未运行,则执行 restart_node 管理工具命令。要覆盖此默认行为,请将 autoRestartVertica 设置为 false

手动任务

由于操作器功能有限,管理员必须手动执行以下任务:

  • 如果仲裁丢失,则重新启动群集。有关维持仲裁的详细信息,请参阅Eon 模式数据库中的数据完整性和高可用性

  • 执行 update_vertica 脚本以设置配置目录。基于 Kubernetes 的 Vertica 需要 update_vertica 的以下配置选项:

    $ /opt/vertica/sbin/update_vertica \
        --accept-eula \
        --add-hosts host-list \
        --dba-user su-passwd-Secret \
        --failure-threshold NONE \
        --no-system-configuration \
        --point-to-point \
        --data-dir /data-dir \
        --dba-user dbadmin \
        --no-package-checks
    

    调用 update_vertica 后,使用 admintoolsdb_add_node 选项添加节点并完成设置:

    $ /opt/vertica/bin/admintools \
        -t db_add_node \
        --hosts host-list \
        --database db-name\
        --subcluster sc-name \
        --noprompt
    

    有关详细信息,请参阅在子群集中添加和移除节点

定义混合群集

在定义混合群集之前,您必须创建 Secret 来存储 SSH 凭据。在 Eon 模式数据库中,节点通过 SSH 进行通信。Vertica 容器使用 SSH,但每次构建容器时都会重新生成 SSH 密钥。

以下命令创建名为 ssh-key 的 Secret,它在生命周期之间持续存储 SSH 凭据,以允许本地节点和 CR 之间的安全连接:

$ kubectl create secret generic ssh-keys --from-file=$HOME/.ssh

创建自定义资源以定义在标准 Eon 模式数据库之外运行的子群集:

apiVersion: vertica.com/v1beta1
kind: VerticaDB
metadata:
  name: hybrid-secondary-sc
spec:
  image: vertica/vertica-k8s:latest
  initPolicy: ScheduleOnly
  sshSecret: ssh-keys
  local:
    dataPath: /data
    depotPath: /depot
  dbName: vertdb
  subclusters:
    - name: sc1
      size: 3
    - name: sc2
      size: 3

在前面的示例中:

  • initPolicy:混合群集要求您将该选项设置为 ScheduleOnly

  • sshSecret:包含 SSH 密钥的 Secret,用于验证与 CR 外部 Vertica 主机的连接。

  • local:必需。这些值将数据持久存储到 PersistentVolume (PV)。这些值必须匹配 Eon 模式数据库中与 Kubernetes pod 关联的目录位置。

  • dbName:此值必须匹配与此子群集关联的标准 Eon 模式数据库的名称。

  • subclusters:每个子群集的定义。

有关完整实施的详细信息,请参阅创建自定义资源。有关每个设置的详细信息,请参阅自定义资源定义参数

9 - 从现有 Eon 模式数据库生成自定义资源

为了简化对基于 Kubernetes 的 Vertica 的采用,Vertica 提供了 vdb-gen 迁移工具,该工具可将现有 Eon 模式数据库恢复为 Kubernetes 中的 StatefulSet。 vdb-gen 通过连接到数据库并写入标准输出,从现有 Eon 模式数据库生成自定义资源 (CR)。

vdb-gen 工具在 vertica-kubernetes GitHub 存储库中作为项目提供。使用 -h 标志查看可用选项(包括用于调试和使用环境变量的选项)的完整列表。以下步骤使用基本命令生成 CR。

  1. 执行 vdb-gen 并将输出重定向到 YAML 格式的文件:

    $ vdb-gen --password secret --name mydb 10.20.30.40 vertdb > vdb.yaml
    

    上面的命令使用以下标志和值:

    • password:现有数据库的超级用户密码。

    • name:新的自定义资源对象的名称。

    • 10.20.30.40:现有数据库的 IP 地址

    • vertdb:现有 Eon 模式数据库的名称。

    • vdb.yaml:YAML 格式的文件,包含由 vdb-gen 工具生成的自定义资源定义。

  2. 使用 admintools stop_db 命令 停止现有数据库:

    $ /opt/vertica/bin/admintools -t stop_db -d vertdb
    

    等待群集租约到期后再继续。有关详细信息,请参阅恢复 Eon 模式数据库群集

  3. 应用由 vdb-gen 工具生成的 YAML 格式的清单:

    $ kubectl apply -f vdb.yaml
    verticadb.vertica.com/mydb created
    
  4. 操作器创建 StatefulSet,在每个 pod 上安装 Vertica,然后运行恢复。要查看为新数据库生成的事件,请使用 kubectl describe

    $ kubectl describe vdb mydb
    

10 - Kubernetes 群集故障排除

这些提示帮助您避免有关 Vertica 在 Kerberos 上部署的问题,并对产生的任何问题进行故障排除。

下载 kubectl 命令行工具以调试您的 Kubernetes 资源。

Helm 安装失败

安装 VerticaDB 运算符和准入控制器 Helm 图表时,helm install 命令可能会返回以下错误:

$ helm install vdb-op vertica-charts/verticadb-operator
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: [unable to recognize "": no matches for kind "Certificate" in version "cert-manager.io/v1", unable to recognize "": no matches for kind "Issuer" in version "cert-manager.io/v1"]

该错误表明您尚未满足准入控制器 webhook 的 TLS 先决条件。要解决此问题,请安装 cert-manager 或配置自定义证书。以下步骤安装 cert-manager。

  1. 安装 cert-manager YAML 清单:

    $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
    
  2. 验证 cert-manager 安装。

    如果您在安装 cert-manager 后立即尝试安装 Helm 图表,则可能收到以下错误:

    $ helm install vdb-op vertica-charts/verticadb-operator
    Error: failed to create resource: Internal error occurred: failed calling webhook "webhook.cert-manager.io": failed to call webhook: Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": dial tcp 10.96.232.154:443: connect: connection refused
    

    您收到此错误是因为 cert-manager 需要时间来创建其 pod 并将 webhook 注册到群集。等待几分钟,然后使用以下命令验证 cert-manager 安装:

    $ kubectl get pods --namespace cert-manager
    NAME                                       READY   STATUS    RESTARTS   AGE
    cert-manager-7dd5854bb4-skks7              1/1     Running   5          12d
    cert-manager-cainjector-64c949654c-9nm2z   1/1     Running   5          12d
    cert-manager-webhook-6bdffc7c9d-b7r2p      1/1     Running   5          12d
    

    有关 cert-manager 安装验证的更多详细信息,请参阅 cert-manager 文档

  3. 验证 cert-manager 安装后,您必须卸载 Helm 图表,然后重新安装:

    $ helm uninstall vdb-op
    $ helm install vdb-op vertica-charts/verticadb-operator
    

有关其他信息,请参阅安装 Vertica DB 操作器

自定义证书 Helm 安装错误

如果您在使用 Helm 图表安装运算符时使用自定义证书,则 helm installkubectl apply 命令可能会返回类似以下内容的错误:

$ kubectl apply -f ../operatorcrd.yaml
Error from server (InternalError): error when creating "../operatorcrd.yaml": Internal error occurred: failed calling webhook "mverticadb.kb.io": Post "https://verticadb-operator-webhook-service.namespace.svc:443/mutate-vertica-com-v1beta1-verticadb?timeout=10s": x509: certificate is valid for ip-10-0-21-169.ec2.internal, test-bastion, not verticadb-operator-webhook-service.default.svc

当 TLS 密钥的域名系统 (DNS) 或主题备用名称 (SAN) 不正确时,您会收到此错误。要更正此错误,请按以下格式在配置文件中定义 DNS 和 SAN:

commonName = verticadb-operator-webhook-service.namespace.svc
...
[alt_names]
DNS.1 = verticadb-operator-webhook-service.namespace.svc
DNS.2 = verticadb-operator-webhook-service.namespace.svc.cluster.local

有关更多详细信息,请参阅安装 Vertica DB 操作器

验证对自定义资源的更新

由于操作员需要时间来执行任务,因此对自定义资源的更新不会立即生效。使用 kubectl 命令行工具验证是否应用了更改。

您可以使用 kubectl wait 命令等待指定的条件。例如,操作员使用 ImageChangeInProgress 条件来提供升级状态。开始映像版本升级后,等待操作员确认升级并将此条件设置为 True:

$ kubectl wait --for=condition=ImageChangeInProgress=True vdb/cluster-name –-timeout=180s

升级开始后,您可以等到操作员离开升级模式并将此条件设置为 False:

$ kubectl wait --for=condition=ImageChangeInProgress=False vdb/cluster-name –-timeout=800s

有关 kubectl wait 的详细信息,请参阅 kubectl 参考文档

pod 正在运行,但数据库尚未就绪

当您检查群集中的 pod 时,pod 正在运行,但数据库尚未就绪:

$ kubectl get pods
NAME                                                    READY   STATUS    RESTARTS   AGE
vertica-crd-sc1-0                                       0/1     Running   0          12m
vertica-crd-sc1-1                                       0/1     Running   1          12m
vertica-crd-sc1-2                                       0/1     Running   0          12m
verticadb-operator-controller-manager-5d9cdc9b8-kw9nv   2/2     Running   0          24m

要查找问题的根本原因,请使用 kubectl logs 检查操作员管理器。以下示例显示公共存储桶不存在:

$ kubectl logs -l app.kubernetes.io/name=verticadb-operator -c manager -f
2021-08-04T20:03:00.289Z        INFO    controllers.VerticaDB   ExecInPod entry {"verticadb": "default/vertica-crd", "pod": {"namespace": "default", "name": "vertica-crd-sc1-0"}, "command": "bash -c ls -l /opt/vertica/config/admintools.conf && grep '^node\\|^v_\\|^host' /opt/vertica/config/admintools.conf "}
2021-08-04T20:03:00.369Z        INFO    controllers.VerticaDB   ExecInPod stream        {"verticadb": "default/vertica-crd", "pod": {"namespace": "default", "name": "vertica-crd-sc1-0"}, "err": null, "stdout": "-rw-rw-r-- 1 dbadmin verticadba 1243 Aug  4 20:00 /opt/vertica/config/admintools.conf\nhosts = 10.244.1.5,10.244.2.4,10.244.4.6\nnode0001 = 10.244.1.5,/data,/data\nnode0002 = 10.244.2.4,/data,/data\nnode0003 = 10.244.4.6,/data,/data\n", "stderr": ""}
2021-08-04T20:03:00.369Z        INFO    controllers.VerticaDB   ExecInPod entry {"verticadb": "default/vertica-crd", "pod": {"namespace": "default", "name": "vertica-crd-sc1-0"}, "command": "/opt/vertica/bin/admintools -t create_db --skip-fs-checks --hosts=10.244.1.5,10.244.2.4,10.244.4.6 --communal-storage-location=s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c --communal-storage-params=/home/dbadmin/auth_parms.conf --sql=/home/dbadmin/post-db-create.sql --shard-count=12 --depot-path=/depot --database verticadb --force-cleanup-on-failure --noprompt --password ******* "}
2021-08-04T20:03:00.369Z        DEBUG   controller-runtime.manager.events       Normal  {"object": {"kind":"VerticaDB","namespace":"default","name":"vertica-crd","uid":"26100df1-93e5-4e64-b665-533e14abb67c","apiVersion":"vertica.com/v1beta1","resourceVersion":"11591"}, "reason": "CreateDBStart", "message": "Calling 'admintools -t create_db'"}
2021-08-04T20:03:17.051Z        INFO    controllers.VerticaDB   ExecInPod stream        {"verticadb": "default/vertica-crd", "pod": {"namespace": "default", "name": "vertica-crd-sc1-0"}, "err": "command terminated with exit code 1", "stdout": "Default depot size in use\nDistributing changes to cluster.\n\tCreating database verticadb\nBootstrap on host 10.244.1.5 return code 1 stdout '' stderr 'Logged exception in writeBufferToFile: RecvFiles failed in closing file [s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/verticadb_rw_access_test.txt]: The specified bucket does not exist. Writing test data to file s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/verticadb_rw_access_test.txt failed.\\nTesting rw access to communal location s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/ failed\\n'\n\nError: Bootstrap on host 10.244.1.5 return code 1 stdout '' stderr 'Logged exception in writeBufferToFile: RecvFiles failed in closing file [s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/verticadb_rw_access_test.txt]: The specified bucket does not exist. Writing test data to file s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/verticadb_rw_access_test.txt failed.\\nTesting rw access to communal location s3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c/ failed\\n'\n\n", "stderr": ""}
2021-08-04T20:03:17.051Z        INFO    controllers.VerticaDB   aborting reconcile of VerticaDB {"verticadb": "default/vertica-crd", "result": {"Requeue":true,"RequeueAfter":0}, "err": null}
2021-08-04T20:03:17.051Z        DEBUG   controller-runtime.manager.events       Warning {"object": {"kind":"VerticaDB","namespace":"default","name":"vertica-crd","uid":"26100df1-93e5-4e64-b665-533e14abb67c","apiVersion":"vertica.com/v1beta1","resourceVersion":"11591"}, "reason": "S3BucketDoesNotExist", "message": "The bucket in the S3 path 's3://newbucket/db/26100df1-93e5-4e64-b665-533e14abb67c' does not exist"}

为群集创建一个 S3 存储桶:

$ S3_BUCKET=newbucket
$ S3_CLUSTER_IP=$(kubectl get svc | grep minio | head -1 | awk '{print $3}')
$ export AWS_ACCESS_KEY_ID=minio
$ export AWS_SECRET_ACCESS_KEY=minio123
$ aws s3 mb s3://$S3_BUCKET --endpoint-url http://$S3_CLUSTER_IP
make_bucket: newbucket

使用 kubectl get pods 验证群集使用新的 S3 存储桶并且数据库已准备就绪:

$ kubectl get pods
NAME                                                    READY   STATUS    RESTARTS   AGE
minio-ss-0-0                                            1/1     Running   0          18m
minio-ss-0-1                                            1/1     Running   0          18m
minio-ss-0-2                                            1/1     Running   0          18m
minio-ss-0-3                                            1/1     Running   0          18m
vertica-crd-sc1-0                                       1/1     Running   0          20m
vertica-crd-sc1-1                                       1/1     Running   0          20m
vertica-crd-sc1-2                                       1/1     Running   0          20m
verticadb-operator-controller-manager-5d9cdc9b8-kw9nv   2/2     Running   0          63m

数据库不可用

创建自定义资源实例后,数据库不可用。 kubectl get custom-resource 命令不显示信息:

$ kubectl get vdb
NAME          AGE   SUBCLUSTERS   INSTALLED   DBADDED   UP
vertica-crd   4s

使用 kubectl describe custom-resource 检查 pod 的事件以确定任何问题:

$ kubectl describe vdb
Name:         vertica-crd
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  vertica.com/v1beta1
Kind:         VerticaDB
Metadata:
  ...
  Superuser Password Secret:  su-passwd
Events:
  Type     Reason                           Age                From                Message
  ----     ------                           ----               ----                -------
  Warning  SuperuserPasswordSecretNotFound  5s (x12 over 15s)  verticadb-operator  Secret for superuser password 'su-passwd' was not found

在这种情况下,自定义资源使用名为 su-passwd 的 Secret 来存储 Superuser Password Secret,但没有这样的 Secret 可用。创建名为 su-passwd 的 Secret 来存储 Secret:

$ kubectl create secret generic su-passwd --from-literal=password=sup3rs3cr3t
secret/su-passwd created

使用 kubectl get custom-resource 来验证问题是否已解决:

$ kubectl get vdb
NAME          AGE   SUBCLUSTERS   INSTALLED   DBADDED   UP
vertica-crd   89s   1             0           0         0

映像拉取失败

使用 Helm 图表部署 Vertica 群集时收到 ImagePullBackOff 错误,但您未从本地注册表服务器预先拉取 Vertica 映像:

$ kubectl describe pod pod-name-0
...
Events:
  Type     Reason            Age                    From               Message
  ----     ------            ----                   ----               -------
  ...
  Warning  Failed            2m32s                  kubelet            Failed to pull image "k8s-rhel7-01:5000/vertica-k8s:default-1": rpc error: code = Unknown desc = context canceled
  Warning  Failed            2m32s                  kubelet            Error: ErrImagePull
  Normal   BackOff           2m32s                  kubelet            Back-off pulling image "k8s-rhel7-01:5000/vertica-k8s:default-1"
  Warning  Failed            2m32s                  kubelet            Error: ImagePullBackOff
  Normal   Pulling           2m18s (x2 over 4m22s)  kubelet            Pulling image "k8s-rhel7-01:5000/vertica-k8s:default-1"

出现这种情况是因为 Vertica 映像太大而无法在部署 Vertica 群集时从注册表中拉取。在 Kubernetes 主机上执行以下命令:

$ docker image list | grep vertica-k8s
k8s-rhel7-01:5000/vertica-k8s default-1 2d6f5d3d90d6 9 days ago 1.55GB

要解决此问题,请完成以下操作之一:

  • 在创建 Vertica StatefulSet 之前拉取每个节点上的 Vertica 映像:

    $ NODES=`kubectl get nodes | grep -v NAME | awk '{print $1}'`
    $ for node in $NODES; do ssh $node docker pull $DOCKER_REGISTRY:5000/vertica-k8s:$K8S_TAG; done
    
  • 为 Vertica 服务器使用大小减小的 vertica/vertica-k8s:latest 映像。

由于 CPU 不足而挂起 pod

如果您的主机节点没有足够的资源来满足来自 pod 的资源请求,则 pod 将保持挂起状态。

在以下示例中,pod 请求主机节点上的 40 个 CPU,并且 pod 停留在 Pending 状态:

$ kubectl describe pod cluster-vertica-defaultsubcluster-0
...
Status:         Pending
...
Containers:
  server:
    Image:       docker.io/library/vertica-k8s:default-1
    Ports:       5433/TCP, 5434/TCP, 22/TCP
    Host Ports:  0/TCP, 0/TCP, 0/TCP
    Command:
      /opt/vertica/bin/docker-entrypoint.sh
      restart-vertica-node
    Limits:
      memory:  200Gi
    Requests:
      cpu: 40
      memory:  200Gi
...
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  3h20m  default-scheduler  0/5 nodes are available: 5 Insufficient cpu.

确认主机节点上可用的资源。以下命令确认主机节点只有 40 个可分配 CPU:

$ kubectl describe node host-node-1
...
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Sat, 20 Mar 2021 22:39:10 -0400   Sat, 20 Mar 2021 13:07:02 -0400   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Sat, 20 Mar 2021 22:39:10 -0400   Sat, 20 Mar 2021 13:07:02 -0400   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Sat, 20 Mar 2021 22:39:10 -0400   Sat, 20 Mar 2021 13:07:02 -0400   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Sat, 20 Mar 2021 22:39:10 -0400   Sat, 20 Mar 2021 13:07:12 -0400   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  172.19.0.5
  Hostname:    eng-g9-191
Capacity:
  cpu:                40
  ephemeral-storage:  285509064Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             263839236Ki
  pods:               110
Allocatable:
  cpu:                40
  ephemeral-storage:  285509064Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             263839236Ki
  pods:               110
...
Non-terminated Pods:          (3 in total)
  Namespace                   Name                                   CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                   ----                                   ------------  ----------  ---------------  -------------  ---
  default                     cluster-vertica-defaultsubcluster-0    38 (95%)      0 (0%)      200Gi (79%)      200Gi (79%)    51m
  kube-system                 kube-flannel-ds-8brv9                  100m (0%)     100m (0%)   50Mi (0%)        50Mi (0%)      9h
  kube-system                 kube-proxy-lgjhp                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         9h
...

要更正此问题,请将子群集中的 resource.requests 减少到低于最大可分配 CPU 的值。以下示例使用名为 patch.yaml 的 YAML 格式文件来降低 pod 的资源请求:

$ cat patch.yaml
spec:
  subclusters:
    - name: defaultsubcluster
      resources:
        requests:
          memory: 238Gi
          cpu: "38"
        limits:
          memory: 238Gi
$ kubectl patch vdb cluster-vertica –-type=merge --patch “$(cat patch.yaml)”
verticadb.vertica.com/cluster-vertica patched

添加和测试 vlogger sidecar

Vertica 提供了 vlogger 映像,该映像将日志从 vertica.log 发送到主机节点上的标准输出以进行日志聚合。

要将 sidecar 添加到 CR,请在 spec.sidecars 定义中添加一个元素:

spec:
  ...
  sidecars:
    - name: vlogger
      image: vertica/vertica-logger:1.0.0

要测试 sidecar,请运行以下命令并验证它是否返回日志:

$ kubectl logs pod-name -c vlogger

2021-12-08 14:39:08.538 DistCall Dispatch:0x7f3599ffd700-c000000000997e [Txn
2021-12-08 14:40:48.923 INFO New log
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> Log /data/verticadb/v_verticadb_node0002_catalog/vertica.log opened; #1
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> Processing command line: /opt/vertica/bin/vertica -D /data/verticadb/v_verticadb_node0002_catalog -C verticadb -n v_verticadb_node0002 -h 10.20.30.40 -p 5433 -P 4803 -Y ipv4
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> Starting up Vertica Analytic Database v11.0.2-20211201
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO>
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> vertica(v11.0.2) built by @re-docker5 from master@a44ffabdf3f05e8d104426506b088192f741c485 on 'Wed Dec  1 06:10:34 2021' $BuildId$
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> CPU architecture: x86_64
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> 64-bit Optimized Build
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> Compiler Version: 7.3.1 20180303 (Red Hat 7.3.1-5)
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> LD_LIBRARY_PATH=/opt/vertica/lib
2021-12-08 14:40:48.923 Main Thread:0x7fbbe2cf6280 [Init] <INFO> LD_PRELOAD=
2021-12-08 14:40:48.925 Main Thread:0x7fbbe2cf6280 <LOG> @v_verticadb_node0002: 00000/5081: Total swap memory used: 0
2021-12-08 14:40:48.925 Main Thread:0x7fbbe2cf6280 <LOG> @v_verticadb_node0002: 00000/4435: Process size resident set: 28651520
2021-12-08 14:40:48.925 Main Thread:0x7fbbe2cf6280 <LOG> @v_verticadb_node0002: 00000/5075: Total Memory free + cache: 59455180800
2021-12-08 14:40:48.925 Main Thread:0x7fbbe2cf6280 [Txn] <INFO> Looking for catalog at: /data/verticadb/v_verticadb_node0002_catalog/Catalog
...

使用 VerticaAutoscaler 找不到 CPU 指标

您可能会注意到 VerticaAutoScaler 没有根据 CPU 利用率正确缩放:

$ kubectl get hpa
NAME                REFERENCE                           TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
autoscaler-name     VerticaAutoscaler/autoscaler-name   <unknown>/50%   3         12        0          19h

$ kubectl describe hpa
Warning: autoscaling/v2beta2 HorizontalPodAutoscaler is deprecated in v1.23+, unavailable in v1.26+; use autoscaling/v2 HorizontalPodAutoscaler
Name: autoscaler-name
Namespace: namespace
Labels: <none>
Annotations: <none>
CreationTimestamp: Thu, 12 May 2022 10:25:02 -0400
Reference: VerticaAutoscaler/autoscaler-name
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): <unknown> / 50%
Min replicas: 3
Max replicas: 12
VerticaAutoscaler pods: 3 current / 0 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 7s horizontal-pod-autoscaler failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
Warning FailedComputeMetricsReplicas 7s horizontal-pod-autoscaler invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)

您收到此错误是因为未安装指标服务器:

$ kubectl top nodes
error: Metrics API not available

要安装指标服务器:

  1. 下载 components.yaml 文件:

    $ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    
  2. (可选)禁用 TLS:

    $ if ! grep kubelet-insecure-tls components.yaml; then
      sed -i 's/- args:/- args:\n - --kubelet-insecure-tls/' components.yaml;
    
  3. 应用 YAML 文件:

    $ kubectl apply -f components.yaml
    
  4. 验证指标服务器是否正在运行:

    $ kubectl get svc metrics-server -n namespace
    NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    metrics-server   ClusterIP   10.105.239.175   <none>        443/TCP   19h
    

VerticaAutoscaler 的 CPU 请求错误

您可能会收到一条错误消息,指出:

failed to get cpu utilization: missing request for cpu

收到此错误是因为您必须对所有容器(包括 sidecar 容器)设置资源限制。要更正此错误:

  1. 验证错误:

    $ kubectl get hpa
    NAME                REFERENCE                           TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    autoscaler-name     VerticaAutoscaler/autoscaler-name   <unknown>/50%   3         12        0          19h
    
    $ kubectl describe hpa
    Warning: autoscaling/v2beta2 HorizontalPodAutoscaler is deprecated in v1.23+, unavailable in v1.26+; use autoscaling/v2 HorizontalPodAutoscaler
    Name: autoscaler-name
    Namespace: namespace
    Labels: <none>
    Annotations: <none>
    CreationTimestamp: Thu, 12 May 2022 15:58:31 -0400
    Reference: VerticaAutoscaler/autoscaler-name
    Metrics: ( current / target )
    resource cpu on pods (as a percentage of request): <unknown> / 50%
    Min replicas: 3
    Max replicas: 12
    VerticaAutoscaler pods: 3 current / 0 desired
    Conditions:
    Type Status Reason Message
    ---- ------ ------ -------
    AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
    ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: failed to get cpu utilization: missing request for cpu
    Events:
    Type Reason Age From Message
    ---- ------ ---- ---- -------
    Warning FailedGetResourceMetric 4s (x5 over 64s) horizontal-pod-autoscaler failed to get cpu utilization: missing request for cpu
    Warning FailedComputeMetricsReplicas 4s (x5 over 64s) horizontal-pod-autoscaler invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: missing request for cpu
    
  2. 向 CR 添加资源限制:

    $ cat /tmp/vdb.yaml
    apiVersion: vertica.com/v1beta1
    kind: VerticaDB
    metadata:
      name: vertica-vdb
    spec:
      sidecars:
        - name: vlogger
          image: vertica/vertica-logger:latest
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "100Mi"
              cpu: "100m"
      communal:
        credentialSecret: communal-creds
        endpoint: https://endpoint
            path: s3://bucket-location
      dbName: verticadb
      image: vertica/vertica-k8s:latest
      subclusters:
      - isPrimary: true
        name: sc1
        resources:
          requests:
            memory: "4Gi"
            cpu: 2
          limits:
            memory: "4Gi"
            cpu: 2
        serviceType: ClusterIP
        serviceName: sc1
        size: 3
      upgradePolicy: Auto
    
  3. 应用更新:

    $ kubectl apply -f /tmp/vdb.yaml
    verticadb.vertica.com/vertica-vdb created
    

当您设置新的 CPU 资源限制时,Kubernetes 会以滚动更新的方式重新调度 StatefulSet 中的每个 pod,直到所有 pod 都具有更新的 CPU 资源限制。