没有服务网格的多集群分片集群
我们建议部署服务网格,以促进多集群分片集群部署中资源之间的连接;但是,如果您希望在没有服务网格的情况下建立多集群分片集群部署,则可以按照本指南配置多集群资源之间所需的网络。
在没有服务网格的情况下,在多个Kubernetes集群上部署分片集群,要求每个进程都向外部公开,并配置为通过外部可用的主机名来标识自身。如果每个主机名的网络配置正确(即连接到任何给定主机名时的流量被路由到特定进程/pod),那么每个其他MongoDB进程和客户端都可以连接到集群中的所有进程。虽然客户端仅连接到mongos进程,但有必要公开其他组件,因为在分片集群部署中,所有进程都必须能够连接到分片集群中的每个其他进程。
步骤
安装并配置Kubernetes Operator。
您可以按照 多集群MongoDB Ops Manager部署指南中的并行过程 进行操作。
部署MongoDB资源。
如以下示例所示,将 type
和 topology
配置为 type=ShardedCluster
和 topology=MultiCluster
。
apiVersion: mongodb.com/v1 kind: MongoDB metadata: annotations: mongodb.com/v1.architecture: non-static name: mdb-sharded namespace: ls spec: shardCount: 1 topology: MultiCluster type: ShardedCluster version: 8.0.4 credentials: my-credentials opsManager: configMapRef: name: my-project persistent: true security: authentication: agents: mode: X509 enabled: true internalCluster: X509 modes: - X509 certsSecretPrefix: prefix tls: ca: issuer-ca enabled: true externalAccess: {} configSrv: clusterSpecList: - clusterName: kind-e2e-cluster-1 externalAccess: externalDomain: kind-e2e-cluster-1.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-2 externalAccess: externalDomain: kind-e2e-cluster-2.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-3 externalAccess: externalDomain: kind-e2e-cluster-3.interconnected externalService: {} members: 1 mongos: clusterSpecList: - clusterName: kind-e2e-cluster-1 externalAccess: externalDomain: kind-e2e-cluster-1.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-2 externalAccess: externalDomain: kind-e2e-cluster-2.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-3 externalAccess: externalDomain: kind-e2e-cluster-3.interconnected externalService: {} members: 1 shard: clusterSpecList: - clusterName: kind-e2e-cluster-1 externalAccess: externalDomain: kind-e2e-cluster-1.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-2 externalAccess: externalDomain: kind-e2e-cluster-2.interconnected externalService: {} members: 1 - clusterName: kind-e2e-cluster-3 externalAccess: externalDomain: kind-e2e-cluster-3.interconnected externalService: {} members: 1
示例详情和注意事项
上述示例尚未准备好用于生产环境。请注意以下详细信息和注意事项:
示例中的域 (
kind-e2e-cluster-3.interconnected
) 是人为的,应替换为适当的外部可访问域。该配置使用 TLS(没有 TLS,就无法安全地向外部公开MongoDB进程)和 x509身份验证。可以根据需要任意配置。请参阅相应的加密和身份验证以学习;了解更多信息。
必须为以下组件颁发分片集群中的 TLS 证书:
每个分片副本集
配置服务器副本集
Mongos
每个 TLS 证书(TLS 类型的
-cert
密钥,手动提供或由 cert-manager 颁发)必须在运行Kubernetes Operator 的Kubernetes集群中提供。从那里, Kubernetes Operator 自动将必要的资源(生成的-cert-pem
密钥)复制到其他Kubernetes集群。每个组件的每个 TLS 证书必须包含该组件副本集的所有进程的所有主机名。示例,为第一个分片(索引0)颁发的证书必须在证书的 SAN字段中包含以下主机名(针对部署它的每个集群;Pod 名称遵循
mdb-sharded-<shardIdx>-<clusterIdx>-<podIdxInThisCluster>
约定)。mdb-sharded-0-0-0.kind-e2e-cluster-1.interconnected
mdb-sharded-0-1-0.kind-e2e-cluster-2.interconnected
mdb-sharded-0-2-0.kind-e2e-cluster-3.interconnected
作为参考,使用提供的示例部署的分片集群的所有进程都配置有以下主机名:
mdb-sharded-0-0-0.kind-e2e-cluster-1.interconnected (shard-0) mdb-sharded-0-1-0.kind-e2e-cluster-2.interconnected (shard-0) mdb-sharded-0-2-0.kind-e2e-cluster-3.interconnected (shard-0) mdb-sharded-config-0-0.kind-e2e-cluster-1.interconnected (cs) mdb-sharded-config-1-0.kind-e2e-cluster-2.interconnected (cs) mdb-sharded-config-2-0.kind-e2e-cluster-3.interconnected (cs) mdb-sharded-mongos-0-0.kind-e2e-cluster-1.interconnected (mongos) mdb-sharded-mongos-1-0.kind-e2e-cluster-2.interconnected (mongos) mdb-sharded-mongos-2-0.kind-e2e-cluster-3.interconnected (mongos) 每个
externalService:
都定义有一个默认对象{}
。这意味着Kubernetes Operator 使用默认值创建外部服务(为每个 Pod 创建的服务,应用于路由外部流量):
type: LoadBalancer
ports: 27017
、27018
用于备份
根据Kubernetes集群中的集群配置和负载负载均衡器控制器,对外部服务使用 LoadBalancer 类型将导致为分片的集群中的每个进程预配负载负载均衡器资源。这可能会导致分配大量 LoadBalancer 资源。在最小部署(1 mongos、3-节点配置服务器副本集、1 3-节点副本集的分片)中,这会创建 7 LoadBalancer 服务。
为了最大限度地减少创建的 LoadBalancer 资源数量,我们建议您使用 ClusterIP 服务配置外部访问权限,如以下示例所示:
- clusterName: kind-e2e-cluster-3 externalAccess: externalDomain: kind-e2e-cluster-3.interconnected externalService: type: ClusterIP 由于每个进程(pod) 都有一个关联的 ClusterIP 外部服务,因此您需要为Kubernetes集群创建一个外部“入口点”代理组件,它可以是任何代理(例如HAProxy、Nginx)支持 TLS 直通路由。
代理组件必须部署在每个Kubernetes集群中,并在为每个集群中的组件定义的主机名上向外部公开:
在上面的示例中,为
kind-e2e-cluster-3
定义的每个组件(mongos、配置服务器、分片)都使用 externalDomain:externalDomain: kind-e2e-cluster-3.interconnected
这意味着,代理组件应配置为接收到
*.kind-e2e-cluster-3.interconnected
的所有连接。每个连接都是遵循命名约定
<pod-name>.<externalDomain>
的主机名,示例:Shard Pod:
mdb-sharded-0-2-0.kind-e2e-cluster-2.interconnected (mdb-sharded-<shardIdx>-<clusterIdx>-<podIdx>
代理组件应配置为将任何流量(在端口
27017
或27018
上)代理(在 TCP 级别,无需重新加密流量)到相应的外部服务。示例,对于
mdb-sharded-0-2-0-svc-external
,在将调度配置为<pod-name>.kind-e2e-cluster-2.interconnected
转发到<pod-name>-mdb-sharded-0-2-0-svc-external
时,可以使用通用规则。
请注意,该示例中使用的
externalDomain
是一个人工创建的。必须将其替换为正确的域名。操作符跨Kubernetes集群部署所有进程以及所有必要的外部服务。
每个集群中的每个外部服务都必须在定义的外部域上接收外部流量。在网络完全配置之前,集群没有正确配置,因为对于要配置的副本集, mongod进程需要能够相互连接以实现复制目的。
使用外部域时,所有网络(用于复制和MongoDB 助手到MongoDB 的连接)默认都是通过外部域路由的,这可能效率不高。 改进方法之一是在集群内部配置网络或 DNS 解析,以便将同一Kubernetes集群中部署的 Pod 的外部主机名解析为外部服务的集群本地IP解决。