本主题介绍了如何将 Apigee Hybrid 运行时连接到另一个 Kubernetes 集群中的 Cassandra 数据存储区。在此配置中,运行时集群没有 Cassandra pod。 此配置的名称为外部数据存储区模式。
双集群拓扑
外部 Datastore 模式使用两个 Kubernetes 集群:
- Cassandra 集群运行 Cassandra 环。它不会运行混合运行时组件。
- 运行时集群运行 Hybrid 运行时组件,但没有 Cassandra pod。运行时组件通过网络连接到 Cassandra 集群中的 Cassandra 环。
Apigee 运算符在这两个集群中运行。您需要在每个集群中安装 cert-manager、Apigee 自定义资源定义 (CRD) 和 apigee-operator 图表。下表显示了每个集群中的组件:
| 组件 | Cassandra 集群 | 运行时集群 |
|---|---|---|
| cert-manager | 是 | 是 |
Apigee CRD 和 apigee-operator 图表 |
是 | 是 |
apigee-datastore 图表 |
可以,但需要使用 Cassandra pod | 会,但有 replicaCount: 0 且没有 Cassandra pod |
所有其他混合图表,例如 apigee-telemetry、apigee-redis、apigee-ingress-manager、apigee-org、apigee-env 和 apigee-virtualhost
|
否 | 是 |
Apigee 运算符在每个集群中执行不同的作业:
- 在 Cassandra 集群中,操作员会创建 Cassandra pod。它还管理 Cassandra 生命周期,例如,当您扩缩环时。
- 在运行时集群中,运算符不会创建 Cassandra pod。它会创建一个无头 Service 和一个指向 Cassandra 集群中 Cassandra 环的 Endpoints 对象。如果您启用动态端点同步,运行时集群中的运算符也会从 Cassandra 集群读取 Cassandra 端点。
设置概览
请按以下顺序执行这些步骤。顺序很重要。共享证书授权机构 (CA) 必须位于运行时集群中,然后运行时集群才能颁发证书。 如需了解详情,请参阅在安装运算符之前共享 Apigee CA。
-
在 Cassandra 集群中,安装 cert-manager、Apigee CRD、
apigee-operator图表和apigee-datastore图表。 - 确保 Cassandra 集群中的 Cassandra pod 已准备就绪。
- 在运行时集群中,安装 cert-manager。
-
将
apigee-casecret 从 Cassandra 集群复制到运行时集群。 请在运行时集群中安装apigee-operator图表之前执行此步骤。 -
在运行时集群中,安装 Hybrid 运行时组件。为
apigee-datastore图表使用外部数据存储区替换项。使用与 Cassandra 集群中相同的 Cassandra 凭据。 - (推荐)启用动态端点同步。
- 验证连接。
如需了解安装每个图表的步骤,请参阅使用 Helm 安装 Apigee Hybrid。
准备工作
请确保您的环境符合以下要求:
- 与 Cassandra 的网络连接。运行时集群必须通过 TCP 端口 9042 连接到 Cassandra pod。将这两个集群放在共享 VPC 中,或放在彼此之间具有专用连接的网络中。
- 一个区域。将这两个集群放在同一区域中。集群之间的往返时间会增加每个运行时请求的延迟时间。
- 两个集群中的 cert-manager。在每个集群中,cert-manager 会为运行时与 Cassandra 之间的 mTLS 连接颁发证书。在 Cassandra 集群和运行时集群中安装 cert-manager。
- 每个 Cassandra pod 的路由。Cassandra 客户端驱动程序直接连接到每个 Cassandra pod。运行时集群必须连接到每个 Cassandra pod 的 IP 地址,而不仅仅是一个地址。环前面的负载均衡器或单个虚拟 IP 地址不符合此要求。
- 与 Kubernetes API 服务器的网络连接。仅当您使用动态端点同步时,此要求才适用。运行时集群必须连接到 Cassandra 集群的 Kubernetes API 服务器。
在安装运算符之前共享 Apigee CA
在运行时集群中安装 cert-manager。然后,将 CA Secret 从 Cassandra 集群复制到运行时集群:
kubectl --context CASSANDRA_CLUSTER -n cert-manager get secret apigee-ca -o yaml \ | grep -v -E '^\s+(resourceVersion|uid|creationTimestamp|selfLink):' \ | kubectl --context RUNTIME_CLUSTER -n cert-manager apply -f -
替换以下内容:
-
CASSANDRA_CLUSTER:Cassandra 集群的 kubectl 上下文。 -
RUNTIME_CLUSTER:运行时集群的 kubectl 上下文。
grep 命令会移除属于 Cassandra 集群的元数据字段。
Kubernetes API 服务器不会创建具有 resourceVersion 值的对象。
多区域安装使用相同的共享 CA 原理。如需了解类似的复制步骤,请参阅轮替根 CA 证书。如需了解 Cassandra mTLS 配置,请参阅为 Cassandra 配置身份验证。
在两个集群中使用相同的 Cassandra 凭据
在两个集群的替换文件中使用以下方法之一:
-
在
cassandra.auth中设置相同的用户名和密码:default、admin、ddl、dml、jmx和jolokia。 -
只需设置
cassandra.auth.secret。在每个集群中,Secret 必须包含相同的用户和密码。请参阅创建 Secret。 -
将
cassandra.auth.secretProviderClass设置为读取同一 Secret 存储区的 SecretProviderClass。请参阅在 Hashicorp Vault 中存储 Cassandra Secret。
您不会从 Cassandra 集群复制凭据 Secret。运行时集群中的图表会根据您的替换项创建 Secret。如需查找身份验证失败,请参阅验证连接。
配置外部数据存储区
在运行时集群中,apigee-datastore 图表不得创建 Cassandra pod。
它必须指向 Cassandra 集群中的 Cassandra 环。将以下 cassandra 设置添加到运行时集群的替换文件中:
cassandra: # No Cassandra pods in the runtime cluster. replicaCount: 0 properties: # A comma-separated list of the Cassandra pod IP addresses. externalHost: "CASSANDRA_IP_ADDRESSES" storage: # Required, even with replicaCount: 0. storageSize: "10Gi"
其中:
-
CASSANDRA_IP_ADDRESSES是 Cassandra 集群中 Cassandra Pod 的 IP 地址的逗号分隔列表。例如10.0.0.1:9042,10.0.0.2:9042,10.0.0.3:9042。:9042后缀是可选的。如需获取该列表,请运行以下命令:kubectl --context CASSANDRA_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra \ -o jsonpath='{.items[*].status.podIP}' | tr ' ' ',' -
APIGEE_NAMESPACE是您的 Apigee 命名空间。默认值为apigee。 -
replicaCount: 0会告知运算符在运行时集群中不创建任何 Cassandra pod。运算符会创建一个无头服务和一个指向externalHost地址的端点对象。 -
cassandra.properties.externalHost是 Cassandra IP 地址的逗号分隔列表。每个地址都可以带有:port后缀,但运算符会忽略端口并始终使用端口 9042。该运算符仅接受 IP 地址。它会忽略主机名和 DNS 名称,并针对每个忽略的条目向其日志写入警告。 -
cassandra.storage.storageSize是必需的,但运行时集群不会为 Cassandra 创建 PersistentVolume。ApigeeDatastore验证 webhook 始终检查storageSize。请使用有效数量,例如10Gi。
当您扩缩环时以及 Kubernetes 重新调度 pod 时,pod IP 地址会发生变化。这样一来,externalHost 中的列表就会变得不正确。因此,我们建议使用动态端点同步。动态端点同步会自动使 Cassandra pod IP 地址列表保持最新状态。仅在简单安装或首次设置时使用 externalHost。
通过动态端点同步保持端点最新状态
如果只有 externalHost,您必须在每次 Cassandra 环发生变化时修改替换文件。动态端点同步可免去此手动步骤。运行时集群中的操作员会定期从 Cassandra 集群读取就绪的 Cassandra 端点。然后,它会将这些端点复制到运行时集群中的 Endpoints 对象中。
我们建议使用动态端点同步。每次扩缩环或 Kubernetes 重新调度 Pod 时,Pod IP 地址都会发生变化。动态端点同步会读取 Cassandra 无头 Service 的就绪 Pod 的 IP 地址。因此,运行时集群中的 Endpoints 对象始终包含当前的 Cassandra pod IP 地址。
使用动态端点同步时,仍需要 externalHost。在以下两种情况下,运营商会使用此运算符:
- 在首次成功从 Cassandra 集群读取数据之前。
- 当从 Cassandra 集群读取失败,并且之前成功读取时没有端点时。
如果读取失败,但之前成功读取过端点,则操作员会保留这些端点。运行时会保持与 Cassandra 的连接。
如需启用动态端点同步,请将 externalEndpointsSync 代码块添加到运行时集群的替换文件:
cassandra: replicaCount: 0 properties: # The first endpoints, and the fallback if a read fails. externalHost: "CASSANDRA_IP_ADDRESSES" externalEndpointsSync: # A secret in the runtime cluster. Its "kubeconfig" key holds the # kubeconfig for the Cassandra cluster. secretRef: apigee-remote-cass-kubeconfig # The namespace of the Cassandra headless Service in the Cassandra cluster. namespace: apigee # The Cassandra headless Service in the Cassandra cluster. serviceName: apigee-cassandra-default # The interval between reads, in seconds. The default is 30. intervalSeconds: 30 storage: storageSize: "10Gi"
在 Cassandra 集群中创建只读服务账号
运行时集群中的运算符使用 kubeconfig 连接到 Cassandra 集群。此 kubeconfig 必须使用具有最小权限的只读 ServiceAccount。此服务账号只能读取 Cassandra 端点。它无法更改 Cassandra 集群中的资源。
在 Cassandra 集群中,创建以下资源:
- 一个 ServiceAccount,例如
apigee-endpoint-reader。 -
Cassandra 命名空间中的角色和 RoleBinding。该角色仅授予核心
endpoints的get、list和watch动词。请勿提供其他动词,例如create、update、patch或delete。不授予对其他资源的访问权限。 - ServiceAccount 的长期有效令牌 Secret。
然后,为 Cassandra 集群的 Kubernetes API 服务器创建 kubeconfig 文件。此 kubeconfig 必须使用 ServiceAccount 的令牌。在运行时集群中,创建一个名称与您在 externalEndpointsSync.secretRef 中设置的名称相同的 Secret。将 kubeconfig 放在 kubeconfig 键中:
kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE create secret generic \ apigee-remote-cass-kubeconfig --from-file=kubeconfig=READER_KUBECONFIG_FILE
将 READER_KUBECONFIG_FILE 替换为只读服务账号的 kubeconfig 文件的路径。
kubeconfig 包含长效令牌。请像保管其他凭据一样妥善保管此密钥。
监控动态端点同步
如果从 Cassandra 集群读取数据失败,运行时会保持连接。但在运行时集群中,端点不会更改,直到再次成功读取为止。监控同步,以便在 Cassandra 环发生更改之前发现持续性故障。
运行时集群中的运算符会发出以下信号:
-
ApigeeDatastore资源状态中的EndpointSyncDegraded条件。在连续三次读取失败后,该条件会变为True。原因是RemoteReadFailed或NoReadyRemoteEndpoints。成功读取后,条件会变为False,原因为SyncSucceeded。 -
external_endpoint_sync_last_success_timestamp指标。此指标是上次成功读取的时间,以 Unix 秒为单位。 -
external_endpoint_sync_failures_total指标。此指标用于统计失败的读取次数。
这两个指标具有 ApigeeDatastore 资源的 namespace 和 name 标签。该运算符会在其指标端点上显示这些信息。
如需查看条件,请运行以下命令:
kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get apigeedatastore default \
-o jsonpath='{.status.conditions}'
我们建议针对 EndpointSyncDegraded 条件设置提醒。ApigeeDatastore 状态会在操作员重启时保持该条件。只有成功读取才会将条件设置为 False。
如果您还针对该指标使用了提醒,则当以下两个表达式之一为 true 时,系统会发送提醒:
-
time() - external_endpoint_sync_last_success_timestamp > 300 -
absent(external_endpoint_sync_last_success_timestamp)
仅在成功读取后,操作员才会设置相应指标。如果操作员在读取失败时重启,则指标会缺失。这样一来,第一个表达式就不匹配,只有第二个表达式会发送提醒。
验证连接
安装运行时组件后,在运行时集群中执行以下检查:
-
确保运行时集群没有 Cassandra Pod:
kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra
输出为
No resources found。 -
确保 Endpoints 对象指向 Cassandra 环:
kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get endpoints apigee-cassandra-default
ENDPOINTS列显示 Cassandra IP 地址。如果您使用动态端点同步,则这些是 Cassandra 集群中就绪的 Cassandra pod 的 IP 地址。 -
确保 Cassandra 设置作业已完成:
kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get jobs \ | grep -E 'apigee-cassandra-(schema|user)-setup'
COMPLETIONS列显示每个作业的1/1。如果作业未完成,请检查作业日志中是否存在身份验证错误。然后,确保这两个集群使用相同的 Cassandra 凭据。
扩缩 Cassandra 环
Cassandra 集群中的 Apigee 操作器拥有 Cassandra 生命周期。扩缩 Cassandra 集群中的 Cassandra。您无法从运行时集群扩缩 Cassandra。
遵循与运行时集群中的 Cassandra 环相同的规则:
- 以三的倍数扩缩 Cassandra。这样可确保环在三个可用区之间保持平衡。
- 在增加 pod 数量之前,请确保 Cassandra 集群具有足够的节点容量。
-
如果您不使用动态端点同步,请在每次扩缩操作后更新
externalHost。
如需了解详情,请参阅扩缩 Cassandra。
后续步骤
- 如需在每个集群中安装图表,请参阅使用 Helm 安装 Apigee Hybrid。
- 如需了解 Cassandra mTLS 和凭据,请参阅为 Cassandra 配置身份验证。
- 如需向 Cassandra 环添加容量,请参阅扩缩 Cassandra。