Search code examples
node.jstypescriptelasticsearchkubernetesmicrok8s

Can't connect to Elasticsearch with Node.Js on Kubernetes (self signed certificate in certificate chain)


I have a NodeJs application running inside a Kubernetes cluster (I am using microk8s). I've also followed the official steps to setup Elasticsearch on Kubernetes.

Issue

But I am unable to connect to the Elasticsearch cluster. I get this error:

ConnectionError: self signed certificate in certificate chain

This is a code snippet of my connection:

const client = new elasticsearch.Client({
  node: process.env.elasticsearch_node,
  // https://elasticsearch-es-http.default.svc.cluster.local:9200
});

Minimal reproduction

I've created a minimal reproduction of this issue here: https://github.com/flolu/elasticsearch-k8s-connection. (Setup instructions are in the README)

Basically, everything works fine when running Elasticsearch inside Docker compose, but I can't connect when running inside Kubernetes.

The reason for this is probably because I didn't setup TLS certificates correctly, but I haven't found any information about it. Do I configure it inside my NodeJs application when creating the ES client or at a cluster level?


Solution

  • The solution is to configure SSL and the Elastic user when creating the Client

    const client = new elasticsearch.Client({
      node: process.env.elasticsearch_node,
      auth: {
        username: "elastic",
        password: process.env.elasticsearch_password || "changeme",
      },
      ssl: {
        ca: process.env.elasticsearch_certificate,
        rejectUnauthorized: false,
      },
    });
    

    The password and the certificate are provided by Elastic. They are stored inside Kubernetes secrets. So I've just passed the password and the certificate into my NodeJs service via environment variables like this:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: search-deployment
    spec:
      selector:
        matchLabels:
          app: search
      replicas: 1
      template:
        metadata:
          labels:
            app: search
        spec:
          containers:
            - name: search
              image: search:placeholder_name
              imagePullPolicy: Always
              env:
                - name: elasticsearch_node
                  value: https://elasticsearch-es-http.default.svc.cluster.local:9200
                - name: elasticsearch_certificate
                  valueFrom:
                    secretKeyRef:
                      name: elasticsearch-es-http-ca-internal
                      key: tls.crt
                - name: elasticsearch_password
                  valueFrom:
                    secretKeyRef:
                      name: elasticsearch-es-elastic-user
                      key: elastic