MongoDB 自定义资源是通过 Kubernetes 操作符定义和管理 MongoDB 部署的主要方式。您无需直接配置 MongoDB 实例,只需在 YAML 显示文件中声明您所需的状态,操作符便会协调集群的实际状态以匹配该状态。本指南将带您了解该显示文件的概念构建块,帮助您了解每个配置区域的功能,以及在规划部署以满足团队要求时何时何地需要它。
无论是初次建立开发副本集,还是在生产分片集群上进行迭代,此处概述的决策构成了 Kubernetes 上稳定、安全、高性能 MongoDB 部署的基础。
有关完整的字段规范,请参阅 MongoDB 数据库资源规范。
选择部署类型
您需要做的第一个决定是要创建哪种类型的 MongoDB 部署。spec.type 字段接受三个值,每个值都针对不同的工作负载和操作要求。在写入任何 YAML 代码之前,了解它们之间的权衡关系至关重要。
独立运行的实例运行单个 mongod 进程。它们最适合于当地开发、测试场景或评估功能,在这些场景中,冗余不是问题。由于独立运行的实例没有复制,因此不支持自动故障转移,也不建议将其用于生产数据。
副本集是 MongoDB 的默认生产拓扑结构。副本集由多个 mongod 节点(通常三个或更多)组成,这些节点保持数据的相同副本。如果主节点失败,剩余节点将选举一个新的主节点,无需手动介入。选择副本集可以为您提供高可用性、通过从节点读取来实现读取可扩展性,以及执行滚动维护的能力。对于大多数团队而言,这是您开始的地方:
apiVersion: mongodb.com/v1 kind: MongoDB metadata: name: my-replica-set spec: type: ReplicaSet members: 3 version: "8.0.0" opsManager: configMapRef: name: my-project-configmap credentials: my-credentials persistent: true
分片集群将数据分布到多个分片,每个分片本身都是一个副本集。分片前有 mongos 个路由器,用于引导客户端流量,以及一个专用的配置服务器副本集,用于存储集群元数据。如果数据集的增长超出单个副本集可以有效提供服务的范围,或者您需要水平扩展写入,分片集群是正确的选择。配置更复杂,因为您必须指定分片、每个分片的 mongod 个实例、mongos 个路由器和配置服务器的计数:
apiVersion: mongodb.com/v1 kind: MongoDB metadata: name: my-sharded-cluster spec: type: ShardedCluster shardCount: 2 mongodsPerShardCount: 3 mongosCount: 2 configServerCount: 3 version: "8.0.0" opsManager: configMapRef: name: my-project-configmap credentials: my-credentials persistent: true
连接到 MongoDB Ops Manager
每个 MongoDB 自定义资源都必须链接到 Ops Manager 项目。此连接是 Kubernetes 操作符 注册部署以进行监控、自动化和备份的方式。两个配置使连接工作:用于识别项目的 ConfigMap 和用于存储 API 凭证的 Secret。
ConfigMap 告诉 Kubernetes 操作符将部署放置在哪个 MongoDB Ops Manager 项目中。至少必须包含指向 MongoDB Ops Manager 实例的 projectName 和 baseUrl。您可以选择使用 orgId 将部署固定到特定组织:
apiVersion: v1 kind: ConfigMap metadata: name: my-project-configmap data: projectName: "MyKubernetesProject" baseUrl: "https://ops-manager.example.com" orgId: "5e8f8b8b8b8b8b8b8b8b8b8b"
Secret 包含 Kubernetes 操作符代表您向 MongoDB Ops Manager API 进行身份验证时使用的编程 API 密钥对:
kubectl create secret generic my-credentials \ --from-literal="publicKey=<public-api-key>" \ --from-literal="privateKey=<private-api-key>"
然后,在 MongoDB CR 中引用这两个参数:
spec: opsManager: configMapRef: name: my-project-configmap credentials: my-credentials
要了解有关创建这些必备条件的更多信息,请参阅为 Kubernetes Operator 创建凭证和使用 ConfigMap 为每个 MongoDB 部署创建一个项目。
MongoDB 版本和功能兼容性
spec.version 字段设置 Kubernetes Operator 部署的 MongoDB 服务器版本(例如 "8.0.0")。选择正确的版本不仅仅是为了获取最新功能。您还应考虑驱动程序库、正在运行的 MongoDB Ops Manager 版本以及团队的升级节奏的版本兼容矩阵。
在主版本之间升级时,featureCompatibilityVersion (特征兼容性版本)字段可以为您提供安全网。特征兼容性版本 控制哪些存储引擎和复制功能处于活动状态,它可以设置得低于二进制版本身。这样,您可以先升级二进制文件,验证稳定性,然后再提高特征兼容性版本,以在单独的有意步骤中解锁新功能。如果您需要回滚,较低的 特征兼容性版本 可确保数据文件与上一个二进制版本保持兼容。
spec: version: "8.0.0" featureCompatibilityVersion: "7.0"
有关参考,请参阅规格中的 spec.version 和 spec.featureCompatibilityVersion。
保护您的部署
Kubernetes 中 MongoDB 部署的**安全**性具有两个维度:使用 TLS 加密网络流量,以及验证客户端和集群节点。这两个都在 spec.security 块下配置,了解它们如何交互对于获取安全且可用的部署至关重要。
使用 TLS 加密连接
TLS 加密可保护客户端与 MongoDB 服务器之间以及副本集节点之间传输中的数据。启用 TLS 时,Kubernetes 操作符预期包含服务器证书和私钥的秘密,并可选包含带有签名该证书的 CA 证书的 ConfigMap。
certsSecretPrefix 字段告诉 Kubernetes 操作符如何获取证书 Secret 的名称。如果将前缀设置为 mdb,并将部署命名为 my-replica-set,则 Kubernetes 操作符会查找命名为 mdb-my-replica-set-cert 的 Secret。如下示例所示,当多个部署共享命名空间时,此命名规范可避免冲突:
spec: security: certsSecretPrefix: "mdb" tls: enabled: true ca: "custom-ca-configmap"
如果使用默认 MongoDB CA,可以省略 ca 字段。否则,将 CA 证书上传到 ConfigMap 中,并在此处引用它。要了解如何为 Kubernetes 中的 MongoDB 生成和管理 TLS 证书,包括 cert-manager 集成,请参阅配置加密和设置 cert-manager 集成。
选择身份验证机制
除了加密,您还需要确定客户端如何证明其身份。该操作符支持四种身份验证模式,您可以同时启用多个:
SCRAM(加盐挑战响应身份验证机制)是最简单的设置方式。用户使用用户名和密码进行身份验证。它适用于通过环境变量注入或 Kubernetes secret 管理凭证的应用程序,并且不需要 PKI 基础设施。
X.509 使用 TLS 客户端证书作为身份证明。如果您已有证书基础设施并希望完全避免基于密码的凭证,这是一个不错的选择。这需要启用 TLS。
LDAP 将身份验证委托给外部目录服务,使其成为可以集中管理用户身份的组织的理想选择。此模式需要可网络访问的 LDAP 服务器和绑定凭证。
OIDC(OpenID Connect)与 Azure AD、Okta 或 Google 等身份提供程序集成,以实现基于令牌的身份验证。这是最现代的方法,可与云环境中的工作负载身份模式很好地协作。
您在 spec.security.authentication 下配置身份验证:
spec: security: tls: enabled: true authentication: enabled: true modes: ["SCRAM", "X509"] internalCluster: "X509"
internalCluster 字段控制副本集节点如何彼此之间进行身份验证。将其设置为 "X509" 意味着节点间流量使用 X.509 证书,即使客户端使用 SCRAM 进行身份验证。
有关详细的身份验证设置程序,请参阅启用身份验证。
存储和持久性
MongoDB 是一种有状态的工作负载,因此配置存储的方式会直接影响性能、持久性以及从故障中恢复的能力。对于数据丢失不可接受的任何环境(基本上是除了一次性测试之外的所有环境),spec.persistent 字段必须设置为 true。启用持久性后,Kubernetes 操作符会创建可以在 Pod 重启和重新调度后依然存在的 PersistentVolumeClaims (PVC)。
单卷与多卷
默认情况下,MongoDB 使用单个卷所有数据。这对于开发和许多生产工作负载来说是足够的,但有些团队会将数据、日志和日志放在不同的卷上。分离它们可以让您将更快的存储类别分配给关键性能路径,例如预写日志,同时使用更便宜的存储来存储日志,如下示例所示:
spec: podSpec: persistence: multiple: data: storage: "200Gi" storageClass: "fast-ssd" journal: storage: "50Gi" storageClass: "fast-ssd" logs: storage: "20Gi" storageClass: "standard"
如果单个卷即可,则配置更简单:
spec: podSpec: persistence: single: storage: "100Gi" storageClass: "standard"
对于分片集群,每个分片、每个配置服务器和 mongos 路由器都有其自己的 Pod 规格 (shardPodSpec、configSrvPodSpec、mongosPodSpec),因此周全考虑存储类别尤为重要。这使您可以为每个组件独立调整存储大小和层级。
有关完整的持久性字段集,请参阅规格参考中的 独立运行的实例设置,其中包含 spec.podSpec.persistence.single、spec.podSpec.persistence.multiple.data 和相关字段。
资源分配和 Pod 模板
在部署时间内正确调整 MongoDB Pod 的 CPU 和内存是最具影响的决策之一,并且随着工作负载的变化,您可能会重新访问。Kubernetes Operator 通过 podSpec (用于副本集和独立运行的实例)和 shardPodSpec、configSrvPodSpec 和 mongosPodSpec (用于分片集群)暴露资源控制。
为 CPU 和内存设置 requests 和 limits,可确保 Kubernetes 将 Pod 调度到具有足够容量的节点,并防止失控进程影响同一节点上的其他工作负载。以下示例说明了可作为起点的配置。在此配置中,您将创建至少具有 2 个 CPU 内核和 4 GiB 内存的生产副本集节点,并将限制设置为匹配或超过这些值:
spec: podSpec: podTemplate: spec: containers: - name: mongodb-enterprise-database resources: requests: cpu: "2" memory: "4Gi" limits: cpu: "4" memory: "8Gi"
Pod 模板还允许您设置标签、注解、容忍度以及亲和性规则。亲和性规则在生产环境中尤为重要,因为它们控制着副本集如何在 Kubernetes 节点和故障域之间进行分布式。
例如,以下亲和规则将节点分布到可用区域,以防止区域级别的服务中断:
spec: podSpec: podTemplate: spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app.kubernetes.io/name: my-replica-set topologyKey: "topology.kubernetes.io/zone"
有关 podTemplate 字段的完整列表,请参阅规格参考,尤其是 spec.podSpec.podTemplate.spec.affinity。
配置备份
Kubernetes 操作符 中的备份使用 构建于 MongoDB Ops Manager 的连续备份功能。启用后,MongoDB Ops Manager 会实时捕获oplog 并定期拍摄快照,这些功能可以提供时间点恢复。这意味着您可以恢复到配置的保留窗口内的任何秒,而不仅仅是最后一个快照的时间戳。
要在 MongoDB 资源上启用备份,请将 spec.backup.mode 设置为 enabled。您还可以配置快照计划,该计划可控制快照的拍摄频率和保留时长,如下示例所示:
spec: backup: mode: enabled snapshotSchedule: snapshotIntervalHours: 6 snapshotRetentionDays: 7 dailySnapshotRetentionDays: 30 pointInTimeWindowHours: 24
如果您的组织要求对静态备份数据进行加密,则可以与符合 KMIP 规范的密钥管理服务器集成,如下示例所示:
spec: backup: mode: enabled encryption: kmip: client: clientCertificatePrefix: "backup-kmip"
autoTerminateOnDeletion 标志控制在 MongoDB 资源被删除时是否清理备份数据。在非生产环境中将其设置为 true 以避免孤立的备份状态;在生产环境中将其保持为 false 以使备份数据在资源被意外删除后仍可用:
spec: backup: mode: enabled autoTerminateOnDeletion: false
分配标签可让您控制特定部署使用哪些备份基础设施(oplog 存储、快照存储),在多个部署共享单个 MongoDB Ops Manager 实例时,这十分有用。
要了解全部备份设置,请参阅规范参考中的 副本集设置。要了解如何部署备份基础设施本身,请参阅配置 MongoDB 数据库备份。
对外公开部署
默认情况下,Kubernetes 中的 MongoDB 部署只能在集群内访问。许多团队需要从 Kubernetes 外运行的应用程序、开发过程中的客户端工具或多区域架构中的另一个 Kubernetes 集群访问其数据库。
spec.externalAccess 块指示 Kubernetes 操作符创建 Kubernetes 服务,以将外部流量路由到 MongoDB Pod。您可以选择 LoadBalancer 服务(预配云提供商负载均衡器)和 NodePort 服务(在每个集群节点上曝露静态端口),如以下示例所示:
spec: externalAccess: externalService: spec: type: LoadBalancer annotations: service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
对于副本集,此外还可以配置 externalDomain 为每个节点分配可预测的 DNS 主机名,这可简化客户端的连接字符串构建:
spec: externalAccess: externalDomain: "mongodb.example.com" externalService: spec: type: LoadBalancer
要了解更多信息,请参阅从 Kubernetes 外部连接到 MongoDB 数据库资源。
调整 MongoDB Server 参数
在自定义资源中,并非每个 MongoDB 调优设置都有一级字段。对于未包含在 Kubernetes 操作符的显式模式中的任何设置,spec.additionalMongodConfig 块可让您传递任意 mongod 配置选项。这些将直接转换为 MongoDB Ops Manager 应用的服务器配置。
additionalMongodConfig 的常用用途包括调整 WiredTiger 缓存大小、限制 TLS 协议版本或更改监听端口,如以下示例所示:
spec: additionalMongodConfig: net: tls: disabledProtocols: "TLS1_0,TLS1_1" storage: wiredTiger: engineConfig: cacheSizeGB: 4
在分片集群中,每个组件(分片、配置服务器、mongos)都有其自己的 additionalMongodConfig 字段,因此您可以独立调整它们。有关所支持选项的完整列表,请参阅 MongoDB 手册中的 MongoDB Server 参数。
MongoDB Agent 配置
每个 MongoDB Pod 都运行一个 MongoDB Agent,用于托管 mongod 进程、处理自动化任务并向 Ops Manager 报告状况。您可以通过 spec.agent 调整 MongoDB Agent 行为,包括启动选项(如日志轮换限制和连接超时),如以下示例所示:
spec: agent: startupOptions: maxLogFiles: "10" maxLogFileSize: "100" dialTimeout: "20"
spec.logLevel 字段设置 MongoDB Agent 的日志详细程度。在初始设置或疑难排除过程中,DEBUG 可以发挥巨大作用;在稳定状态生产中,INFO 或 WARN 可以避免过多的日志量:
spec: logLevel: "DEBUG"
有关 MongoDB 代理的完整设置,请参阅 规格参考。
多集群部署
对于需要将单个 MongoDB 部署分布到多个 Kubernetes 集群的团队(可能是为了地理备份、灾难恢复或数据主权),Kubernetes 操作符支持多集群拓扑。将 spec.topology 设置为 MultiCluster 会指示 Kubernetes 操作符,定义于 spec.clusterSpecList 中的副本集节点住在不同的 Kubernetes 集群中,如下示例所示:
spec: topology: MultiCluster clusterSpecList: - clusterName: "cluster-us-east" members: 2 - clusterName: "cluster-us-west" members: 2 - clusterName: "cluster-eu-west" members: 1
多集群部署会增加额外的前提条件,包括跨集群网络和服务网格或外部 DNS 配置。在继续之前,请查看多集群前提条件和多集群架构。
有关多集群规范字段,请参阅多 Kubernetes 集群规范。
随时维护 MongoDB 自定义资源配置
MongoDB 自定义资源不是一次性文物。随着团队要求的变化,您将扩展节点、添加分片、启用备份、轮换 TLS 证书、升级 MongoDB 版本或调整资源限制。Kubernetes 操作符正是为此设计的:您更新 YAML 显示文件,使用 kubectl apply 应用它,Kubernetes 操作符会逐渐协调更改。
安全迭代的几条指南:
逐渐扩展节点。一次添加或删除一个副本集节点可以降低选举中断的风险。
分两步升级版本。首先在将
featureCompatibilityVersion保持在上一级别的同时提升二进制版本,然后在验证稳定性后提升特征兼容性版本。在证书到期前进行轮换。TLS 证书的生命周期有限。规划轮换过程,最好使用
cert-manager自动化,并首先在非生产环境中对其进行测试。谨慎测试存储变更。某些存储变更(如切换存储类)可能需要手动卷积迁移。始终在预发布环境集群中进行验证。
监控资源状态。在任何更改之后,通过使用
kubectl get mdb检查资源状态并查看 Kubernetes Operator 日志中的协调错误,验证 Kubernetes Operator 是否成功协调了您的更改。
有关修改部署的实际操作,请参阅 编辑数据库资源。
汇总所有信息
以下示例将本页上介绍的概念组合到可用于生产的副本集配置中。它包括 TLS、SCRAM 身份验证、备份、反亲和调度、分割数据/日志/日志卷和 WiredTiger 调优:
apiVersion: mongodb.com/v1 kind: MongoDB metadata: name: prod-replica-set namespace: mongodb-production spec: type: ReplicaSet members: 3 version: "8.0.0" featureCompatibilityVersion: "8.0" opsManager: configMapRef: name: prod-project-configmap credentials: prod-credentials persistent: true security: certsSecretPrefix: "prod-mdb" tls: enabled: true ca: "prod-ca-configmap" authentication: enabled: true modes: ["SCRAM"] internalCluster: "X509" backup: mode: enabled autoTerminateOnDeletion: false snapshotSchedule: snapshotIntervalHours: 6 snapshotRetentionDays: 7 dailySnapshotRetentionDays: 30 pointInTimeWindowHours: 48 podSpec: persistence: multiple: data: storage: "500Gi" storageClass: "fast-ssd" journal: storage: "100Gi" storageClass: "fast-ssd" logs: storage: "50Gi" storageClass: "standard" podTemplate: spec: containers: - name: mongodb-enterprise-database resources: requests: cpu: "2" memory: "8Gi" limits: cpu: "4" memory: "16Gi" affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app.kubernetes.io/name: prod-replica-set topologyKey: "topology.kubernetes.io/zone" additionalMongodConfig: net: tls: disabledProtocols: "TLS1_0,TLS1_1" storage: wiredTiger: engineConfig: cacheSizeGB: 8
提示
MongoDB 数据库资源规格 — 完整的 MongoDB CR 字段参考
部署副本集 — 副本集部署步骤说明
部署分片集群 — 分片集群部署步骤
配置加密 — TLS 配置详情
启用身份验证 — 身份验证机制
配置 MongoDB 数据库备份 — 备份程序
从外部 Kubernetes 连接 MongoDB 数据库资源 — 外部访问设置
多 Kubernetes 集群资源规范 — 多集群字段参考