Elastic Search Cloud - 为重建索引添加 ca

Elastic Search Cloud - Adding ca for reindex

背景

我正在使用 Kubernetes 中的弹性云在 GKE 中使用弹性搜索。

我希望从一个集群到另一个集群执行重建索引。 所以我调用了以下内容:

POST_reindex

正文:

{
  "source": {
    "remote": {
      "host": "https://IP:PORT",
      "username": "USER",
      "password": "PASSWORD"
    },
    "index": "test"
  },
  "dest": {
    "index": "test"
  }
}

回复:

{
    "error": {
        "root_cause": [
            {
                "type": "s_s_l_handshake_exception",
                "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
            }
        ],
        "type": "s_s_l_handshake_exception",
        "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
        "caused_by": {
            "type": "validator_exception",
            "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
            "caused_by": {
                "type": "sun_cert_path_builder_exception",
                "reason": "unable to find valid certification path to requested target"
            }
        }
    },
    "status": 500
}

所以基本上就是说远程集群证书不可信

问题

我想添加一个 ca 到受信任的 ca 以重新索引。

根据文档 reindex.ssl.certificate_authorities 是我应该使用的。 所以我创建了一个秘密并将其路径添加到节点集 yaml:

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elastic-cluster-1
spec:
  version: 7.6.1
  image: docker.elastic.co/elasticsearch/elasticsearch:7.6.1
  nodeSets:
  - name: default
    count: 3
    config:
      node.master: true
      node.data: true
      node.ingest: true
      reindex.remote.whitelist: "REMOTE_IP"
      reindex.ssl.certificate_authorities: ["/app/secrets/ca.pem"]
    podTemplate:
      metadata:
        labels:
          # additional labels for pods
          type: elastic-master-node
      spec:
        initContainers:
        # Increase linux map count to allow elastic to store large memory maps
        - name: sysctl
          securityContext:
            privileged: true
          command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
        containers:
        - name: elasticsearch
          # specify resource limits and requests
          resources:
            limits:
              memory: 3.5Gi
              cpu: 1
          env:
          - name: ES_JAVA_OPTS
            value: "-Xms2g -Xmx2g"
          volumeMounts:
          - name: my-ca
            mountPath: /app/secrets
            readOnly: true
        volumes:
        - name: my-ca
          secret:
            secretName: my-ca
    # Request persistent data storage for pods
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: ssd
  - name: data
    count: 3
    config:
      node.master: false
      node.data: true
      node.ingest: true
    podTemplate:
      metadata:
        labels:
          # additional labels for pods
          type: elastic-data-node
      spec:
        initContainers:
        # Increase linux map count to allow elastic to store large memory maps
        - name: sysctl
          securityContext:
            privileged: true
          command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
        containers:
        - name: elasticsearch
          # specify resource limits and requests
          resources:
            limits:
              memory: 3.5Gi
              cpu: 1
          env:
          - name: ES_JAVA_OPTS
            value: "-Xms2g -Xmx2g"
    # Request persistent data storage for pods
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: ssd
  # Google cloud storage credentials
  secureSettings:
  - secretName: "gcs-credentials"
  http:
    service:
      spec:
        # expose this cluster Service with a LoadBalancer
        type: LoadBalancer
    tls:
      certificate:
        secretName: elasticsearch-certificate

Pod 初始化失败,出现以下错误:

{"type": "server", "timestamp": "2020-12-10T15:53:07,132Z", "level": "ERROR", "component": "o.e.b.ElasticsearchUncaughtExceptionHandler", "cluster.name": "elastic-cluster-1", "node.name": "elastic-cluster-1-es-default-2", "message": "uncaught exception in thread [main]",
"stacktrace": ["org.elasticsearch.bootstrap.StartupException: java.security.AccessControlException: access denied (\"java.io.FilePermission\" \"/app/secrets/ca.pem\" \"read\")",
"at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:174) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:125) ~[elasticsearch-cli-7.6.1.jar:7.6.1]",
"at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[elasticsearch-7.6.1.jar:7.6.1]",
"Caused by: java.security.AccessControlException: access denied (\"java.io.FilePermission\" \"/app/secrets/ca.pem\" \"read\")",
"at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[?:?]",
"at java.security.AccessController.checkPermission(AccessController.java:1036) ~[?:?]",
"at java.lang.SecurityManager.checkPermission(SecurityManager.java:408) ~[?:?]",
"at java.lang.SecurityManager.checkRead(SecurityManager.java:747) ~[?:?]",
"at sun.nio.fs.UnixChannelFactory.open(UnixChannelFactory.java:255) ~[?:?]",
"at sun.nio.fs.UnixChannelFactory.newFileChannel(UnixChannelFactory.java:143) ~[?:?]",
"at sun.nio.fs.UnixChannelFactory.newFileChannel(UnixChannelFactory.java:156) ~[?:?]",
"at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:217) ~[?:?]",
"at java.nio.file.Files.newByteChannel(Files.java:374) ~[?:?]",
"at java.nio.file.Files.newByteChannel(Files.java:425) ~[?:?]",
"at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420) ~[?:?]",
"at java.nio.file.Files.newInputStream(Files.java:159) ~[?:?]",
"at org.elasticsearch.common.ssl.PemUtils.readCertificates(PemUtils.java:594) ~[?:?]",
"at org.elasticsearch.common.ssl.PemTrustConfig.loadCertificates(PemTrustConfig.java:83) ~[?:?]",
"at org.elasticsearch.common.ssl.PemTrustConfig.createTrustManager(PemTrustConfig.java:73) ~[?:?]",
"at org.elasticsearch.common.ssl.SslConfiguration.createSslContext(SslConfiguration.java:136) ~[?:?]",
"at org.elasticsearch.index.reindex.ReindexSslConfig.reload(ReindexSslConfig.java:145) ~[?:?]",
"at org.elasticsearch.index.reindex.ReindexSslConfig.<init>(ReindexSslConfig.java:115) ~[?:?]",
"at org.elasticsearch.index.reindex.ReindexPlugin.createComponents(ReindexPlugin.java:88) ~[?:?]",
"at org.elasticsearch.node.Node.lambda$new(Node.java:456) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:271) ~[?:?]",
"at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1621) ~[?:?]",
"at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]",
"at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]",
"at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]",
"at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]",
"at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]",
"at org.elasticsearch.node.Node.<init>(Node.java:459) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.node.Node.<init>(Node.java:257) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Bootstrap.<init>(Bootstrap.java:221) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:221) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:349) ~[elasticsearch-7.6.1.jar:7.6.1]",
"at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.6.1.jar:7.6.1]",
"... 6 more"] }
uncaught exception in thread [main]
java.security.AccessControlException: access denied ("java.io.FilePermission" "/app/secrets/ca.pem" "read")
        at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
        at java.base/java.security.AccessController.checkPermission(AccessController.java:1036)
        at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)
        at java.base/java.lang.SecurityManager.checkRead(SecurityManager.java:747)
        at java.base/sun.nio.fs.UnixChannelFactory.open(UnixChannelFactory.java:255)
        at java.base/sun.nio.fs.UnixChannelFactory.newFileChannel(UnixChannelFactory.java:143)
        at java.base/sun.nio.fs.UnixChannelFactory.newFileChannel(UnixChannelFactory.java:156)
        at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:217)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:374)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:425)
        at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420)
        at java.base/java.nio.file.Files.newInputStream(Files.java:159)
        at org.elasticsearch.common.ssl.PemUtils.readCertificates(PemUtils.java:594)
        at org.elasticsearch.common.ssl.PemTrustConfig.loadCertificates(PemTrustConfig.java:83)
        at org.elasticsearch.common.ssl.PemTrustConfig.createTrustManager(PemTrustConfig.java:73)
        at org.elasticsearch.common.ssl.SslConfiguration.createSslContext(SslConfiguration.java:136)
        at org.elasticsearch.index.reindex.ReindexSslConfig.reload(ReindexSslConfig.java:145)
        at org.elasticsearch.index.reindex.ReindexSslConfig.<init>(ReindexSslConfig.java:115)
        at org.elasticsearch.index.reindex.ReindexPlugin.createComponents(ReindexPlugin.java:88)
        at org.elasticsearch.node.Node.lambda$new(Node.java:456)
        at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:271)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1621)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
        at org.elasticsearch.node.Node.<init>(Node.java:459)
        at org.elasticsearch.node.Node.<init>(Node.java:257)
        at org.elasticsearch.bootstrap.Bootstrap.<init>(Bootstrap.java:221)

我验证了 ca 存在于路径 /app/secrets/ca.pem 中并且具有读取权限:

我怎样才能正确地处理这个问题? 为什么它无法读取提供的 ca?

我遇到了完全相同的问题,在这里尝试了您的解决方案但失败了。它似乎应该工作。我最终放弃并禁用了远程证书的验证。

reindex.ssl.verification_mode: none

证书必须在 Elasticsearch 配置目录中。唯一的 actual 文档在配置 guide [不在参考中,天堂forfend] 第二个配置节下来,注意 #2.

https://www.elastic.co/guide/en/elasticsearch/reference/6.3/configuring-tls.html#tls-http

对于官方 Docker 图片,这是 /usr/share/elasticsearch/config/

关于你的下一个问题,“但是如果它不能位于配置目录以外的任何地方,为什么我必须指定完整路径?”答案是:¯\_(ツ)_/¯