﻿---
title: Deploy an Elasticsearch cluster
description: To deploy a simple Elasticsearch cluster specification, with one Elasticsearch node: The operator automatically creates and manages Kubernetes resources...
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/elasticsearch-deployment-quickstart
products:
  - Elastic Cloud on Kubernetes
applies_to:
  - Elastic Cloud on Kubernetes: Generally available
---

# Deploy an Elasticsearch cluster
To deploy a simple [Elasticsearch](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/solutions/search/get-started) cluster specification, with one Elasticsearch node:
```yaml
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.4.1
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF
```

The operator automatically creates and manages Kubernetes resources to achieve the desired state of the Elasticsearch cluster. It may take up to a few minutes until all the resources are created and the cluster is ready for use.
<warning>
  Setting `node.store.allow_mmap: false` has performance implications and should be tuned for production workloads as described in the [Virtual memory](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/virtual-memory) section.
</warning>

<note>
  If your Kubernetes cluster does not have any Kubernetes nodes with at least 2GiB of free memory, the pod will be stuck in `Pending` state. Check [*Manage compute resources*](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/manage-compute-resources) for more information about resource requirements and how to configure them.
</note>

<note>
  The cluster that you deployed in this quickstart guide only allocates a persistent volume of 1GiB for storage using the default [storage class](https://kubernetes.io/docs/concepts/storage/storage-classes/) defined for the Kubernetes cluster. You will most likely want to have more control over this for production workloads. Refer to [Volume claim templates](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates) for more information.
</note>

For a full description of each `CustomResourceDefinition` (CRD), refer to the [*API Reference*](https://docs-v3-preview.elastic.dev/elastic/cloud-on-k8s/tree/main/reference/api-reference) or view the CRD files in the [project repository](https://github.com/elastic/cloud-on-k8s/tree/3.4/config/crds). You can also retrieve information about a CRD from the cluster. For example, describe the Elasticsearch CRD specification with [`describe`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_describe/):
```sh
kubectl describe crd elasticsearch
```


## Monitor cluster health and creation progress

Get an overview of the current Elasticsearch clusters in the Kubernetes cluster with [`get`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_get/), including health, version and number of nodes:
```sh
kubectl get elasticsearch
```

When you first create the Kubernetes cluster, there is no `HEALTH` status and the `PHASE` is empty. After the pod and service start-up, the `PHASE` turns into `Ready`, and `HEALTH` becomes `green`. The `HEALTH` status comes from Elasticsearch's [cluster health API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-cluster-health).
```sh
NAME          HEALTH    NODES     VERSION   PHASE         AGE
quickstart              1         9.4.1               1s
```

While the Elasticsearch pod is in the process of being started it will report `Pending` as checked with [`get`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_get/):
```sh
kubectl get pods --selector='elasticsearch.k8s.elastic.co/cluster-name=quickstart'
```

Which will output similar to:
```sh
NAME                      READY   STATUS    RESTARTS   AGE
quickstart-es-default-0   0/1     Pending   0          9s
```

During and after start-up, up that pod’s [`logs`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_logs/) can be accessed:
```sh
kubectl logs -f quickstart-es-default-0
```

Once the pod has finished coming up, our original [`get`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_get/) request will now report:
```sh
NAME          HEALTH    NODES     VERSION   PHASE         AGE
quickstart    green     1         9.4.1     Ready         1m
```


## Access your Elasticsearch cluster

ECK automatically creates a `ClusterIP` service for [HTTP access to your cluster](/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/accessing-services#k8s-kubernetes-service). You can verify it with `kubectl get`:
```sh
kubectl get service quickstart-es-http
```

Which will output similar to:
```sh
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
quickstart-es-http   ClusterIP   10.15.251.145   <none>        9200/TCP   34m
```

In order to make requests to the [Elasticsearch API](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/rest-apis):
1. Get the credentials.
   By default, a user named `elastic` is created with the password stored inside a [Kubernetes secret](https://kubernetes.io/docs/concepts/configuration/secret/). This default user can be disabled if desired, refer to [Users and roles](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/users-roles/cluster-or-deployment-auth/native) for more information.
   ```sh
   PASSWORD=$(kubectl get secret quickstart-es-elastic-user -o go-template='{{.data.elastic | base64decode}}')
   ```
2. Retrieve the CA certificate.
   By default, ECK enables HTTPS for Elasticsearch, generates a private CA for each cluster, and issues certificates signed for the associated DNS service names, such as `quickstart-es-http.<namespace>.svc`.
   The CA certificate is available in the `<name>-es-http-certs-public` secret. For this `quickstart` cluster, run the following command to save the CA certificate to a local file named `quickstart-es-ca.crt`:
   ```sh
   kubectl get secret quickstart-es-http-certs-public -o go-template='{{index .data "ca.crt" | base64decode }}' > quickstart-es-ca.crt
   ```
   Refer to [Manage HTTP certificates on ECK](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/security/k8s-https-settings) for information about customizing HTTP TLS configuration.
3. Issue a request to the [Elasticsearch info API](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-info). You can do so from inside the Kubernetes cluster or from your local workstation.
   <tip>
   The following examples use `curl` to access the Elasticsearch endpoint with full TLS verification, providing the CA certificate with the `--cacert` option.For testing only, you can use [`--insecure`](https://curl.se/docs/manpage.html#-k) (or `-k`) to skip certificate verification. This flag turns off TLS trust checks and should not be used in production.
   </tip>
   - **From inside the Kubernetes cluster**
  Use the service name to access the Elasticsearch endpoint from any Kubernetes Pod:
  ```sh
  curl --cacert <PATH_TO_CA> -u "elastic:$PASSWORD" "https://quickstart-es-http.<namespace>.svc:9200" 
  ```
  For example, if you run the command from an Elasticsearch Pod and the cluster is deployed in the `default` namespace, you can run:
  ```sh
  curl --cacert /usr/share/elasticsearch/config/http-certs/ca.crt \
    -u "elastic:$PASSWORD" "https://quickstart-es-http.default.svc:9200"
  ```
- **From your local workstation**
  1. Start a local port-forward in a separate terminal to route `localhost:9200` to the `quickstart-es-http` Kubernetes Service:
   ```sh
   kubectl port-forward service/quickstart-es-http 9200
   ```
   <note>
   Port-forwarding is mainly intended for local testing. In production environments, if the cluster must be accessible from outside the Kubernetes cluster, consider using a `LoadBalancer` service or another exposure mechanism. Refer to [Allow public access](/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/accessing-services#k8s-allow-public-access) for more information.
   </note>
2. Access Elasticsearch through the forwarded port:
   ```sh
   curl --cacert quickstart-es-ca.crt -u "elastic:$PASSWORD" "https://localhost:9200"
   ```
   The previous command validates the certificate with the provided CA, but hostname verification fails because `localhost` is not present in the certificate SANs. To perform full TLS verification of both the certificate and the requested hostname, use:
   ```sh
   NAMESPACE=default 
   curl --cacert quickstart-es-ca.crt -u "elastic:$PASSWORD" \
     --resolve quickstart-es-http.${NAMESPACE}.svc:9200:127.0.0.1 \
     "https://quickstart-es-http.${NAMESPACE}.svc:9200"
   ```


## Next steps

This completes the quickstart of deploying an Elasticsearch cluster. We recommend continuing to:
- [Deploy a Kibana instance](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/kibana-instance-quickstart)
- For information about how to apply changes to your deployments, refer to [applying updates](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/update-deployments).
- To explore other configuration options for your Elasticsearch cluster, see [Elasticsearch configuration](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/elasticsearch-configuration) and [Configure deployments](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6566/deploy-manage/deploy/cloud-on-k8s/configure-deployments).