├── LICENSE
├── README.md
├── es-curator-config.yaml
├── es-curator.yaml
├── es-data-pdb.yaml
├── es-data.yaml
├── es-discovery-svc.yaml
├── es-ingest-svc.yaml
├── es-ingest.yaml
├── es-master-pdb.yaml
├── es-master.yaml
├── es-svc.yaml
├── kibana-cm.yaml
├── kibana-svc.yaml
├── kibana.yaml
└── stateful
├── README.md
├── es-data-stateful.yaml
├── es-data-svc.yaml
├── es-master-stateful.yaml
└── es-master-svc.yaml
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This project is no longer maintained
2 |
3 | As of November 7th, 2018, I've decided to end my commitment to maintaining this repo and related.
4 |
5 | It's been 3 years since I last used Elasticsearch, so I no longer have the motivation it takes to maintain and evolve this project. Also, other projects need all the attention I can give.
6 |
7 | It was a great run, **thank you all**.
8 |
9 | # kubernetes-elasticsearch-cluster
10 | Elasticsearch cluster on top of Kubernetes made easy.
11 |
12 | ### Table of Contents
13 |
14 | * [(Very) Important Notes](#important-notes)
15 | * [Pre-Requisites](#pre-requisites)
16 | * [Build container image (optional)](#build-images)
17 | * [Test](#test)
18 | * [Deploy](#deploy)
19 | * [Access the service](#access-the-service)
20 | * [Pod anti-affinity](#pod-anti-affinity)
21 | * [Availability](#availability)
22 | * [Deploy with Helm](#helm)
23 | * [Install plug-ins](#plugins)
24 | * [Clean-up with Curator](#curator)
25 | * [Kibana](#kibana)
26 | * [FAQ](#faq)
27 | * [Troubleshooting](#troubleshooting)
28 |
29 | ## Abstract
30 |
31 | [Elasticsearch best-practices recommend to separate nodes in three roles](https://www.elastic.co/guide/en/elasticsearch/reference/6.2/modules-node.html):
32 |
33 | * `Master` nodes - intended for clustering management only, no data, no HTTP API
34 | * `Data` nodes - intended for client usage and data
35 | * `Ingest` nodes - intended for document pre-processing during ingestion
36 |
37 | Given this, I'm going to demonstrate how to provision a production grade scenario consisting of 3 master, 2 data and 2 ingest nodes.
38 |
39 |
40 |
41 | ## (Very) Important notes
42 |
43 | * Elasticsearch pods need for an init-container to run in privileged mode, so it can set some VM options.
44 | For that to happen, the `kubelet` should be running with args `--allow-privileged`, otherwise the init-container will fail to run.
45 |
46 | * By default, `ES_JAVA_OPTS` is set to `-Xms256m -Xmx256m`. This is a *very low* value but many users, i.e. `minikube` users,
47 | were having issues with pods getting killed because hosts were out of memory.
48 | One can change this in the deployment descriptors available in this repository.
49 |
50 | * As of the moment, Kubernetes pod descriptors use an `emptyDir` for storing data in each data node container.
51 | This is meant to be for the sake of simplicity and should be adapted according to one's storage needs.
52 |
53 | * The [stateful](stateful) directory contains an example which deploys the data pods as a `StatefulSet`.
54 | These use a `volumeClaimTemplates` to provision persistent storage for each pod.
55 |
56 | * By default, `PROCESSORS` is set to `1`. This may not be enough for some deployments, especially at startup time.
57 | Adjust `resources.limits.cpu` and/or `livenessProbe` accordingly if required. Note that `resources.limits.cpu` must be an integer.
58 |
59 |
60 |
61 | ## Pre-requisites
62 |
63 | * Kubernetes 1.11.x (tested with v1.11.2 on top of [Vagrant + CoreOS](https://github.com/pires/kubernetes-vagrant-coreos-cluster)).
64 | * `kubectl` configured to access the Kubernetes API.
65 |
66 |
67 |
68 | ## Build images (optional)
69 |
70 | Providing one's own version of [the images automatically built from this repository](https://github.com/pires/docker-elasticsearch-kubernetes) will not be supported. This is an *optional* step. One has been warned.
71 |
72 | ## Test
73 |
74 | ### Deploy
75 |
76 | ```shell
77 | kubectl create -f es-discovery-svc.yaml
78 | kubectl create -f es-svc.yaml
79 | kubectl create -f es-master.yaml
80 | kubectl rollout status -f es-master.yaml
81 |
82 | kubectl create -f es-ingest-svc.yaml
83 | kubectl create -f es-ingest.yaml
84 | kubectl rollout status -f es-ingest.yaml
85 |
86 | kubectl create -f es-data.yaml
87 | kubectl rollout status -f es-data.yaml
88 | ```
89 |
90 | Let's check if everything is working properly:
91 |
92 | ```shell
93 | kubectl get svc,deployment,pods -l component=elasticsearch
94 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
95 | service/elasticsearch ClusterIP 10.100.243.196 9200/TCP 3m
96 | service/elasticsearch-discovery ClusterIP None 9300/TCP 3m
97 | service/elasticsearch-ingest ClusterIP 10.100.76.74 9200/TCP 2m
98 |
99 | NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
100 | deployment.extensions/es-data 2 2 2 2 1m
101 | deployment.extensions/es-ingest 2 2 2 2 2m
102 | deployment.extensions/es-master 3 3 3 3 3m
103 |
104 | NAME READY STATUS RESTARTS AGE
105 | pod/es-data-56f8ff8c97-642bq 1/1 Running 0 1m
106 | pod/es-data-56f8ff8c97-h6hpc 1/1 Running 0 1m
107 | pod/es-ingest-6ddd5fc689-b4s94 1/1 Running 0 2m
108 | pod/es-ingest-6ddd5fc689-d8rtj 1/1 Running 0 2m
109 | pod/es-master-68bf8f86c4-bsfrx 1/1 Running 0 3m
110 | pod/es-master-68bf8f86c4-g8nph 1/1 Running 0 3m
111 | pod/es-master-68bf8f86c4-q5khn 1/1 Running 0 3m
112 | ```
113 |
114 | As we can assert, the cluster seems to be up and running. Easy, wasn't it?
115 |
116 | ### Access the service
117 |
118 | *Don't forget* that services in Kubernetes are only acessible from containers in the cluster. For different behavior one should [configure the creation of an external load-balancer](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer). While it's supported within this example service descriptor, its usage is out of scope of this document, for now.
119 |
120 | *Note:* if you are using one of the cloud providers which support external load balancers, setting the type field to "LoadBalancer" will provision a load balancer for your Service. You can uncomment the field in [es-svc.yaml](https://github.com/pires/kubernetes-elasticsearch-cluster/blob/master/es-svc.yaml).
121 |
122 | ```shell
123 | kubectl get svc elasticsearch
124 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
125 | elasticsearch ClusterIP 10.100.243.196 9200/TCP 3m
126 | ```
127 |
128 | From any host on the Kubernetes cluster (that's running `kube-proxy` or similar), run:
129 |
130 | ```shell
131 | curl http://10.100.243.196:9200
132 | ```
133 |
134 | One should see something similar to the following:
135 |
136 | ```json
137 | {
138 | "name" : "es-data-56f8ff8c97-642bq",
139 | "cluster_name" : "myesdb",
140 | "cluster_uuid" : "RkRkTl26TDOE7o0FhCcW_g",
141 | "version" : {
142 | "number" : "6.3.2",
143 | "build_flavor" : "default",
144 | "build_type" : "tar",
145 | "build_hash" : "053779d",
146 | "build_date" : "2018-07-20T05:20:23.451332Z",
147 | "build_snapshot" : false,
148 | "lucene_version" : "7.3.1",
149 | "minimum_wire_compatibility_version" : "5.6.0",
150 | "minimum_index_compatibility_version" : "5.0.0"
151 | },
152 | "tagline" : "You Know, for Search"
153 | }
154 | ```
155 |
156 | Or if one wants to see cluster information:
157 |
158 | ```shell
159 | curl http://10.100.243.196:9200/_cluster/health?pretty
160 | ```
161 |
162 | One should see something similar to the following:
163 |
164 | ```json
165 | {
166 | "cluster_name" : "myesdb",
167 | "status" : "green",
168 | "timed_out" : false,
169 | "number_of_nodes" : 7,
170 | "number_of_data_nodes" : 2,
171 | "active_primary_shards" : 0,
172 | "active_shards" : 0,
173 | "relocating_shards" : 0,
174 | "initializing_shards" : 0,
175 | "unassigned_shards" : 0,
176 | "delayed_unassigned_shards" : 0,
177 | "number_of_pending_tasks" : 0,
178 | "number_of_in_flight_fetch" : 0,
179 | "task_max_waiting_in_queue_millis" : 0,
180 | "active_shards_percent_as_number" : 100.0
181 | }
182 | ```
183 |
184 |
185 |
186 | ## Pod anti-affinity
187 |
188 | One of the main advantages of running Elasticsearch on top of Kubernetes is how resilient the cluster becomes, particularly during
189 | node restarts. However if all data pods are scheduled onto the same node(s), this advantage decreases significantly and may even
190 | result in no data pods being available.
191 |
192 | It is then **highly recommended**, in the context of the solution described in this repository, that one adopts [pod anti-affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature)
193 | in order to guarantee that two data pods will never run on the same node.
194 |
195 | Here's an example:
196 |
197 | ```yaml
198 | spec:
199 | affinity:
200 | podAntiAffinity:
201 | preferredDuringSchedulingIgnoredDuringExecution:
202 | - weight: 100
203 | podAffinityTerm:
204 | labelSelector:
205 | matchExpressions:
206 | - key: component
207 | operator: In
208 | values:
209 | - elasticsearch
210 | - key: role
211 | operator: In
212 | values:
213 | - data
214 | topologyKey: kubernetes.io/hostname
215 | containers:
216 | - (...)
217 | ```
218 |
219 |
220 |
221 | ## Availability
222 |
223 | If one wants to ensure that no more than `n` Elasticsearch nodes will be unavailable at a time, one can optionally (change and) apply the following manifests:
224 |
225 | ```shell
226 | kubectl create -f es-master-pdb.yaml
227 | kubectl create -f es-data-pdb.yaml
228 | ```
229 |
230 | **Note:** This is an advanced subject and one should only put it in practice if one understands clearly what it means both in the Kubernetes and Elasticsearch contexts. For more information, please consult [Pod Disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions).
231 |
232 |
233 |
234 | ## Deploy with Helm
235 |
236 | **WARNING:** The Helm chart is maintained by someone else in the community and may not up-to-date with this repo.
237 |
238 | [Helm](https://github.com/kubernetes/helm) charts for a basic (non-stateful) ElasticSearch deployment are maintained at https://github.com/clockworksoul/helm-elasticsearch. With Helm properly installed and configured, standing up a complete cluster is almost trivial:
239 |
240 | ```shell
241 | git clone https://github.com/clockworksoul/helm-elasticsearch.git
242 | helm install helm-elasticsearch
243 | ```
244 |
245 | Various parameters of the cluster, including replica count and memory allocations, can be adjusted by editing the `helm-elasticsearch/values.yaml` file. For information about Helm, please consult the [complete Helm documentation](https://github.com/kubernetes/helm/blob/master/docs/index.md).
246 |
247 |
248 |
249 | ## Install plug-ins
250 |
251 | The image used in this repo is very minimalist. However, one can install additional plug-ins at will by simply specifying the `ES_PLUGINS_INSTALL` environment variable in the desired pod descriptors. For instance, to install [Google Cloud Storage](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-gcs.html) and [S3](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3.html) plug-ins it would be like follows:
252 |
253 | ```yaml
254 | - name: "ES_PLUGINS_INSTALL"
255 | value: "repository-gcs,repository-s3"
256 | ```
257 |
258 | **Note:** The X-Pack plugin does not currently work with the `quay.io/pires/docker-elasticsearch-kubernetes` image. See Issue #102
259 |
260 |
261 |
262 | ## Clean-up with Curator
263 |
264 | Additionally, one can run a [CronJob](http://kubernetes.io/docs/user-guide/cron-jobs/) that will periodically run [Curator](https://github.com/elastic/curator) to clean up indices (or do other actions on the Elasticsearch cluster).
265 |
266 | ```shell
267 | kubectl create -f es-curator-config.yaml
268 | kubectl create -f es-curator.yaml
269 | ```
270 |
271 | Please, confirm the job has been created.
272 |
273 | ```shell
274 | kubectl get cronjobs
275 | NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
276 | curator 1 0 * * * False 0
277 | ```
278 |
279 | The job is configured to run once a day at _1 minute past midnight and delete indices that are older than 3 days_.
280 |
281 | **Notes**
282 |
283 | * One can change the schedule by editing the cron notation in `es-curator.yaml`.
284 | * One can change the action (e.g. delete older than 3 days) by editing the `es-curator-config.yaml`.
285 | * The definition of the `action_file.yaml` is quite self-explaining for simple set-ups. For more advanced configuration options, please consult the [Curator Documentation](https://www.elastic.co/guide/en/elasticsearch/client/curator/current/index.html).
286 |
287 | If one wants to remove the curator job, just run:
288 |
289 | ```shell
290 | kubectl delete cronjob curator
291 | kubectl delete configmap curator-config
292 | ```
293 |
294 |
295 |
296 | ## Kibana
297 |
298 | **WARNING:** The Kibana section is maintained by someone else in the community and may not up-to-date with this repo.
299 |
300 | ### Deploy
301 |
302 | If Kibana defaults are not enough, one may want to customize `kibana.yaml` through a `ConfigMap`.
303 | Please refer to [Configuring Kibana](https://www.elastic.co/guide/en/kibana/current/settings.html) for all available attributes.
304 |
305 | ```shell
306 | kubectl create -f kibana-cm.yaml
307 | kubectl create -f kibana-svc.yaml
308 | kubectl create -f kibana.yaml
309 | ```
310 |
311 | Kibana will become available through service `kibana`, and one will be able to access it from within the cluster, or proxy it through the Kubernetes API as follows:
312 |
313 | ```shell
314 | curl https:///api/v1/namespaces/default/services/kibana:http/proxy
315 | ```
316 |
317 | One can also create an Ingress to expose the service publicly or simply use the service nodeport.
318 | In the case one proceeds to do so, one must change the environment variable `SERVER_BASEPATH` to the match their environment.
319 |
320 | ## FAQ
321 |
322 | ### Why does `NUMBER_OF_MASTERS` differ from number of master-replicas?
323 |
324 | The default value for this environment variable is 2, meaning a cluster will need a minimum of 2 master nodes to operate. If a cluster has 3 masters and one dies, the cluster still works. Minimum master nodes are usually `n/2 + 1`, where `n` is the number of master nodes in a cluster. If a cluster has 5 master nodes, one should have a minimum of 3, less than that and the cluster _stops_. If one scales the number of masters, make sure to update the minimum number of master nodes through the Elasticsearch API as setting environment variable will only work on cluster setup. More info: https://www.elastic.co/guide/en/elasticsearch/guide/1.x/_important_configuration_changes.html#_minimum_master_nodes
325 |
326 |
327 | ### How can I customize `elasticsearch.yaml`?
328 |
329 | Read a different config file by settings env var `ES_PATH_CONF=/path/to/my/config/` [(see the Elasticsearch docs for more)](https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html#config-files-location). Another option would be to build one's own image from [this repository](https://github.com/pires/docker-elasticsearch-kubernetes)
330 |
331 | ## Troubleshooting
332 |
333 | ### No up-and-running site-local
334 |
335 | One of the errors one may come across when running the setup is the following error:
336 |
337 | ```
338 | [2016-11-29T01:28:36,515][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
339 | org.elasticsearch.bootstrap.StartupException: java.lang.IllegalArgumentException: No up-and-running site-local (private) addresses found, got [name:lo (lo), name:eth0 (eth0)]
340 | at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:116) ~[elasticsearch-5.0.1.jar:5.0.1]
341 | at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:103) ~[elasticsearch-5.0.1.jar:5.0.1]
342 | at org.elasticsearch.cli.SettingCommand.execute(SettingCommand.java:54) ~[elasticsearch-5.0.1.jar:5.0.1]
343 | at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:96) ~[elasticsearch-5.0.1.jar:5.0.1]
344 | at org.elasticsearch.cli.Command.main(Command.java:62) ~[elasticsearch-5.0.1.jar:5.0.1]
345 | at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:80) ~[elasticsearch-5.0.1.jar:5.0.1]
346 | at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:73) ~[elasticsearch-5.0.1.jar:5.0.1]
347 | Caused by: java.lang.IllegalArgumentException: No up-and-running site-local (private) addresses found, got [name:lo (lo), name:eth0 (eth0)]
348 | at org.elasticsearch.common.network.NetworkUtils.getSiteLocalAddresses(NetworkUtils.java:187) ~[elasticsearch-5.0.1.jar:5.0.1]
349 | at org.elasticsearch.common.network.NetworkService.resolveInternal(NetworkService.java:246) ~[elasticsearch-5.0.1.jar:5.0.1]
350 | at org.elasticsearch.common.network.NetworkService.resolveInetAddresses(NetworkService.java:220) ~[elasticsearch-5.0.1.jar:5.0.1]
351 | at org.elasticsearch.common.network.NetworkService.resolveBindHostAddresses(NetworkService.java:130) ~[elasticsearch-5.0.1.jar:5.0.1]
352 | at org.elasticsearch.transport.TcpTransport.bindServer(TcpTransport.java:575) ~[elasticsearch-5.0.1.jar:5.0.1]
353 | at org.elasticsearch.transport.netty4.Netty4Transport.doStart(Netty4Transport.java:182) ~[?:?]
354 | at org.elasticsearch.common.component.AbstractLifecycleComponent.start(AbstractLifecycleComponent.java:68) ~[elasticsearch-5.0.1.jar:5.0.1]
355 | at org.elasticsearch.transport.TransportService.doStart(TransportService.java:182) ~[elasticsearch-5.0.1.jar:5.0.1]
356 | at org.elasticsearch.common.component.AbstractLifecycleComponent.start(AbstractLifecycleComponent.java:68) ~[elasticsearch-5.0.1.jar:5.0.1]
357 | at org.elasticsearch.node.Node.start(Node.java:525) ~[elasticsearch-5.0.1.jar:5.0.1]
358 | at org.elasticsearch.bootstrap.Bootstrap.start(Bootstrap.java:211) ~[elasticsearch-5.0.1.jar:5.0.1]
359 | at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:288) ~[elasticsearch-5.0.1.jar:5.0.1]
360 | at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:112) ~[elasticsearch-5.0.1.jar:5.0.1]
361 | ... 6 more
362 | [2016-11-29T01:28:37,448][INFO ][o.e.n.Node ] [kIEYQSE] stopping ...
363 | [2016-11-29T01:28:37,451][INFO ][o.e.n.Node ] [kIEYQSE] stopped
364 | [2016-11-29T01:28:37,452][INFO ][o.e.n.Node ] [kIEYQSE] closing ...
365 | [2016-11-29T01:28:37,464][INFO ][o.e.n.Node ] [kIEYQSE] closed
366 | ```
367 |
368 | This is related to how the container binds to network ports (defaults to ``_local_``). It will need to match the actual node network interface name, which depends on what OS and infrastructure provider one uses. For instance, if the primary interface on the node is `p1p1` then that is the value that needs to be set for the `NETWORK_HOST` environment variable.
369 | Please see [the documentation](https://github.com/pires/docker-elasticsearch#environment-variables) for reference of options.
370 |
371 | In order to workaround this, set `NETWORK_HOST` environment variable in the pod descriptors as follows:
372 |
373 | ```yaml
374 | - name: "NETWORK_HOST"
375 | value: "_eth0_" #_p1p1_ if interface name is p1p1, _ens4_ if interface name is ens4, and so on.
376 | ```
377 |
378 | ### (IPv6) org.elasticsearch.bootstrap.StartupException: BindTransportException
379 |
380 | Intermittent failures occur when the local network interface has both IPv4 and IPv6 addresses, and Elasticsearch tries to bind to the IPv6 address first.
381 | If the IPv4 address is chosen first, Elasticsearch starts correctly.
382 |
383 | In order to workaround this, set `NETWORK_HOST` environment variable in the pod descriptors as follows:
384 |
385 | ```yaml
386 | - name: "NETWORK_HOST"
387 | value: "_eth0:ipv4_" #_p1p1:ipv4_ if interface name is p1p1, _ens4:ipv4_ if interface name is ens4, and so on.
388 | ```
389 |
--------------------------------------------------------------------------------
/es-curator-config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: curator-config
5 | data:
6 | action_file.yml: |-
7 | ---
8 | # Remember, leave a key empty if there is no value. None will be a string,
9 | # not a Python "NoneType"
10 | #
11 | # Also remember that all examples have 'disable_action' set to True. If you
12 | # want to use this action as a template, be sure to set this to False after
13 | # copying it.
14 | actions:
15 | 1:
16 | action: delete_indices
17 | description: "Clean up ES by deleting old indices"
18 | options:
19 | timeout_override:
20 | continue_if_exception: False
21 | disable_action: False
22 | ignore_empty_list: True
23 | filters:
24 | - filtertype: age
25 | source: name
26 | direction: older
27 | timestring: '%Y.%m.%d'
28 | unit: days
29 | unit_count: 3
30 | field:
31 | stats_result:
32 | epoch:
33 | exclude: False
34 | config.yml: |-
35 | ---
36 | # Remember, leave a key empty if there is no value. None will be a string,
37 | # not a Python "NoneType"
38 | client:
39 | hosts:
40 | - elasticsearch
41 | port: 9200
42 | url_prefix:
43 | use_ssl: False
44 | certificate:
45 | client_cert:
46 | client_key:
47 | ssl_no_validate: False
48 | http_auth:
49 | timeout: 30
50 | master_only: False
51 |
52 | logging:
53 | loglevel: INFO
54 | logfile:
55 | logformat: default
56 | blacklist: ['elasticsearch', 'urllib3']
57 |
--------------------------------------------------------------------------------
/es-curator.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1beta1
2 | kind: CronJob
3 | metadata:
4 | name: curator
5 | spec:
6 | schedule: 1 0 * * *
7 | jobTemplate:
8 | spec:
9 | template:
10 | spec:
11 | containers:
12 | - name: curator
13 | image: quay.io/pires/docker-elasticsearch-curator:5.5.1
14 | args:
15 | - --config
16 | - /etc/config/config.yml
17 | - /etc/config/action_file.yml
18 | volumeMounts:
19 | - name: config-volume
20 | mountPath: /etc/config
21 | volumes:
22 | - name: config-volume
23 | configMap:
24 | name: curator-config
25 | restartPolicy: OnFailure
26 |
--------------------------------------------------------------------------------
/es-data-pdb.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: policy/v1beta1
2 | kind: PodDisruptionBudget
3 | metadata:
4 | name: elasticsearch-data
5 | spec:
6 | maxUnavailable: 1
7 | selector:
8 | matchLabels:
9 | component: elasticsearch
10 | role: data
11 |
--------------------------------------------------------------------------------
/es-data.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: es-data
5 | labels:
6 | component: elasticsearch
7 | role: data
8 | spec:
9 | replicas: 2
10 | template:
11 | metadata:
12 | labels:
13 | component: elasticsearch
14 | role: data
15 | spec:
16 | initContainers:
17 | - name: init-sysctl
18 | image: busybox:1.27.2
19 | command:
20 | - sysctl
21 | - -w
22 | - vm.max_map_count=262144
23 | securityContext:
24 | privileged: true
25 | containers:
26 | - name: es-data
27 | image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.2
28 | env:
29 | - name: NAMESPACE
30 | valueFrom:
31 | fieldRef:
32 | fieldPath: metadata.namespace
33 | - name: NODE_NAME
34 | valueFrom:
35 | fieldRef:
36 | fieldPath: metadata.name
37 | - name: CLUSTER_NAME
38 | value: myesdb
39 | - name: NODE_MASTER
40 | value: "false"
41 | - name: NODE_INGEST
42 | value: "false"
43 | - name: HTTP_ENABLE
44 | value: "true"
45 | - name: ES_JAVA_OPTS
46 | value: -Xms256m -Xmx256m
47 | - name: PROCESSORS
48 | valueFrom:
49 | resourceFieldRef:
50 | resource: limits.cpu
51 | resources:
52 | requests:
53 | cpu: 0.25
54 | limits:
55 | cpu: 1
56 | ports:
57 | - containerPort: 9200
58 | name: http
59 | - containerPort: 9300
60 | name: transport
61 | livenessProbe:
62 | tcpSocket:
63 | port: transport
64 | initialDelaySeconds: 20
65 | periodSeconds: 10
66 | readinessProbe:
67 | httpGet:
68 | path: /_cluster/health
69 | port: http
70 | initialDelaySeconds: 20
71 | timeoutSeconds: 5
72 | volumeMounts:
73 | - name: storage
74 | mountPath: /data
75 | volumes:
76 | - emptyDir:
77 | medium: ""
78 | name: storage
79 |
--------------------------------------------------------------------------------
/es-discovery-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: elasticsearch-discovery
5 | labels:
6 | component: elasticsearch
7 | role: master
8 | spec:
9 | selector:
10 | component: elasticsearch
11 | role: master
12 | ports:
13 | - name: transport
14 | port: 9300
15 | protocol: TCP
16 | clusterIP: None
17 |
--------------------------------------------------------------------------------
/es-ingest-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: elasticsearch-ingest
5 | labels:
6 | component: elasticsearch
7 | role: ingest
8 | spec:
9 | selector:
10 | component: elasticsearch
11 | role: ingest
12 | ports:
13 | - name: http
14 | port: 9200
15 | #type: LoadBalancer
16 |
--------------------------------------------------------------------------------
/es-ingest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: es-ingest
5 | labels:
6 | component: elasticsearch
7 | role: ingest
8 | spec:
9 | replicas: 2
10 | template:
11 | metadata:
12 | labels:
13 | component: elasticsearch
14 | role: ingest
15 | spec:
16 | initContainers:
17 | - name: init-sysctl
18 | image: busybox:1.27.2
19 | command:
20 | - sysctl
21 | - -w
22 | - vm.max_map_count=262144
23 | securityContext:
24 | privileged: true
25 | containers:
26 | - name: es-ingest
27 | image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.2
28 | env:
29 | - name: NAMESPACE
30 | valueFrom:
31 | fieldRef:
32 | fieldPath: metadata.namespace
33 | - name: NODE_NAME
34 | valueFrom:
35 | fieldRef:
36 | fieldPath: metadata.name
37 | - name: CLUSTER_NAME
38 | value: myesdb
39 | - name: NODE_MASTER
40 | value: "false"
41 | - name: NODE_DATA
42 | value: "false"
43 | - name: HTTP_ENABLE
44 | value: "true"
45 | - name: ES_JAVA_OPTS
46 | value: -Xms256m -Xmx256m
47 | - name: NETWORK_HOST
48 | value: _site_,_lo_
49 | - name: PROCESSORS
50 | valueFrom:
51 | resourceFieldRef:
52 | resource: limits.cpu
53 | resources:
54 | requests:
55 | cpu: 0.25
56 | limits:
57 | cpu: 1
58 | ports:
59 | - containerPort: 9200
60 | name: http
61 | - containerPort: 9300
62 | name: transport
63 | livenessProbe:
64 | tcpSocket:
65 | port: transport
66 | initialDelaySeconds: 20
67 | periodSeconds: 10
68 | readinessProbe:
69 | httpGet:
70 | path: /_cluster/health
71 | port: http
72 | initialDelaySeconds: 20
73 | timeoutSeconds: 5
74 | volumeMounts:
75 | - name: storage
76 | mountPath: /data
77 | volumes:
78 | - emptyDir:
79 | medium: ""
80 | name: storage
81 |
--------------------------------------------------------------------------------
/es-master-pdb.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: policy/v1beta1
2 | kind: PodDisruptionBudget
3 | metadata:
4 | name: elasticsearch-master
5 | spec:
6 | maxUnavailable: 1
7 | selector:
8 | matchLabels:
9 | component: elasticsearch
10 | role: master
11 |
--------------------------------------------------------------------------------
/es-master.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: es-master
5 | labels:
6 | component: elasticsearch
7 | role: master
8 | spec:
9 | replicas: 3
10 | template:
11 | metadata:
12 | labels:
13 | component: elasticsearch
14 | role: master
15 | spec:
16 | initContainers:
17 | - name: init-sysctl
18 | image: busybox:1.27.2
19 | command:
20 | - sysctl
21 | - -w
22 | - vm.max_map_count=262144
23 | securityContext:
24 | privileged: true
25 | containers:
26 | - name: es-master
27 | image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.2
28 | env:
29 | - name: NAMESPACE
30 | valueFrom:
31 | fieldRef:
32 | fieldPath: metadata.namespace
33 | - name: NODE_NAME
34 | valueFrom:
35 | fieldRef:
36 | fieldPath: metadata.name
37 | - name: CLUSTER_NAME
38 | value: myesdb
39 | - name: NUMBER_OF_MASTERS
40 | value: "2"
41 | - name: NODE_MASTER
42 | value: "true"
43 | - name: NODE_INGEST
44 | value: "false"
45 | - name: NODE_DATA
46 | value: "false"
47 | - name: HTTP_ENABLE
48 | value: "false"
49 | - name: ES_JAVA_OPTS
50 | value: -Xms256m -Xmx256m
51 | - name: PROCESSORS
52 | valueFrom:
53 | resourceFieldRef:
54 | resource: limits.cpu
55 | resources:
56 | requests:
57 | cpu: 0.25
58 | limits:
59 | cpu: 1
60 | ports:
61 | - containerPort: 9300
62 | name: transport
63 | livenessProbe:
64 | tcpSocket:
65 | port: transport
66 | initialDelaySeconds: 20
67 | periodSeconds: 10
68 | volumeMounts:
69 | - name: storage
70 | mountPath: /data
71 | volumes:
72 | - emptyDir:
73 | medium: ""
74 | name: "storage"
75 |
--------------------------------------------------------------------------------
/es-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: elasticsearch
5 | labels:
6 | component: elasticsearch
7 | role: data
8 | spec:
9 | selector:
10 | component: elasticsearch
11 | role: data
12 | ports:
13 | - name: http
14 | port: 9200
15 | #type: LoadBalancer
16 |
--------------------------------------------------------------------------------
/kibana-cm.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: kibana-config
5 | data:
6 | kibana.yml: |
7 | ---
8 | server.name: kibana
9 | server.host: "0"
10 | elasticsearch.url: http://elasticsearch:9200
11 |
--------------------------------------------------------------------------------
/kibana-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: kibana
5 | labels:
6 | component: kibana
7 | spec:
8 | selector:
9 | component: kibana
10 | ports:
11 | - name: http
12 | port: 80
13 | targetPort: http
14 |
--------------------------------------------------------------------------------
/kibana.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: kibana
5 | labels:
6 | component: kibana
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | component: kibana
12 | template:
13 | metadata:
14 | labels:
15 | component: kibana
16 | spec:
17 | containers:
18 | - name: kibana
19 | image: docker.elastic.co/kibana/kibana-oss:6.3.2
20 | env:
21 | - name: CLUSTER_NAME
22 | value: myesdb
23 | - name: SERVER_BASEPATH
24 | value: /api/v1/namespaces/default/services/kibana:http/proxy
25 | resources:
26 | limits:
27 | cpu: 1000m
28 | requests:
29 | cpu: 100m
30 | ports:
31 | - containerPort: 5601
32 | name: http
33 | readinessProbe:
34 | httpGet:
35 | path: /api/status
36 | port: http
37 | initialDelaySeconds: 20
38 | timeoutSeconds: 5
39 | volumeMounts:
40 | - name: config
41 | mountPath: /usr/share/kibana/config
42 | readOnly: true
43 | volumes:
44 | - name: config
45 | configMap:
46 | name: kibana-config
47 |
--------------------------------------------------------------------------------
/stateful/README.md:
--------------------------------------------------------------------------------
1 | # Elasticsearch StatefulSet Data Pod
2 |
3 | This directory contains Kubernetes configurations which run elasticsearch data and master pods as a [`StatefulSet`](https://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/), using storage provisioned using a [`StorageClass`](http://blog.kubernetes.io/2016/10/dynamic-provisioning-and-storage-in-kubernetes.html). Be sure to read and understand the documentation in the root directory, which deploys the data pods as a `Deployment` using an `emptyDir` for storage.
4 |
5 | ## Storage
6 |
7 | The [`es-data-stateful.yaml`](es-data-stateful.yaml) and [`es-master-stateful.yaml`](es-master-stateful.yaml) files contain `volumeClaimTemplates` sections which request 2GB volume for each master node, and 12GB volume for each data node. This is plenty of space for a demonstration cluster, but will fill up quickly under moderate to heavy load. Consider modifying the disk size to your needs.
8 |
9 | ## Deploy
10 | The root directory contains instructions for deploying elasticsearch using a `Deployment` with transient storage for data pods. These brief instructions show a deployment using the `StatefulSet` and `StorageClass`.
11 |
12 | ```
13 | kubectl create -f ../es-discovery-svc.yaml
14 | kubectl create -f ../es-svc.yaml
15 |
16 | kubectl create -f es-master-svc.yaml
17 | kubectl create -f es-master-stateful.yaml
18 | kubectl rollout status -f es-master-stateful.yaml
19 |
20 | kubectl create -f ../es-ingest-svc.yaml
21 | kubectl create -f ../es-ingest.yaml
22 | kubectl rollout status -f ../es-ingest.yaml
23 |
24 | kubectl create -f es-data-svc.yaml
25 | kubectl create -f es-data-stateful.yaml
26 | kubectl rollout status -f es-data-stateful.yaml
27 | ```
28 |
29 | Kubernetes creates the pods for a `StatefulSet` one at a time, waiting for each to come up before starting the next, so it may take a few minutes for all pods to be provisioned. Refer back to the documentation in the root directory for details on testing the cluster, and configuring a curator job to clean up.
30 |
--------------------------------------------------------------------------------
/stateful/es-data-stateful.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: StatefulSet
3 | metadata:
4 | name: es-data
5 | labels:
6 | component: elasticsearch
7 | role: data
8 | spec:
9 | selector:
10 | matchLabels:
11 | component: elasticsearch
12 | role: data
13 | serviceName: elasticsearch-data
14 | replicas: 3
15 | template:
16 | metadata:
17 | labels:
18 | component: elasticsearch
19 | role: data
20 | spec:
21 | initContainers:
22 | - name: init-sysctl
23 | image: busybox:1.27.2
24 | command:
25 | - sysctl
26 | - -w
27 | - vm.max_map_count=262144
28 | securityContext:
29 | privileged: true
30 | containers:
31 | - name: es-data
32 | image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.2
33 | env:
34 | - name: NAMESPACE
35 | valueFrom:
36 | fieldRef:
37 | fieldPath: metadata.namespace
38 | - name: NODE_NAME
39 | valueFrom:
40 | fieldRef:
41 | fieldPath: metadata.name
42 | - name: CLUSTER_NAME
43 | value: myesdb
44 | - name: NODE_MASTER
45 | value: "false"
46 | - name: NODE_INGEST
47 | value: "false"
48 | - name: HTTP_ENABLE
49 | value: "true"
50 | - name: ES_JAVA_OPTS
51 | value: -Xms256m -Xmx256m
52 | - name: PROCESSORS
53 | valueFrom:
54 | resourceFieldRef:
55 | resource: limits.cpu
56 | resources:
57 | requests:
58 | cpu: 0.25
59 | limits:
60 | cpu: 1
61 | ports:
62 | - containerPort: 9200
63 | name: http
64 | - containerPort: 9300
65 | name: transport
66 | livenessProbe:
67 | tcpSocket:
68 | port: transport
69 | initialDelaySeconds: 20
70 | periodSeconds: 10
71 | readinessProbe:
72 | httpGet:
73 | path: /_cluster/health
74 | port: http
75 | initialDelaySeconds: 20
76 | timeoutSeconds: 5
77 | volumeMounts:
78 | - name: storage
79 | mountPath: /data
80 | volumeClaimTemplates:
81 | - metadata:
82 | name: storage
83 | spec:
84 | storageClassName: standard
85 | accessModes: [ ReadWriteOnce ]
86 | resources:
87 | requests:
88 | storage: 12Gi
89 |
--------------------------------------------------------------------------------
/stateful/es-data-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: elasticsearch-data
5 | labels:
6 | component: elasticsearch
7 | role: data
8 | spec:
9 | ports:
10 | - port: 9300
11 | name: transport
12 | clusterIP: None
13 | selector:
14 | component: elasticsearch
15 | role: data
16 |
--------------------------------------------------------------------------------
/stateful/es-master-stateful.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: StatefulSet
3 | metadata:
4 | name: es-master
5 | labels:
6 | component: elasticsearch
7 | role: master
8 | spec:
9 | selector:
10 | matchLabels:
11 | component: elasticsearch
12 | role: master
13 | serviceName: elasticsearch-master
14 | replicas: 3
15 | template:
16 | metadata:
17 | labels:
18 | component: elasticsearch
19 | role: master
20 | spec:
21 | initContainers:
22 | - name: init-sysctl
23 | image: busybox:1.27.2
24 | command:
25 | - sysctl
26 | - -w
27 | - vm.max_map_count=262144
28 | securityContext:
29 | privileged: true
30 | containers:
31 | - name: es-master
32 | image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.0
33 | env:
34 | - name: NAMESPACE
35 | valueFrom:
36 | fieldRef:
37 | fieldPath: metadata.namespace
38 | - name: NODE_NAME
39 | valueFrom:
40 | fieldRef:
41 | fieldPath: metadata.name
42 | - name: CLUSTER_NAME
43 | value: myesdb
44 | - name: NUMBER_OF_MASTERS
45 | value: "2"
46 | - name: NODE_MASTER
47 | value: "true"
48 | - name: NODE_INGEST
49 | value: "false"
50 | - name: NODE_DATA
51 | value: "false"
52 | - name: HTTP_ENABLE
53 | value: "false"
54 | - name: ES_JAVA_OPTS
55 | value: -Xms256m -Xmx256m
56 | - name: PROCESSORS
57 | valueFrom:
58 | resourceFieldRef:
59 | resource: limits.cpu
60 | resources:
61 | requests:
62 | cpu: 0.25
63 | limits:
64 | cpu: 1
65 | ports:
66 | - containerPort: 9300
67 | name: transport
68 | livenessProbe:
69 | tcpSocket:
70 | port: transport
71 | initialDelaySeconds: 20
72 | periodSeconds: 10
73 | volumeMounts:
74 | - name: storage
75 | mountPath: /data
76 | volumeClaimTemplates:
77 | - metadata:
78 | name: storage
79 | spec:
80 | storageClassName: standard
81 | accessModes: [ ReadWriteOnce ]
82 | resources:
83 | requests:
84 | storage: 2Gi
85 |
--------------------------------------------------------------------------------
/stateful/es-master-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: elasticsearch-master
5 | labels:
6 | component: elasticsearch
7 | role: master
8 | spec:
9 | ports:
10 | - port: 9300
11 | name: transport
12 | clusterIP: None
13 | selector:
14 | component: elasticsearch
15 | role: master
16 |
--------------------------------------------------------------------------------