使用istio从Kubernetes pod通过Java应用程序连接到分片的mongodb集群

时间:2018-11-05 13:53:35

标签: mongodb kubernetes istio

我在GCP https://cloud.mongodb.com的地图集上托管了一个分片的mongodb集群

通过在Java应用程序中以这种方式配置主分片myapp-shard-00-01-vki7g.gcp.mongodb.net:27017并没有问题,我可以在本地运行docker容器时连接到它。

java -Dlog4j.configurationFile=resources/log4j2.properties \
                 -Dmyapp.myapp.userDatabases=mydb \
                 -Dmyapp.myapp.port=27018 \
                 -Dmyapp.mongo.host=myapp-shard-00-01-vki7g.gcp.mongodb.net \
                 -Dmyapp.mongo.port=27017 \
-Dmyapp.mongo.sslEnabled=true \
     -Dmyapp.mongo.authenticationMechanism=SCRAM-SHA-1 \
                 -Xms1G \
                 -Xmx3G \
                 -XX:+UseParallelGC \
                 -XX:+HeapDumpOnOutOfMemoryError \
                 -XX:HeapDumpPath=logs/java_pid.hprof \
                 -XX:+UseGCOverheadLimit \
                 -server \
                 -XX:+UseStringDeduplication \
                 -jar myapp.jar

export ENV_MYAPP_MONGO_USER=myusername export ENV_MYAPP_MONGO_PWD=mypassword export ENV_MYAPP_MONGO_AUTH_SOURCE=admin

但是,当我在Kubernetes上设置相同的容器并运行相同的命令以及设置环境变量时,出现以下错误

com.mongodb.MongoCommandException: Command failed with error 40413 (Location40413): 'BSON field 'OperationSessionInfo.$clusterTime' is a duplicate field' on server m8yapp-staging-shard-00-01-vki7g.gcp.mongodb.net:27017. The full response is { "operationTime" : { "$timestamp" : { "t" : 1541424794, "i" : 3 } }, "ok" : 0.0, "errmsg" : "BSON field 'OperationSessionInfo.$clusterTime' is a duplicate field", "code" : 40413, "codeName" : "Location40413", "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1541424794, "i" : 3 } }, "signature" : { "hash" : { "$binary" : "Lo375z7JMqIYZKjRhlXvJwQzoNE=", "$type" : "00" }, "keyId" : { "$numberLong" : "6592814596526964737" } } } }
    at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179) ~[mongodb-driver-core-3.8.2.jar!/:?]
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:293) ~[mongodb-driver-core-3.8.2.jar!/:?]
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255) [mongodb-driver-core-3.8.2.jar!/:?]
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99) [mongodb-driver-core-3.8.2.jar!/:?]
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:444) [mongodb-driver-core-3.8.2.jar!/:?]

我尝试通过以下方式设置以下出口:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongodb-staging
spec:
  hosts:
  - myapp-shard-00-01-vki7g.gcp.mongodb.net
  - myapp-shard-00-00-vki7g.gcp.mongodb.net
  - myapp-shard-00-02-vki7g.gcp.mongodb.net
  ports:
  - number: 27017
    name: mongo
    protocol: MONGO
  resolution: DNS

我还尝试将协议设置为TCP,将分辨率设置为NONE

我可以使用以下命令从本地以及kubernetes连接到此mongodb:

mongo --host myapp-shard-00-01-vki7g.gcp.mongodb.net --port 27017 --username <myusername> --password <mypassword> --ssl --authenticationDatabase admin

我无法在此处发布Java代码,但是我不确定在本地运行docker容器时,为什么在Kubernetes上抛出上述错误,为什么Docker容器会通过?

编辑

我尝试添加此内容

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongodb-staging
spec:
  hosts:
  - myapp-shard-00-01-vki7g.gcp.mongodb.net
  ports:
  - number: 27017
    name: tls-mongo
    protocol: tls
  resolution: DNS
  location: MESH_EXTERNAL

---  
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: mongodb
spec:
  hosts:
  - myapp-shard-00-01-vki7g.gcp.mongodb.net
  tls:
  - match:
    - port: 27017
      sni_hosts:
      - myapp-shard-00-01-vki7g.gcp.mongodb.net
    route:
    - destination:
        host: myapp-shard-00-01-vki7g.gcp.mongodb.net #primary
        port:
          number: 27017
      weight: 100

我添加了此内容,但仍然出现相同的错误。

1 个答案:

答案 0 :(得分:0)

您必须将对MongoDB的访问配置为使用CIDR表示法中带有IP块的TCP(请参见https://preliminary.istio.io/blog/2018/egress-tcp/)或通过SNI来配置TLS(请参见www.google.com示例的https://preliminary.istio.io/docs/tasks/traffic-management/egress/,只需替换HTTPS TLS。

我实际上已经完成了有关使用外部MongoDB服务的PR-参见https://github.com/istio/istio.io/pull/2347,在那里我指定了各种选项来控制流向MongoDB的外部流量。