On the previous post we used the minikube wrapper kube.sh to install ECK - Elastic Cloud on Kubernetes. ECK uses an operator that was created by Elastic to deploy and orchestrate the Elastic Stack in kubernetes. ECK is not the only way to install elasticsearch in kubernetes, you can also use Helm charts to install the Stack.
What is the difference between an operator and helm charts?
Helm
Helm is a package management system for kubernetes. The packaging format is called charts. In OS terms its like rpm or deb packages. An application is packed into a package that can be installed using a helm install command. It is used to get an application up and running quickly. You can run packages with minimal changes or even no changes at all and you can quickly repeat the application on multiple environments quickly.
Kubernetes operators
Operators also package applications into an easy to deploy formats but it also uses custom resources to include a glot of complex configuration data within the package. With operators you can deploy a stateful application in a automatic way and deploy an application across a cluster that is configured in a particular way to achieve HA. You can also automate other tasks via orchestration via operators.
When to use helm vs operators?
- Simple application install - any type of simple application install wtihout much customization, Helm is a better and easier choice
- Customizations? - If you are configuring application with a lot of configurations or orchestrations, operator would be better
- Iteration/maturity - If your application is mature and went through various iterations and you know how it works in the kubernetes environment and want to have some automation as next steps, operator would be better
Even with the differences both helm and operator has its uses. In this article we will install helm and configure Elasticsearch and kibana using helm charts.
Install Helm
Helm provides a super easy way to install the helm binary for any OS.
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
Lets install kube.sh and start our minikube environment
$ curl -fsSL https://raw.githubusercontent.com/jlim0930/scripts/master/kube.sh -o kube.sh
$ chmod +x kube.sh
$ ./kube.sh start
bash: warning: setlocale: LC_ALL: cannot change locale (C.UTF-8)
[DEBUG] minikube found.
[DEBUG] kubectl found.
[DEBUG] build minikube
[DEBUG] CPU will be set to 4 cores
❗ These changes will take effect upon a minikube delete and then a minikube start
[DEBUG] MEM will be set to 16005mb
❗ These changes will take effect upon a minikube delete and then a minikube start
😄 minikube v1.19.0 on Centos 7.9.2009
🎉 minikube 1.20.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.20.0
💡 To disable this notice, run: 'minikube config set WantUpdateNotification false'
✨ Using the docker driver based on user configuration
👍 Starting control plane node minikube in cluster minikube
💾 Downloading Kubernetes v1.20.2 preload ...
> preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB 100.00% 10.99 Mi
🔥 Creating docker container (CPUs=4, Memory=16005MB) ...
🐳 Preparing Kubernetes v1.20.2 on Docker 20.10.5 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
▪ Using image metallb/speaker:v0.8.2
▪ Using image metallb/controller:v0.8.2
🌟 The 'metallb' addon is enabled
[DEBUG] minikube IP is: 192.168.49.2
[DEBUG] LoadBalancer Pool: 192.168.49.150 - 192.168.49.175
Please note that we have a LoadBalancer Pool of 192.168.49.150-192.168.49.175. The range might be different on your machine but you should be able to browse or access these IP's from the same server/workstation.
Now we have everything we need and a running minikube environment to get going.
Elastic's Helm charts are located: https://github.com/elastic/helm-charts
Elasticsearch/Kibana/Filebeat/Metricbeat was GA'ed since 7.7 and currently as of today logstash and APM server is still in BETA.
Although you can install ECK operator using Helm charts as seen on https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html we will install Elasticsearch and Kibana as applications without the operator.
Lets get started
Add the elastic repo
$ helm repo add elastic https://helm.elastic.co
"elastic" has been added to your repositories
To see all packages in the elastic repository
$ helm search repo elastic
NAME CHART VERSION APP VERSION DESCRIPTION
elastic/elasticsearch 7.12.1 7.12.1 Official Elastic helm chart for Elasticsearch
elastic/apm-server 7.12.1 7.12.1 Official Elastic helm chart for Elastic APM Server
elastic/eck-operator 1.5.0 1.5.0 A Helm chart for deploying the Elastic Cloud on...
elastic/eck-operator-crds 1.5.0 1.5.0 A Helm chart for installing the ECK operator Cu...
elastic/filebeat 7.12.1 7.12.1 Official Elastic helm chart for Filebeat
elastic/kibana 7.12.1 7.12.1 Official Elastic helm chart for Kibana
elastic/logstash 7.12.1 7.12.1 Official Elastic helm chart for Logstash
elastic/metricbeat 7.12.1 7.12.1 Official Elastic helm chart for Metricbeat
You can add the -l
switch to get the long listing that shows all the available versions helm search repo elastic -l
Install elasticsearch
There are multiple ways to install a package
- You can just run
helm install elasticsearch elastic/elasticsearch
and it will install elasticsearch using the default values set in the helm chart. - You can download all the default values for the chart and edit it to customize the chart and install using the customized values
$ helm show values elastic/elasticserach | tee -a values.yaml $ vi values.yaml # Edit for your needs $ helm install elasticsearch elastic/elasticsearch -f ./values.yaml
- You can install using just
--set
to set the values of customization inline$ helm install elasticsearch elastic/elasticsearch --set xxxxxxxxxxxx
NOTES - all custom values and their meanings can be found on https://github.com/elastic/helm-charts/tree/master/elasticsearch Also it would be good to look through the values.yaml to see what you can set.
For our purposes I will install it using inline options
$ helm install elasticsearch elastic/elasticsearch --set service.type=LoadBalancer,antiAffinity="soft",replicas=3,imageTag=7.12.1
NAME: elasticsearch
LAST DEPLOYED: Sat May 15 09:34:35 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Watch all cluster members come up.
$ kubectl get pods --namespace=default -l app=elasticsearch-master -w
2. Test cluster health using Helm test.
$ helm test elasticsearch
$ kubectl get pods --namespace=default -l app=elasticsearch-master -w
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 0/1 Init:0/1 0 7s
elasticsearch-master-1 0/1 Init:0/1 0 7s
elasticsearch-master-2 0/1 Init:0/1 0 7s
elasticsearch-master-1 0/1 PodInitializing 0 53s
elasticsearch-master-2 0/1 PodInitializing 0 53s
elasticsearch-master-0 0/1 PodInitializing 0 53s
elasticsearch-master-0 0/1 Running 0 54s
elasticsearch-master-2 0/1 Running 0 54s
elasticsearch-master-1 0/1 Running 0 55s
elasticsearch-master-1 1/1 Running 0 118s
elasticsearch-master-0 1/1 Running 0 2m2s
elasticsearch-master-2 1/1 Running 0 2m4s
$ helm test elasticsearch
NAME: elasticsearch
LAST DEPLOYED: Sat May 15 09:34:35 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: elasticsearch-gtuee-test
Last Started: Sat May 15 09:36:57 2021
Last Completed: Sat May 15 09:36:59 2021
Phase: Succeeded
NOTES:
1. Watch all cluster members come up.
$ kubectl get pods --namespace=default -l app=elasticsearch-master -w
2. Test cluster health using Helm test.
$ helm test elasticsearch
$ kubectl get pod,svc,pv
NAME READY STATUS RESTARTS AGE
pod/elasticsearch-master-0 1/1 Running 0 3m27s
pod/elasticsearch-master-1 1/1 Running 0 3m27s
pod/elasticsearch-master-2 1/1 Running 0 3m27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/elasticsearch-master LoadBalancer 10.102.211.193 192.168.49.150 9200:30416/TCP,9300:31121/TCP 3m27s
service/elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 3m27s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m37s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-2cc64f66-2967-4734-92f4-6c428effd516 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-0 standard 3m27s
persistentvolume/pvc-61e9fa07-1ae9-4741-b835-e0b0877476ba 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-2 standard 3m27s
persistentvolume/pvc-9481c420-786a-4edc-a200-67ea5a043fb7 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-1 standard 3m27s
When I installed elasticsearch I passed a few settings service.type=LoadBalancer,antiAffinity="soft",replicas=3,imageTag=7.12.1
These settings can be found on the default values.yaml. I just passed the settings that I wanted to update and change from the default.
Setting | Changed |
---|---|
service.type | default is ClusterIP but I wanted to make it reachable and used a LoadBalancer |
antiAffinity | default is hard however since I am using minikube I need to set it as soft |
replicas | default is 1 I wanted to have 3 nodes |
imageTag | You can set this to any supported version of elastic |
Now that our cluster is up lets access it. As you scan also see from the above our elasticsearch-master service has an external IP of 192.168.49.150
so we'll use that to access it
$ curl 192.168.49.150:9200
{
"name" : "elasticsearch-master-0",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "MNEDcCWwQMOLZrYmQDoIvw",
"version" : {
"number" : "7.12.1",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "3186837139b9c6b6d23c3200870651f10d3343b7",
"build_date" : "2021-04-20T20:56:39.040728659Z",
"build_snapshot" : false,
"lucene_version" : "8.8.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
$ curl 192.168.49.150:9200/_cat/nodes
172.17.0.6 41 62 10 0.35 0.45 0.56 cdfhilmrstw - elasticsearch-master-2
172.17.0.4 27 62 10 0.35 0.45 0.56 cdfhilmrstw - elasticsearch-master-0
172.17.0.5 46 62 10 0.35 0.45 0.56 cdfhilmrstw * elasticsearch-master-1
The defaults does not setup any type of security and we can get into that later on.
Install kibana
Again you can get the defaults by running
$ helm show values elastic/kibana | tee -a values.yaml
$ vi values.yaml
For this example I will just run a simple kibana install via inline with minimal settings
$ helm install kibana elastic/kibana --set imageTag=7.12.1,service.type=LoadBalancer
NAME: kibana
LAST DEPLOYED: Sat May 15 09:52:24 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 1/1 Running 0 18m
elasticsearch-master-1 1/1 Running 0 18m
elasticsearch-master-2 1/1 Running 0 18m
kibana-kibana-5fb66568d8-vmr2f 0/1 ContainerCreating 0 40s
kibana-kibana-5fb66568d8-vmr2f 0/1 Running 0 54s
kibana-kibana-5fb66568d8-vmr2f 1/1 Running 0 103s
$ kubectl get pod,svc,pv
NAME READY STATUS RESTARTS AGE
pod/elasticsearch-master-0 1/1 Running 0 21m
pod/elasticsearch-master-1 1/1 Running 0 21m
pod/elasticsearch-master-2 1/1 Running 0 21m
pod/kibana-kibana-5fb66568d8-vmr2f 1/1 Running 0 3m42s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/elasticsearch-master LoadBalancer 10.102.211.193 192.168.49.150 9200:30416/TCP,9300:31121/TCP 21m
service/elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 21m
service/kibana-kibana LoadBalancer 10.99.43.212 192.168.49.151 5601:32143/TCP 3m42s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25m
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-2cc64f66-2967-4734-92f4-6c428effd516 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-0 standard 21m
persistentvolume/pvc-61e9fa07-1ae9-4741-b835-e0b0877476ba 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-2 standard 21m
persistentvolume/pvc-9481c420-786a-4edc-a200-67ea5a043fb7 30Gi RWO Delete Bound default/elasticsearch-master-elasticsearch-master-1 standard 21m
Looks like our kibana is running on 192.168.49.151
Again you can edit values and install using -f values.yaml
instead of inline.
I will be updating this article with SSL configuration, Security settings, and various use cases. If you have any usecase you want to suggest please let me know.
Can you please give a example of Elastic Agent , Fleet Server, kibana in Minikube, As i search for many places but nowhere i found a working solution, i tried 2-3 days but not able to make it running.