├── .gitignore ├── .helmignore ├── Chart.yaml ├── LICENSE ├── README.md ├── templates ├── NOTES.txt ├── _helpers.tpl ├── client-deployment.yaml ├── client-poddisruptionbudget.yaml ├── client-service-external.yaml ├── client-service.yaml ├── clusterrole.yaml ├── clusterrolebinding.yaml ├── configmap.yaml ├── curator-clusterrole.yaml ├── curator-clusterrolebinding.yaml ├── curator-configmap.yaml ├── curator-cronjob.yaml ├── curator-role.yaml ├── curator-rolebinding.yaml ├── curator-secret.yaml ├── curator-serviceaccount.yaml ├── data-poddisruptionbudget.yaml ├── data-statefulset.yaml ├── master-poddisruptionbudget.yaml ├── master-service.yaml ├── master-statefulset.yaml ├── security-configmap.yaml ├── securityinit-clusterrole.yaml ├── securityinit-clusterrolebinding.yaml ├── securityinit-job.yaml ├── securityinit-role.yaml ├── securityinit-rolebinding.yaml ├── securityinit-secret.yaml ├── securityinit-serviceaccount.yaml └── serviceaccount.yaml └── values.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # for osx 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). 4 | # Only one pattern per line. 5 | .DS_Store 6 | # Common VCS dirs 7 | .git/ 8 | .gitignore 9 | .bzr/ 10 | .bzrignore 11 | .hg/ 12 | .hgignore 13 | .svn/ 14 | # Common backup files 15 | *.swp 16 | *.bak 17 | *.tmp 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | -------------------------------------------------------------------------------- /Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: elasticsearch 3 | home: https://www.elastic.co/products/elasticsearch 4 | version: 3.0.0 5 | description: Elasticsearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases. 6 | icon: https://static-www.elastic.co/assets/blteb1c97719574938d/logo-elastic-elasticsearch-lt.svg 7 | sources: 8 | - https://www.elastic.co/products/elasticsearch 9 | - https://github.com/pires/kubernetes-elasticsearch-cluster 10 | - https://github.com/kubernetes/charts/tree/master/incubator/elasticsearch 11 | - https://github.com/clockworksoul/helm-elasticsearch 12 | maintainers: 13 | - name: Mikael Knutsson 14 | email: mikael.knutsson@lalamove.com 15 | - name: Matt Titmus 16 | email: matthew.titmus@gmail.com 17 | engine: gotpl 18 | -------------------------------------------------------------------------------- /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 | # helm-elasticsearch 2 | This is a fork by @lalamove merging the incubator elasticsearch chart found here: https://github.com/kubernetes/charts/tree/master/incubator/elasticsearch 3 | together with some open pull requests on https://github.com/clockworksoul/helm-elasticsearch 4 | 5 | ## Features 6 | - RBAC support 7 | - TLS support using Kubernetes certificate API 8 | - Elasticsearch Curator (to prune old indicies) 9 | - Install Elasticsearch Addons through init container 10 | - Compatible with any vanilla elasticsearch install 11 | - Latest version of Elasticsearch in an Alpine image (blacktop/elasticsearch) 12 | 13 | ## Deploying with Helm 14 | 15 | Read the comments in values.yaml and customise them to suit your needs. The sizes and resource limits are suitable for a minikube deploy. Production deploys will require significantly more resources. 16 | With Helm properly installed and configured, standing up a complete cluster is almost trivial: 17 | 18 | ``` 19 | $ git clone https://github.com/lalamove/helm-elasticsearch.git elasticsearch 20 | $ helm install elasticsearch 21 | ``` 22 | 23 | ## Enabling TLS 24 | If you enable TLS you need to keep two things in mind. First, make sure the `clusterDomain` is correct. And second, make sure you approve the certificate requests by using `kubectl certificate approve ...` 25 | 26 | ## Contributing 27 | 28 | Please do! Taking pull requests. 29 | -------------------------------------------------------------------------------- /templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The elasticsearch cluster has been installed. 2 | {{- if .Values.tls.enable }} 3 | 4 | BEFORE ELASTICSEARCH CAN START, YOU NEED TO APPROVE THE CERTIFICATE REQUESTS 5 | Please run: 6 | kubectl certificate approve $(kubectl get csr -n {{ .Release.Namespace }} -l "component={{ template "fullname" . }}" | awk '{print $1}') 7 | Once you have verified that all nodes have requested a certificate by running: 8 | kubectl get certificatesigningrequests --namespace {{ .Release.Namespace }} -l "component={{ template "fullname" . }}" 9 | {{- end }} 10 | 11 | Elasticsearch can be accessed: 12 | 13 | * Within your cluster, at the following DNS name at port 9200: 14 | 15 | {{ template "fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 16 | 17 | * From outside the cluster, run these commands in the same shell: 18 | {{- if contains "NodePort" .Values.common.serviceType }} 19 | 20 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) 21 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 22 | echo http://$NODE_IP:$NODE_PORT 23 | {{- else if contains "LoadBalancer" .Values.common.serviceType }} 24 | 25 | WARNING: You have likely exposed your Elasticsearch cluster direct to the internet. 26 | Elasticsearch does not implement any security for public facing clusters by default. 27 | As a minimum level of security; switch to ClusterIP/NodePort and place an Nginx gateway infront of the cluster in order to lock down access to dangerous HTTP endpoints and verbs. 28 | 29 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 30 | You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' 31 | 32 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 33 | echo http://$SERVICE_IP:9200 34 | {{- else if contains "ClusterIP" .Values.common.serviceType }} 35 | 36 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "component={{ template "fullname" . }},role=client" -o jsonpath="{.items[0].metadata.name}") 37 | echo "Visit http://127.0.0.1:9200 to use Elasticsearch" 38 | kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 9200:9200 39 | {{- end }} 40 | -------------------------------------------------------------------------------- /templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name }} 16 | {{- end -}} 17 | 18 | {{/* 19 | Return the appropriate apiVersion for the Curator cron job. 20 | */}} 21 | {{- define "curator.cronJob.apiVersion" -}} 22 | {{- if ge .Capabilities.KubeVersion.Minor "10" -}} 23 | "batch/v1beta1" 24 | {{- else -}} 25 | "batch/v2alpha1" 26 | {{- end -}} 27 | {{- end -}} 28 | {{/* 29 | init container template 30 | */}} 31 | {{- define "init-containers" -}} 32 | {{- if not $.Values.microk8s }} 33 | - name: init-sysctl 34 | image: busybox 35 | imagePullPolicy: IfNotPresent 36 | command: ["sysctl", "-w", "vm.max_map_count=262144"] 37 | resources: 38 | limits: 39 | cpu: "500m" 40 | memory: 256Mi 41 | requests: 42 | cpu: 100m 43 | memory: 256Mi 44 | securityContext: 45 | privileged: true 46 | {{- end }} 47 | {{- if $.Values.tls.enable }} 48 | - name: generate-tls-pair 49 | image: "{{ .Values.tls.image }}:{{ .Values.tls.imageTag }}" 50 | imagePullPolicy: {{ .Values.tls.imagePullPolicy }} 51 | env: 52 | - name: NAMESPACE 53 | valueFrom: 54 | fieldRef: 55 | fieldPath: metadata.namespace 56 | - name: POD_NAME 57 | valueFrom: 58 | fieldRef: 59 | fieldPath: metadata.name 60 | - name: SUBDOMAIN 61 | value: {{ template "fullname" . }} 62 | - name: POD_IP 63 | valueFrom: 64 | fieldRef: 65 | fieldPath: status.podIP 66 | args: 67 | - "-namespace=$(NAMESPACE)" 68 | - "-pod-ip=$(POD_IP)" 69 | - "-pod-name=$(POD_NAME)" 70 | - "-hostname=$(POD_NAME)" 71 | - "-subdomain=$(SUBDOMAIN)" 72 | - "-headless-name-as-cn" 73 | - "-service-names={{ template "fullname" . }}-discovery,{{ template "fullname" . }}" 74 | - "-cert-dir=/tls/" 75 | - "-pkcs8" 76 | - "-labels=component={{ template "fullname" . }}" 77 | - "-additional-dnsnames={{ .Values.client.dnsname }}" 78 | volumeMounts: 79 | - name: tls 80 | mountPath: /tls 81 | - name: copy-ca 82 | image: busybox 83 | imagePullPolicy: IfNotPresent 84 | command: ["cp", "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", "/tls/ca.crt"] 85 | resources: 86 | limits: 87 | cpu: "500m" 88 | memory: 256Mi 89 | requests: 90 | cpu: 100m 91 | memory: 256Mi 92 | volumeMounts: 93 | - name: tls 94 | mountPath: /tls 95 | {{- if .Values.client.expose }} 96 | - name: chain-ca 97 | image: busybox 98 | imagePullPolicy: IfNotPresent 99 | command: ["sh", "-c", "cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt /var/mount/prodsa.crt > /tls/ca.crt"] 100 | resources: 101 | limits: 102 | cpu: "500m" 103 | memory: 256Mi 104 | requests: 105 | cpu: 100m 106 | memory: 256Mi 107 | volumeMounts: 108 | - name: prodsaca 109 | mountPath: /var/mount 110 | - name: tls 111 | mountPath: /tls 112 | {{- end }} 113 | {{- end }} 114 | {{- if .Values.common.plugins }} 115 | - name: es-plugin-install 116 | image: "{{ .Values.common.image.repository }}:{{ .Values.common.image.tag }}" 117 | imagePullPolicy: {{ .Values.common.image.pullPolicy }} 118 | securityContext: 119 | capabilities: 120 | add: 121 | - IPC_LOCK 122 | - SYS_RESOURCE 123 | resources: 124 | limits: 125 | cpu: "500m" 126 | memory: 256Mi 127 | requests: 128 | cpu: 100m 129 | memory: 256Mi 130 | command: 131 | - "sh" 132 | - "-c" 133 | - "{{ if .Values.opendistro_security.enable }}elasticsearch-plugin install {{ .Values.opendistro_security.plugin }};{{ end }}{{- range .Values.common.plugins }}elasticsearch-plugin install {{ . }};{{- end }} true" 134 | env: 135 | - name: NODE_NAME 136 | value: es-plugin-install 137 | resources: 138 | limits: 139 | cpu: "500m" 140 | memory: 256Mi 141 | requests: 142 | cpu: 100m 143 | memory: 256Mi 144 | volumeMounts: 145 | - mountPath: /storage/ 146 | name: storage 147 | - mountPath: /usr/share/elasticsearch/config/ 148 | name: configdir 149 | - mountPath: /usr/share/elasticsearch/plugins/ 150 | name: plugindir 151 | - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml 152 | name: config 153 | subPath: elasticsearch.yml 154 | - mountPath: /usr/share/elasticsearch/config/tls/ 155 | name: tls 156 | {{- end }} 157 | - name: permissions 158 | image: busybox 159 | command: ["sh", "-c", "chmod 400 /usr/share/elasticsearch/config/tls/*; chown -R 1000: /usr/share/elasticsearch/ /storage/; true"] 160 | resources: 161 | limits: 162 | cpu: "500m" 163 | memory: 256Mi 164 | requests: 165 | cpu: 100m 166 | memory: 256Mi 167 | volumeMounts: 168 | - mountPath: /storage 169 | name: storage 170 | {{- end -}} 171 | -------------------------------------------------------------------------------- /templates/client-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }}-client 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }}-client 11 | role: client 12 | spec: 13 | replicas: {{ .Values.client.replicas }} 14 | strategy: 15 | type: RollingUpdate 16 | selector: 17 | matchLabels: 18 | component: {{ template "fullname" . }}-client 19 | role: client 20 | template: 21 | metadata: 22 | labels: 23 | release: "{{ .Release.Name }}" 24 | app: {{ template "fullname" . }} 25 | component: {{ template "fullname" . }}-client 26 | role: client 27 | {{- if .Values.client.labels }} 28 | {{ toYaml .Values.client.labels | indent 8 }} 29 | {{- end }} 30 | {{- if .Values.client.annotations }} 31 | annotations: 32 | {{ toYaml .Values.client.annotations | indent 8 }} 33 | {{- end }} 34 | spec: 35 | subdomain: {{ template "fullname" . }} 36 | serviceAccountName: {{ template "fullname" . }} 37 | securityContext: 38 | fsGroup: 1000 39 | {{- if eq .Values.client.antiAffinity "hard" }} 40 | affinity: 41 | podAntiAffinity: 42 | preferredDuringSchedulingIgnoredDuringExecution: 43 | - weight: 1 44 | podAffinityTerm: 45 | topologyKey: "failure-domain.beta.kubernetes.io/zone" 46 | labelSelector: 47 | matchLabels: 48 | component: {{ template "fullname" . }} 49 | role: client 50 | requiredDuringSchedulingIgnoredDuringExecution: 51 | - topologyKey: "kubernetes.io/hostname" 52 | labelSelector: 53 | matchLabels: 54 | component: {{ template "fullname" . }} 55 | role: client 56 | {{- else if eq .Values.client.antiAffinity "soft" }} 57 | affinity: 58 | podAntiAffinity: 59 | preferredDuringSchedulingIgnoredDuringExecution: 60 | - weight: 1 61 | podAffinityTerm: 62 | topologyKey: "failure-domain.beta.kubernetes.io/zone" 63 | labelSelector: 64 | matchLabels: 65 | component: {{ template "fullname" . }} 66 | role: client 67 | - weight: 2 68 | podAffinityTerm: 69 | topologyKey: "kubernetes.io/hostname" 70 | labelSelector: 71 | matchLabels: 72 | component: {{ template "fullname" . }} 73 | role: client 74 | {{- end }} 75 | initContainers: 76 | {{ include "init-containers" . | indent 6 }} 77 | containers: 78 | - name: elasticsearch 79 | securityContext: 80 | capabilities: 81 | add: 82 | - IPC_LOCK 83 | - SYS_RESOURCE 84 | image: "{{ .Values.common.image.repository }}:{{ .Values.common.image.tag }}" 85 | imagePullPolicy: {{ .Values.common.image.pullPolicy }} 86 | env: 87 | - name: NAMESPACE 88 | valueFrom: 89 | fieldRef: 90 | fieldPath: metadata.namespace 91 | - name: NODE_NAME 92 | valueFrom: 93 | fieldRef: 94 | fieldPath: metadata.name 95 | - name: DISCOVERY_SERVICE 96 | value: {{ template "fullname" . }}-discovery.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }} 97 | - name: ES_JAVA_OPTS 98 | value: "-XX:ParallelGCThreads={{ .Values.data.processors | mul 4 }} -Djava.net.preferIPv4Stack=true -Xms{{ .Values.client.heapSize }} -Xmx{{ .Values.client.heapSize }}" 99 | - name: NODE_DATA 100 | value: "false" 101 | - name: NODE_MASTER 102 | value: "false" 103 | - name: NODE_INGEST 104 | value: "true" 105 | - name: HTTP_ENABLE 106 | value: "true" 107 | - name: PROCESSORS 108 | value: "{{ .Values.client.processors }}" 109 | {{- range $key, $value := .Values.common.env }} 110 | - name: {{ $key | upper | replace "-" "_" }} 111 | value: {{ $value | quote }} 112 | {{- end }} 113 | {{- range $key, $value := .Values.client.env }} 114 | - name: {{ $key | upper | replace "-" "_" }} 115 | value: {{ $value | quote }} 116 | {{- end }} 117 | resources: 118 | {{ toYaml .Values.client.resources | indent 10 }} 119 | ports: 120 | - containerPort: 9200 121 | name: http 122 | protocol: TCP 123 | - containerPort: 9300 124 | name: transport 125 | protocol: TCP 126 | livenessProbe: 127 | tcpSocket: 128 | port: transport 129 | initialDelaySeconds: 60 130 | periodSeconds: 10 131 | readinessProbe: 132 | {{- if .Values.opendistro_security.enable }} 133 | tcpSocket: 134 | port: http 135 | {{- else }} 136 | httpGet: 137 | path: /_cluster/health 138 | port: http 139 | {{- if .Values.tls.enable }} 140 | scheme: HTTPS 141 | {{- end }} 142 | {{- end }} 143 | initialDelaySeconds: 20 144 | timeoutSeconds: 10 145 | failureThreshold: 30 146 | resources: 147 | {{ toYaml .Values.client.resources | indent 10 }} 148 | volumeMounts: 149 | {{- if .Values.common.plugins }} 150 | - mountPath: /usr/share/elasticsearch/config/ 151 | name: configdir 152 | - mountPath: /usr/share/elasticsearch/plugins/ 153 | name: plugindir 154 | {{- end }} 155 | {{- if .Values.tls.enable }} 156 | - mountPath: /usr/share/elasticsearch/config/tls/ 157 | name: tls 158 | readOnly: true 159 | {{- end }} 160 | - mountPath: /storage/ 161 | name: storage 162 | - mountPath: /usr/share/elasticsearch/config/jvm.options 163 | name: config 164 | subPath: jvm.options 165 | - mountPath: /usr/share/elasticsearch/config/log4j2.properties 166 | name: config 167 | subPath: log4j2.properties 168 | - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml 169 | name: config 170 | subPath: elasticsearch.yml 171 | {{- if .Values.opendistro_security.enable }} 172 | - mountPath: /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/ 173 | name: security-config 174 | {{- end }} 175 | volumes: 176 | {{- if .Values.client.expose }} 177 | - name: prodsaca 178 | secret: 179 | secretName: prod-sa-ca 180 | {{- end }} 181 | {{- if .Values.common.plugins }} 182 | - name: configdir 183 | emptyDir: {} 184 | - name: plugindir 185 | emptyDir: {} 186 | {{- end }} 187 | {{- if .Values.tls.enable }} 188 | - name: tls 189 | emptyDir: {} 190 | {{- end }} 191 | - configMap: 192 | name: {{ template "fullname" . }}-config 193 | name: config 194 | - emptyDir: 195 | medium: "" 196 | name: storage 197 | {{- if .Values.opendistro_security.enable }} 198 | - configMap: 199 | name: {{ template "fullname" . }}-security-config 200 | name: security-config 201 | {{- end }} 202 | -------------------------------------------------------------------------------- /templates/client-poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: {{ template "fullname" . }}-client 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }} 11 | role: client 12 | spec: 13 | minAvailable: 50% 14 | selector: 15 | matchLabels: 16 | app: {{ template "fullname" . }} 17 | role: client 18 | -------------------------------------------------------------------------------- /templates/client-service-external.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.client.expose }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "fullname" . }}-expose 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | component: {{ template "fullname" . }}-client 12 | role: client 13 | annotations: 14 | service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0 15 | spec: 16 | type: LoadBalancer 17 | selector: 18 | component: {{ template "fullname" . }}-client 19 | role: client 20 | ports: 21 | - name: http 22 | port: {{ .Values.service.httpPort }} 23 | targetPort: 9200 24 | protocol: TCP 25 | - name: transport 26 | port: {{ .Values.service.transportPort }} 27 | targetPort: 9300 28 | protocol: TCP 29 | {{- end -}} -------------------------------------------------------------------------------- /templates/client-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }}-client 11 | role: client 12 | spec: 13 | type: {{ .Values.common.serviceType }} 14 | selector: 15 | component: {{ template "fullname" . }}-client 16 | role: client 17 | ports: 18 | - name: http 19 | port: {{ .Values.service.httpPort }} 20 | targetPort: 9200 21 | protocol: TCP 22 | - name: transport 23 | port: {{ .Values.service.transportPort }} 24 | targetPort: 9300 25 | protocol: TCP 26 | -------------------------------------------------------------------------------- /templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "fullname" . }} 11 | rules: 12 | - apiGroups: 13 | - certificates.k8s.io 14 | resources: 15 | - certificatesigningrequests 16 | verbs: 17 | - create 18 | - get 19 | - delete 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" .}} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "fullname" . }} 11 | roleRef: 12 | apiGroup: rbac.authorization.k8s.io 13 | kind: ClusterRole 14 | name: {{ template "fullname" . }} 15 | subjects: 16 | - kind: ServiceAccount 17 | name: {{ template "fullname" . }} 18 | namespace: {{ .Release.Namespace }} 19 | {{- end -}} 20 | -------------------------------------------------------------------------------- /templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "fullname" . }}-config 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | data: 11 | jvm.options: |- 12 | ## GC configuration 13 | -XX:G1ConcRefinementThreads=8 14 | -XX:GCDrainStackTargetSize=64 15 | -XX:+SegmentedCodeCache 16 | -XX:+UseCompressedClassPointers 17 | -XX:+UseCompressedOops 18 | -XX:+UseG1GC 19 | -XX:+AlwaysPreTouch 20 | -server 21 | -Xss1m 22 | -Djava.awt.headless=true 23 | -Dfile.encoding=UTF-8 24 | -Djna.nosys=true 25 | -XX:-OmitStackTraceInFastThrow 26 | -Dio.netty.noUnsafe=true 27 | -Dio.netty.noKeySetOptimization=true 28 | -Dio.netty.recycler.maxCapacityPerThread=0 29 | -Dlog4j.shutdownHookEnabled=false 30 | -Dlog4j2.disable.jmx=true 31 | 32 | log4j2.properties: |- 33 | status = error 34 | appender.console.type = Console 35 | appender.console.name = console 36 | appender.console.layout.type = PatternLayout 37 | appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n 38 | rootLogger.level = info 39 | rootLogger.appenderRef.console.ref = console 40 | 41 | elasticsearch.yml: |- 42 | cluster: 43 | name: {{ .Values.common.env.CLUSTER_NAME }} 44 | 45 | node: 46 | master: ${NODE_MASTER:true} 47 | data: ${NODE_DATA:true} 48 | name: ${NODE_NAME} 49 | ingest: ${NODE_INGEST:true} 50 | max_local_storage_nodes: ${MAX_LOCAL_STORAGE_NODES:1} 51 | 52 | network.host: ${NETWORK_HOST:_local_} 53 | 54 | path: 55 | data: /storage/data 56 | logs: /storage/logs 57 | 58 | bootstrap: 59 | memory_lock: ${MEMORY_LOCK:false} 60 | 61 | http: 62 | enabled: ${HTTP_ENABLE:true} 63 | compression: true 64 | cors: 65 | enabled: ${HTTP_CORS_ENABLE:false} 66 | allow-origin: ${HTTP_CORS_ALLOW_ORIGIN:"*"} 67 | 68 | indices: 69 | memory.index_buffer_size: 30% 70 | 71 | #index: 72 | # refresh_interval: 30s 73 | 74 | discovery: 75 | zen: 76 | ping.unicast.hosts: ${DISCOVERY_SERVICE:} 77 | minimum_master_nodes: ${NUMBER_OF_MASTERS:1} 78 | 79 | # see https://github.com/elastic/elasticsearch-definitive-guide/pull/679 80 | processors: ${PROCESSORS:} 81 | {{- if .Values.tls.enable }} 82 | opendistro_security: 83 | {{- if .Values.opendistro_security.enable }} 84 | advanced_modules_enabled: {{ .Values.opendistro_security.advanced_modules_enabled }} 85 | restapi: 86 | roles_enabled: ["all_access", "security_rest_api_access"] 87 | nodes_dn: 88 | - "CN=*.{{ template "fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }}" 89 | authcz: 90 | admin_dn: 91 | - "CN=admin.{{ template "fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }},OU=securityadmin,O=logging" 92 | {{- end }} 93 | ssl: 94 | http: 95 | clientauth_mode: REQUIRE 96 | enabled: true 97 | enabled_protocols: 98 | - "TLSv1.3" 99 | - "TLSv1.2" 100 | pemkey_filepath: tls/tls.key 101 | pemcert_filepath: tls/tls.crt 102 | pemtrustedcas_filepath: tls/ca.crt 103 | transport: 104 | pemkey_filepath: tls/tls.key 105 | pemcert_filepath: tls/tls.crt 106 | pemtrustedcas_filepath: tls/ca.crt 107 | {{- end }} 108 | 109 | {{- if .Values.common.config }} 110 | {{ toYaml .Values.common.config | indent 4 }} 111 | {{- end }} 112 | -------------------------------------------------------------------------------- /templates/curator-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable }} 2 | {{- if .Values.rbac.create -}} 3 | apiVersion: rbac.authorization.k8s.io/v1beta1 4 | kind: ClusterRole 5 | metadata: 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-curator 12 | rules: 13 | - apiGroups: 14 | - certificates.k8s.io 15 | resources: 16 | - certificatesigningrequests 17 | verbs: 18 | - create 19 | - get 20 | - delete 21 | {{- end -}} 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /templates/curator-clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable -}} 2 | {{- if .Values.rbac.create -}} 3 | apiVersion: rbac.authorization.k8s.io/v1beta1 4 | kind: ClusterRoleBinding 5 | metadata: 6 | labels: 7 | app: {{ template "fullname" .}} 8 | component: curator 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | name: {{ template "fullname" . }}-curator 13 | roleRef: 14 | apiGroup: rbac.authorization.k8s.io 15 | kind: ClusterRole 16 | name: {{ template "fullname" . }}-curator 17 | subjects: 18 | - kind: ServiceAccount 19 | name: {{ template "fullname" . }}-curator 20 | namespace: {{ .Release.Namespace }} 21 | {{- end -}} 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /templates/curator-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- define "acton_file_template" }} 2 | # Remember, leave a key empty if there is no value. None will be a string, 3 | # not a Python "NoneType" 4 | # 5 | # Also remember that all examples have 'disable_action' set to True. If you 6 | # want to use this action as a template, be sure to set this to False after 7 | # copying it. 8 | actions: 9 | {{- range $index, $action := .Values.curator.actions }} 10 | {{ add $index 1 }}: 11 | action: {{ $action.action}} 12 | description: {{ $action.description }} 13 | options: 14 | ignore_empty_list: True 15 | timeout_override: 16 | continue_if_exception: False 17 | disable_action: False 18 | {{- if hasKey $action "filters" }} 19 | filters: 20 | {{- range .filters }} 21 | {{- if eq ( .type | toString ) "age" }} 22 | - filtertype: {{ .type }} 23 | source: {{ .source }} 24 | direction: {{ .direction }} 25 | timestring: {{ .timestring | toString | quote }} 26 | unit: {{ .unit }} 27 | unit_count: {{ .unit_count }} 28 | field: 29 | stats_result: 30 | epoch: 31 | exclude: {{ .exclude }} 32 | {{- end }} 33 | 34 | {{- /* end Filters iteration */ -}} 35 | {{- end }} 36 | 37 | {{- /* end Filters test */ -}} 38 | {{- end }} 39 | 40 | {{- /* end Actions iteration */ -}} 41 | {{- end }} 42 | {{end}} 43 | 44 | {{- if .Values.curator.enable }} 45 | apiVersion: v1 46 | kind: ConfigMap 47 | metadata: 48 | name: {{ template "fullname" . }}-curator-config 49 | labels: 50 | component: curator 51 | app: {{ template "fullname" . }} 52 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 53 | release: "{{ .Release.Name }}" 54 | heritage: "{{ .Release.Service }}" 55 | data: 56 | action_file.yml: |- 57 | --- 58 | {{- template "acton_file_template" . }} 59 | 60 | config.yml: |- 61 | --- 62 | # Remember, leave a key empty if there is no value. None will be a string, 63 | # not a Python "NoneType" 64 | client: 65 | hosts: 66 | - {{ template "fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }} 67 | port: {{ .Values.service.httpPort }} 68 | url_prefix: 69 | {{- if .Values.tls.enable }} 70 | use_ssl: True 71 | certificate: /tls/ca.crt 72 | client_cert: /tls/tls.crt 73 | client_key: /tls/tls.key 74 | ssl_no_validate: False 75 | {{- else }} 76 | use_ssl: False 77 | certificate: 78 | client_cert: 79 | client_key: 80 | ssl_no_validate: False 81 | {{- end }} 82 | http_auth: 83 | timeout: 30 84 | master_only: False 85 | 86 | logging: 87 | loglevel: DEBUG 88 | logfile: 89 | logformat: json 90 | blacklist: [] #['elasticsearch', 'urllib3'] 91 | {{- end }} -------------------------------------------------------------------------------- /templates/curator-cronjob.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable }} 2 | apiVersion: {{ template "curator.cronJob.apiVersion" . }} 3 | kind: CronJob 4 | metadata: 5 | name: {{ template "fullname" . }}-curator 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | schedule: {{ .Values.curator.schedule }} 13 | jobTemplate: 14 | spec: 15 | template: 16 | spec: 17 | serviceAccountName: {{ template "fullname" . }}-curator 18 | subdomain: "{{ template "fullname" . }}" 19 | {{- if .Values.tls.enable }} 20 | initContainers: 21 | - name: generate-tls-pair 22 | image: "{{ .Values.tls.image }}:{{ .Values.tls.imageTag }}" 23 | imagePullPolicy: "{{ .Values.tls.imagePullPolicy }}" 24 | env: 25 | - name: NAMESPACE 26 | valueFrom: 27 | fieldRef: 28 | fieldPath: metadata.namespace 29 | - name: POD_NAME 30 | valueFrom: 31 | fieldRef: 32 | fieldPath: metadata.name 33 | - name: SUBDOMAIN 34 | value: {{ template "fullname" . }} 35 | - name: POD_IP 36 | valueFrom: 37 | fieldRef: 38 | fieldPath: status.podIP 39 | args: 40 | - "-namespace=$(NAMESPACE)" 41 | - "-pod-ip=$(POD_IP)" 42 | - "-pod-name=$(POD_NAME)" 43 | - "-hostname=$(POD_NAME)" 44 | - "-subdomain=$(SUBDOMAIN)" 45 | - "-organizations=logging" 46 | - "-organizational-units=curator" 47 | - "-headless-name-as-cn" 48 | - "-service-names={{ template "fullname" . }}-discovery,{{ template "fullname" . }}" 49 | - "-pkcs8" 50 | - "-labels=component={{ template "fullname" . }}" 51 | - "-secret-name={{ template "fullname" . }}-curator-keys" 52 | {{- end }} 53 | containers: 54 | - name: curator 55 | image: "{{ .Values.curator.image }}:{{ .Values.curator.imageTag }}" 56 | imagePullPolicy: "{{ .Values.curator.imagePullPolicy }}" 57 | args: ["--config", "/etc/config/config.yml", "/etc/config/action_file.yml"] 58 | resources: 59 | limits: 60 | cpu: 200m 61 | memory: 256Mi 62 | requests: 63 | cpu: 100m 64 | memory: 256Mi 65 | volumeMounts: 66 | - name: config-volume 67 | mountPath: /etc/config 68 | - name: tls 69 | mountPath: /tls 70 | volumes: 71 | - name: tls 72 | secret: 73 | secretName: {{ template "fullname" . }}-curator-keys 74 | defaultMode: 511 75 | - name: config-volume 76 | configMap: 77 | name: {{ template "fullname" . }}-curator-config 78 | restartPolicy: OnFailure 79 | {{- end }} 80 | -------------------------------------------------------------------------------- /templates/curator-role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: Role 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "fullname" . }}-curator 11 | namespace: {{ .Release.Namespace }} 12 | rules: 13 | - apiGroups: [""] 14 | resources: 15 | - secrets 16 | resourceNames: 17 | - "{{ template "fullname" . }}-curator-keys" 18 | verbs: 19 | - update 20 | - get 21 | {{- end -}} 22 | -------------------------------------------------------------------------------- /templates/curator-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: RoleBinding 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" .}} 7 | component: curator 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-curator 12 | namespace: {{ .Release.Namespace }} 13 | roleRef: 14 | apiGroup: rbac.authorization.k8s.io 15 | kind: Role 16 | name: {{ template "fullname" . }}-curator 17 | subjects: 18 | - kind: ServiceAccount 19 | name: {{ template "fullname" . }}-curator 20 | namespace: {{ .Release.Namespace }} 21 | {{- end -}} 22 | -------------------------------------------------------------------------------- /templates/curator-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | component: curator 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | heritage: "{{ .Release.Service }}" 10 | release: "{{ .Release.Name }}" 11 | name: {{ template "fullname" . }}-curator-keys 12 | namespace: {{ .Release.Namespace }} 13 | type: tls 14 | data: 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /templates/curator-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.curator.enable }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | component: curator 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-curator 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /templates/data-poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: {{ template "fullname" . }}-data 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }} 11 | role: data 12 | spec: 13 | minAvailable: 50% 14 | selector: 15 | matchLabels: 16 | app: {{ template "fullname" . }} 17 | role: data 18 | -------------------------------------------------------------------------------- /templates/data-statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ template "fullname" . }}-data 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }} 11 | role: data 12 | spec: 13 | serviceName: {{ template "fullname" . }}-data 14 | replicas: {{ .Values.data.replicas }} 15 | updateStrategy: 16 | type: RollingUpdate 17 | podManagementPolicy: Parallel 18 | selector: 19 | matchLabels: 20 | component: {{ template "fullname" . }} 21 | role: data 22 | template: 23 | metadata: 24 | labels: 25 | release: "{{ .Release.Name }}" 26 | app: {{ template "fullname" . }} 27 | component: {{ template "fullname" . }} 28 | role: data 29 | {{- if .Values.data.labels }} 30 | {{ toYaml .Values.data.labels | indent 8 }} 31 | {{- end }} 32 | {{- if .Values.data.annotations }} 33 | annotations: 34 | {{ toYaml .Values.data.annotations | indent 8 }} 35 | {{- end }} 36 | spec: 37 | subdomain: {{ template "fullname" . }} 38 | serviceAccountName: {{ template "fullname" . }} 39 | securityContext: 40 | fsGroup: 1000 41 | {{- if eq .Values.data.antiAffinity "hard" }} 42 | affinity: 43 | podAntiAffinity: 44 | requiredDuringSchedulingIgnoredDuringExecution: 45 | - topologyKey: "kubernetes.io/hostname" 46 | labelSelector: 47 | matchLabels: 48 | component: {{ template "fullname" . }} 49 | role: data 50 | preferredDuringSchedulingIgnoredDuringExecution: 51 | - weight: 1 52 | podAffinityTerm: 53 | topologyKey: "failure-domain.beta.kubernetes.io/zone" 54 | labelSelector: 55 | matchLabels: 56 | component: {{ template "fullname" . }} 57 | role: data 58 | {{- else if eq .Values.data.antiAffinity "soft" }} 59 | affinity: 60 | podAntiAffinity: 61 | preferredDuringSchedulingIgnoredDuringExecution: 62 | - weight: 1 63 | podAffinityTerm: 64 | topologyKey: "failure-domain.beta.kubernetes.io/zone" 65 | labelSelector: 66 | matchLabels: 67 | component: {{ template "fullname" . }} 68 | role: data 69 | - weight: 2 70 | podAffinityTerm: 71 | topologyKey: "kubernetes.io/hostname" 72 | labelSelector: 73 | matchLabels: 74 | component: {{ template "fullname" . }} 75 | role: data 76 | {{- end }} 77 | initContainers: 78 | {{ include "init-containers" . | indent 6 }} 79 | containers: 80 | - name: elasticsearch 81 | image: "{{ .Values.common.image.repository }}:{{ .Values.common.image.tag }}" 82 | imagePullPolicy: {{ .Values.common.image.pullPolicy }} 83 | securityContext: 84 | capabilities: 85 | add: 86 | - IPC_LOCK 87 | - SYS_RESOURCE 88 | env: 89 | - name: NAMESPACE 90 | valueFrom: 91 | fieldRef: 92 | fieldPath: metadata.namespace 93 | - name: NODE_NAME 94 | valueFrom: 95 | fieldRef: 96 | fieldPath: metadata.name 97 | - name: DISCOVERY_SERVICE 98 | value: {{ template "fullname" . }}-discovery.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }} 99 | - name: ES_JAVA_OPTS 100 | value: "-XX:ParallelGCThreads={{ .Values.data.processors | mul 3 }} -Djava.net.preferIPv4Stack=true -Xms{{ .Values.data.heapSize }} -Xmx{{ .Values.data.heapSize }}" 101 | - name: NODE_DATA 102 | value: "true" 103 | - name: NODE_MASTER 104 | value: "false" 105 | - name: NODE_INGEST 106 | value: "false" 107 | - name: HTTP_ENABLE 108 | value: "{{ .Values.data.enableHTTP }}" 109 | - name: PROCESSORS 110 | value: "{{ .Values.data.processors }}" 111 | {{- range $key, $value := .Values.common.env }} 112 | - name: {{ $key | upper | replace "-" "_" }} 113 | value: {{ $value | quote }} 114 | {{- end }} 115 | {{- range $key, $value := .Values.data.env }} 116 | - name: {{ $key | upper | replace "-" "_" }} 117 | value: {{ $value | quote }} 118 | {{- end }} 119 | ports: 120 | - containerPort: 9300 121 | name: transport 122 | protocol: TCP 123 | {{- if .Values.data.enableHTTP }} 124 | - containerPort: 9200 125 | name: http 126 | protocol: TCP 127 | {{- end }} 128 | readinessProbe: 129 | {{- if and .Values.master.enableHTTP (not .Values.opendistro_security.enable) }} 130 | {{/* We cannot use http readinessProbe for opendistro_security since it requires client cert auth */}} 131 | httpGet: 132 | path: /_cluster/health?local=true 133 | port: http 134 | {{- if .Values.tls.enable }} 135 | scheme: HTTPS 136 | {{- end }} 137 | {{- else }} 138 | tcpSocket: 139 | port: transport 140 | {{- end }} 141 | initialDelaySeconds: 20 142 | periodSeconds: 10 143 | failureThreshold: 30 144 | livenessProbe: 145 | tcpSocket: 146 | port: transport 147 | initialDelaySeconds: 60 148 | periodSeconds: 10 149 | resources: 150 | {{ toYaml .Values.data.resources | indent 10 }} 151 | volumeMounts: 152 | {{- if .Values.common.plugins }} 153 | - mountPath: /usr/share/elasticsearch/config/ 154 | name: configdir 155 | - mountPath: /usr/share/elasticsearch/plugins/ 156 | name: plugindir 157 | {{- end }} 158 | {{- if .Values.tls.enable }} 159 | - mountPath: /usr/share/elasticsearch/config/tls/ 160 | name: tls 161 | readOnly: true 162 | {{- end }} 163 | - mountPath: /storage/ 164 | name: storage 165 | - mountPath: /usr/share/elasticsearch/config/jvm.options 166 | name: config 167 | subPath: jvm.options 168 | - mountPath: /usr/share/elasticsearch/config/log4j2.properties 169 | name: config 170 | subPath: log4j2.properties 171 | - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml 172 | name: config 173 | subPath: elasticsearch.yml 174 | {{- if .Values.opendistro_security.enable }} 175 | - mountPath: /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/ 176 | name: security-config 177 | {{- end }} 178 | volumes: 179 | {{- if .Values.client.expose }} 180 | - name: prodsaca 181 | secret: 182 | secretName: prod-sa-ca 183 | {{- end }} 184 | {{- if .Values.common.plugins }} 185 | - name: configdir 186 | emptyDir: {} 187 | - name: plugindir 188 | emptyDir: {} 189 | {{- end }} 190 | {{- if .Values.tls.enable }} 191 | - name: tls 192 | emptyDir: {} 193 | {{- end }} 194 | - configMap: 195 | name: {{ template "fullname" . }}-config 196 | name: config 197 | {{- if .Values.opendistro_security.enable }} 198 | - configMap: 199 | name: {{ template "fullname" . }}-security-config 200 | name: security-config 201 | {{- end }} 202 | volumeClaimTemplates: 203 | - metadata: 204 | name: storage 205 | spec: 206 | accessModes: [ "ReadWriteOnce" ] 207 | storageClassName: {{ .Values.data.storageClass }} 208 | resources: 209 | requests: 210 | storage: {{ .Values.data.storage }} 211 | -------------------------------------------------------------------------------- /templates/master-poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: {{ template "fullname" . }}-master 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }} 11 | role: master 12 | spec: 13 | minAvailable: 51% 14 | selector: 15 | matchLabels: 16 | app: {{ template "fullname" . }} 17 | role: master 18 | -------------------------------------------------------------------------------- /templates/master-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }}-discovery 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }} 11 | role: master 12 | spec: 13 | selector: 14 | component: {{ template "fullname" . }} 15 | role: master 16 | ports: 17 | - name: transport 18 | port: 9300 19 | protocol: TCP 20 | -------------------------------------------------------------------------------- /templates/master-statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ template "fullname" . }}-master 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "fullname" . }}-master 11 | role: master 12 | spec: 13 | serviceName: {{ template "fullname" . }}-master 14 | replicas: {{ .Values.master.replicas }} 15 | updateStrategy: 16 | type: RollingUpdate 17 | podManagementPolicy: Parallel 18 | selector: 19 | matchLabels: 20 | component: {{ template "fullname" . }} 21 | role: master 22 | template: 23 | metadata: 24 | labels: 25 | release: "{{ .Release.Name }}" 26 | app: {{ template "fullname" . }} 27 | component: {{ template "fullname" . }} 28 | role: master 29 | {{- if .Values.master.labels }} 30 | {{ toYaml .Values.master.labels | indent 8 }} 31 | {{- end }} 32 | {{- if .Values.master.annotations }} 33 | annotations: 34 | {{ toYaml .Values.master.annotations | indent 8 }} 35 | {{- end }} 36 | spec: 37 | subdomain: {{ template "fullname" . }} 38 | serviceAccountName: {{ template "fullname" . }} 39 | securityContext: 40 | fsGroup: 1000 41 | {{- if eq .Values.master.antiAffinity "hard" }} 42 | affinity: 43 | podAntiAffinity: 44 | requiredDuringSchedulingIgnoredDuringExecution: 45 | - topologyKey: "failure-domain.beta.kubernetes.io/zone" 46 | labelSelector: 47 | matchLabels: 48 | component: {{ template "fullname" . }} 49 | role: master 50 | preferredDuringSchedulingIgnoredDuringExecution: 51 | - weight: 1 52 | podAffinityTerm: 53 | topologyKey: "kubernetes.io/hostname" 54 | labelSelector: 55 | matchLabels: 56 | component: {{ template "fullname" . }} 57 | role: master 58 | {{- else if eq .Values.master.antiAffinity "soft" }} 59 | affinity: 60 | podAntiAffinity: 61 | preferredDuringSchedulingIgnoredDuringExecution: 62 | - weight: 1 63 | podAffinityTerm: 64 | topologyKey: "failure-domain.beta.kubernetes.io/zone" 65 | labelSelector: 66 | matchLabels: 67 | component: {{ template "fullname" . }} 68 | role: master 69 | - weight: 2 70 | podAffinityTerm: 71 | topologyKey: "kubernetes.io/hostname" 72 | labelSelector: 73 | matchLabels: 74 | component: {{ template "fullname" . }} 75 | role: master 76 | {{- end }} 77 | initContainers: 78 | {{ include "init-containers" . | indent 6 }} 79 | containers: 80 | - name: elasticsearch 81 | securityContext: 82 | capabilities: 83 | add: 84 | - IPC_LOCK 85 | - SYS_RESOURCE 86 | image: "{{ .Values.common.image.repository }}:{{ .Values.common.image.tag }}" 87 | imagePullPolicy: {{ .Values.common.image.pullPolicy }} 88 | env: 89 | - name: NAMESPACE 90 | valueFrom: 91 | fieldRef: 92 | fieldPath: metadata.namespace 93 | - name: NODE_NAME 94 | valueFrom: 95 | fieldRef: 96 | fieldPath: metadata.name 97 | - name: DISCOVERY_SERVICE 98 | value: {{ template "fullname" . }}-discovery.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }} 99 | - name: ES_JAVA_OPTS 100 | value: "-XX:ParallelGCThreads={{ .Values.data.processors | mul 3 }} -Djava.net.preferIPv4Stack=true -Xms{{ .Values.master.heapSize }} -Xmx{{ .Values.master.heapSize }}" 101 | - name: NODE_DATA 102 | value: "false" 103 | - name: NODE_MASTER 104 | value: "true" 105 | - name: NODE_INGEST 106 | value: "false" 107 | - name: HTTP_ENABLE 108 | value: "{{ .Values.master.enableHTTP }}" 109 | - name: PROCESSORS 110 | value: "{{ .Values.master.processors }}" 111 | {{- range $key, $value := .Values.common.env }} 112 | - name: {{ $key | upper | replace "-" "_" }} 113 | value: {{ $value | quote }} 114 | {{- end }} 115 | {{- range $key, $value := .Values.master.env }} 116 | - name: {{ $key | upper | replace "-" "_" }} 117 | value: {{ $value | quote }} 118 | {{- end }} 119 | resources: 120 | {{ toYaml .Values.master.resources | indent 10 }} 121 | ports: 122 | - containerPort: 9300 123 | name: transport 124 | protocol: TCP 125 | {{- if .Values.master.enableHTTP }} 126 | - containerPort: 9200 127 | name: http 128 | protocol: TCP 129 | {{- end }} 130 | readinessProbe: 131 | {{- if and .Values.master.enableHTTP (not .Values.opendistro_security.enable) -}} 132 | {{/* We cannot use http readinessProbe for opendistro_security since it requires client cert auth */}} 133 | httpGet: 134 | path: /_cluster/health?local=true 135 | port: http 136 | {{- if .Values.tls.enable }} 137 | scheme: HTTPS 138 | {{- end }} 139 | {{- else }} 140 | tcpSocket: 141 | port: transport 142 | {{- end }} 143 | initialDelaySeconds: 50 144 | periodSeconds: 10 145 | failureThreshold: 30 146 | livenessProbe: 147 | tcpSocket: 148 | port: transport 149 | initialDelaySeconds: 60 150 | periodSeconds: 10 151 | resources: 152 | {{ toYaml .Values.master.resources | indent 10 }} 153 | volumeMounts: 154 | {{- if .Values.common.plugins }} 155 | - mountPath: /usr/share/elasticsearch/config/ 156 | name: configdir 157 | - mountPath: /usr/share/elasticsearch/plugins/ 158 | name: plugindir 159 | {{- end }} 160 | {{- if .Values.tls.enable }} 161 | - mountPath: /usr/share/elasticsearch/config/tls/ 162 | name: tls 163 | readOnly: true 164 | {{- end }} 165 | - mountPath: /storage/ 166 | name: storage 167 | - mountPath: /usr/share/elasticsearch/config/jvm.options 168 | name: config 169 | subPath: jvm.options 170 | - mountPath: /usr/share/elasticsearch/config/log4j2.properties 171 | name: config 172 | subPath: log4j2.properties 173 | - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml 174 | name: config 175 | subPath: elasticsearch.yml 176 | {{- if .Values.opendistro_security.enable }} 177 | - mountPath: /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/ 178 | name: security-config 179 | {{- end }} 180 | volumes: 181 | {{- if .Values.client.expose }} 182 | - name: prodsaca 183 | secret: 184 | secretName: prod-sa-ca 185 | {{- end }} 186 | {{- if .Values.common.plugins }} 187 | - name: configdir 188 | emptyDir: {} 189 | - name: plugindir 190 | emptyDir: {} 191 | {{- end }} 192 | {{- if .Values.tls.enable }} 193 | - name: tls 194 | emptyDir: {} 195 | {{- end }} 196 | - configMap: 197 | name: {{ template "fullname" . }}-config 198 | name: config 199 | {{- if .Values.opendistro_security.enable }} 200 | - configMap: 201 | name: {{ template "fullname" . }}-security-config 202 | name: security-config 203 | {{- end }} 204 | volumeClaimTemplates: 205 | - metadata: 206 | name: storage 207 | spec: 208 | accessModes: [ "ReadWriteOnce" ] 209 | storageClassName: {{ .Values.master.storageClass }} 210 | resources: 211 | requests: 212 | storage: {{ .Values.master.storage }} 213 | -------------------------------------------------------------------------------- /templates/security-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ template "fullname" . }}-security-config 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | data: 12 | action_groups.yml: |- 13 | UNLIMITED: 14 | readonly: true 15 | permissions: 16 | - "*" 17 | INDICES_ALL: 18 | readonly: true 19 | permissions: 20 | - "indices:*" 21 | MANAGE: 22 | readonly: true 23 | permissions: 24 | - "indices:monitor/*" 25 | - "indices:admin/*" 26 | CREATE_INDEX: 27 | readonly: true 28 | permissions: 29 | - "indices:admin/create" 30 | - "indices:admin/mapping/put" 31 | MANAGE_ALIASES: 32 | readonly: true 33 | permissions: 34 | - "indices:admin/aliases*" 35 | INDICES_MONITOR: 36 | readonly: true 37 | permissions: 38 | - "indices:monitor/*" 39 | DATA_ACCESS: 40 | readonly: true 41 | permissions: 42 | - "indices:data/*" 43 | - CRUD 44 | WRITE: 45 | readonly: true 46 | permissions: 47 | - "indices:data/write*" 48 | - "indices:admin/mapping/put" 49 | READ: 50 | readonly: true 51 | permissions: 52 | - "indices:data/read*" 53 | - "indices:admin/mappings/fields/get*" 54 | DELETE: 55 | readonly: true 56 | permissions: 57 | - "indices:data/write/delete*" 58 | CRUD: 59 | readonly: true 60 | permissions: 61 | - READ 62 | - WRITE 63 | SEARCH: 64 | readonly: true 65 | permissions: 66 | - "indices:data/read/search*" 67 | - "indices:data/read/msearch*" 68 | - SUGGEST 69 | SUGGEST: 70 | readonly: true 71 | permissions: 72 | - "indices:data/read/suggest*" 73 | INDEX: 74 | readonly: true 75 | permissions: 76 | - "indices:data/write/index*" 77 | - "indices:data/write/update*" 78 | - "indices:admin/mapping/put" 79 | - "indices:data/write/bulk*" 80 | GET: 81 | readonly: true 82 | permissions: 83 | - "indices:data/read/get*" 84 | - "indices:data/read/mget*" 85 | 86 | CLUSTER_ALL: 87 | readonly: true 88 | permissions: 89 | - "cluster:*" 90 | CLUSTER_MONITOR: 91 | readonly: true 92 | permissions: 93 | - "cluster:monitor/*" 94 | CLUSTER_COMPOSITE_OPS_RO: 95 | readonly: true 96 | permissions: 97 | - "indices:data/read/mget" 98 | - "indices:data/read/msearch" 99 | - "indices:data/read/mtv" 100 | - "indices:data/read/coordinate-msearch*" 101 | - "indices:admin/aliases/exists*" 102 | - "indices:admin/aliases/get*" 103 | - "indices:data/read/scroll" 104 | CLUSTER_COMPOSITE_OPS: 105 | readonly: true 106 | permissions: 107 | - "indices:data/write/bulk" 108 | - "indices:admin/aliases*" 109 | - CLUSTER_COMPOSITE_OPS_RO 110 | MANAGE_SNAPSHOTS: 111 | readonly: true 112 | permissions: 113 | - "cluster:admin/snapshot/*" 114 | - "cluster:admin/repository/*" 115 | config.yml: |- 116 | opendistro_security: 117 | dynamic: 118 | kibana: 119 | multitenancy_enabled: false 120 | server_username: {{ .Values.opendistro_security.kibana_user }} 121 | index: '.kibana' 122 | do_not_fail_on_forbidden: false 123 | http: 124 | anonymous_auth_enabled: false 125 | xff: 126 | enabled: true 127 | internalProxies: '.+' # since we require clientauth cert for http, we do not need to do IP filtering 128 | remoteIpHeader: 'x-forwarded-for' 129 | proxiesHeader: 'x-forwarded-by' 130 | trustedProxies: '.+' # trust all external proxies, regex pattern 131 | authc: 132 | proxy_auth_domain: 133 | http_enabled: true 134 | transport_enabled: false 135 | order: 0 136 | http_authenticator: 137 | type: proxy 138 | challenge: false 139 | config: 140 | user_header: "x-forwarded-email" 141 | #roles_header: "x-proxy-roles" 142 | authentication_backend: 143 | type: noop 144 | clientcert_auth_domain: 145 | http_enabled: true 146 | transport_enabled: true 147 | order: 1 148 | http_authenticator: 149 | type: clientcert 150 | config: 151 | username_attribute: ou #optional, if omitted DN becomes username 152 | challenge: false 153 | authentication_backend: 154 | type: noop 155 | roles.yml: |- 156 | # Allows everything, but no changes to opendistro_security configuration index 157 | all_access: 158 | readonly: true 159 | cluster: 160 | - UNLIMITED 161 | indices: 162 | '*': 163 | '*': 164 | - UNLIMITED 165 | tenants: 166 | admin_tenant: RW 167 | 168 | # Read all, but no write permissions 169 | readall: 170 | readonly: true 171 | cluster: 172 | - CLUSTER_COMPOSITE_OPS_RO 173 | indices: 174 | '*': 175 | '*': 176 | - READ 177 | 178 | # Read all and monitor, but no write permissions 179 | readall_and_monitor: 180 | cluster: 181 | - CLUSTER_MONITOR 182 | - CLUSTER_COMPOSITE_OPS_RO 183 | indices: 184 | '*': 185 | '*': 186 | - READ 187 | 188 | # For users which use kibana, access to indices must be granted separately 189 | kibana_user: 190 | readonly: true 191 | cluster: 192 | - CLUSTER_MONITOR 193 | - CLUSTER_COMPOSITE_OPS_RO 194 | indices: 195 | '?kibana': 196 | '*': 197 | - MANAGE 198 | - INDEX 199 | - READ 200 | - DELETE 201 | '?tasks': 202 | '*': 203 | - INDICES_ALL 204 | '?management-beats': 205 | '*': 206 | - INDICES_ALL 207 | '*': 208 | '*': 209 | - "indices:data/read/field_caps" 210 | - indices:data/read/xpack/rollup* 211 | - indices:admin/mappings/get* 212 | - indices:admin/get 213 | 214 | # For the kibana server 215 | kibana_server: 216 | readonly: true 217 | cluster: 218 | - CLUSTER_MONITOR 219 | - CLUSTER_COMPOSITE_OPS 220 | - CLUSTER_COMPOSITE_OPS 221 | - cluster:admin/xpack/monitoring* 222 | - indices:admin/template* 223 | - indices:data/read/scroll* 224 | - indices:data/write/reindex 225 | indices: 226 | 'logstash-*': 227 | '*': 228 | - "indices:data/read/field_caps*" 229 | 'tracing-*': 230 | '*': 231 | - "indices:data/read/field_caps*" 232 | 'k8slogs-*': 233 | '*': 234 | - "indices:data/read/field_caps*" 235 | '?kibana': 236 | '*': 237 | - INDICES_ALL 238 | '?kibana-6': 239 | '*': 240 | - INDICES_ALL 241 | '?kibana_*': 242 | '*': 243 | - INDICES_ALL 244 | '?reporting*': 245 | '*': 246 | - INDICES_ALL 247 | '?monitoring*': 248 | '*': 249 | - INDICES_ALL 250 | '?tasks': 251 | '*': 252 | - INDICES_ALL 253 | '?management-beats*': 254 | '*': 255 | - INDICES_ALL 256 | '*': 257 | '*': 258 | - "indices:admin/aliases*" 259 | 260 | spanwrite: 261 | readonly: true 262 | cluster: 263 | - CLUSTER_MONITOR 264 | - CLUSTER_COMPOSITE_OPS 265 | - "indices:admin/template/get" 266 | - "indices:admin/template/put" 267 | indices: 268 | 'jaeger-*': 269 | '*': 270 | - WRITE 271 | - CREATE_INDEX 272 | 273 | spanread: 274 | cluster: 275 | - CLUSTER_MONITOR 276 | readonly: true 277 | indices: 278 | 'jaeger-*': 279 | '*': 280 | - READ 281 | 282 | logreader: 283 | readonly: true 284 | indices: 285 | 'jaeger-*': 286 | '*': 287 | - READ 288 | 'logstash-*': 289 | '*': 290 | - READ 291 | 'k8slogs-*': 292 | '*': 293 | - READ 294 | 295 | # For logstash and beats 296 | logwrite: 297 | readonly: true 298 | cluster: 299 | - CLUSTER_MONITOR 300 | - CLUSTER_COMPOSITE_OPS 301 | - "indices:admin/template/get" 302 | - "indices:admin/template/put" 303 | indices: 304 | 'logstash-*': 305 | '*': 306 | - WRITE 307 | - CREATE_INDEX 308 | 'k8slogs-*': 309 | '*': 310 | - WRITE 311 | - CREATE_INDEX 312 | '*beat*': 313 | '*': 314 | - WRITE 315 | - CREATE_INDEX 316 | 317 | prometheus: 318 | readonly: true 319 | cluster: 320 | - CLUSTER_MONITOR 321 | indices: 322 | '*': 323 | '*': 324 | - INDICES_MONITOR 325 | 326 | curator: 327 | readonly: true 328 | cluster: 329 | - CLUSTER_MONITOR 330 | - CLUSTER_COMPOSITE_OPS 331 | indices: 332 | '*': 333 | '*': 334 | - READ 335 | - INDICES_MONITOR 336 | 'tracing-*': 337 | '*': 338 | - READ 339 | - INDICES_MONITOR 340 | - DELETE 341 | 'k8slogs-*': 342 | '*': 343 | - READ 344 | - INDICES_MONITOR 345 | - DELETE 346 | 'logstash-*': 347 | '*': 348 | - READ 349 | - INDICES_MONITOR 350 | - DELETE 351 | 352 | # Allows adding and modifying repositories and creating and restoring snapshots 353 | manage_snapshots: 354 | readonly: true 355 | cluster: 356 | - MANAGE_SNAPSHOTS 357 | indices: 358 | '*': 359 | '*': 360 | - "indices:data/write/index" 361 | - "indices:admin/create" 362 | 363 | # View and acknowledge alerts for Open Distro for Elasticsearch Alerting 364 | alerting_acknowledge: 365 | readonly: true 366 | indices: 367 | '.opendistro-alerting-alerts': 368 | '*': 369 | - CRUD 370 | 371 | # Create, update, and delete monitors and destinations for Open Distro for Elasticsearch Alerting 372 | alerting_monitors: 373 | readonly: true 374 | indices: 375 | '.opendistro-alerting-config': 376 | '*': 377 | - CRUD 378 | 379 | # Read only for Open Distro for Elasticsearch Alerting 380 | alerting_read_only: 381 | readonly: true 382 | indices: 383 | '.opendistro-alerting-config': 384 | '*': 385 | - READ 386 | '.opendistro-alerting-alerts': 387 | '*': 388 | - READ 389 | 390 | # Allows each user to access own named index 391 | own_index: 392 | cluster: 393 | - CLUSTER_COMPOSITE_OPS 394 | indices: 395 | '${user_name}': 396 | '*': 397 | - INDICES_ALL 398 | 399 | roles_mapping.yml: |- 400 | curator: 401 | readonly: true 402 | users: 403 | - curator 404 | prometheus: 405 | readonly: true 406 | users: 407 | - prometheus 408 | spanread: 409 | readonly: true 410 | users: 411 | - span-read 412 | spanwrite: 413 | readonly: true 414 | users: 415 | - span-write 416 | all_access: 417 | readonly: true 418 | users: 419 | - curator 420 | {{ toYaml .Values.opendistro_security.admins | indent 8 }} 421 | backendroles: 422 | - admin 423 | logwrite: 424 | users: 425 | - logwrite 426 | kibana_server: 427 | readonly: true 428 | users: 429 | - kibana 430 | kibana_user: 431 | users: 432 | {{ toYaml .Values.opendistro_security.users | indent 8 }} 433 | alerting_acknowledge: 434 | users: 435 | {{ toYaml .Values.opendistro_security.users | indent 8 }} 436 | alerting_monitors: 437 | users: 438 | {{ toYaml .Values.opendistro_security.users | indent 8 }} 439 | logreader: 440 | users: 441 | {{ toYaml .Values.opendistro_security.users | indent 8 }} 442 | backendroles: 443 | - kibanauser 444 | readall: 445 | readonly: true 446 | backendroles: 447 | - readall 448 | manage_snapshots: 449 | readonly: true 450 | backendroles: 451 | - snapshotrestore 452 | own_index: 453 | users: 454 | - '*' 455 | 456 | internal_users.yml: |- 457 | # This is the internal user database 458 | # The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh 459 | {} 460 | {{- end -}} 461 | -------------------------------------------------------------------------------- /templates/securityinit-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable }} 2 | {{- if .Values.rbac.create -}} 3 | apiVersion: rbac.authorization.k8s.io/v1beta1 4 | kind: ClusterRole 5 | metadata: 6 | labels: 7 | app: {{ template "fullname" . }} 8 | component: securityinit 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | name: {{ template "fullname" . }}-securityinit 13 | rules: 14 | - apiGroups: 15 | - certificates.k8s.io 16 | resources: 17 | - certificatesigningrequests 18 | verbs: 19 | - create 20 | - get 21 | - delete 22 | {{- end -}} 23 | {{- end -}} 24 | -------------------------------------------------------------------------------- /templates/securityinit-clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" .}} 7 | component: securityinit 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-securityinit 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: {{ template "fullname" . }}-securityinit 16 | subjects: 17 | - kind: ServiceAccount 18 | name: {{ template "fullname" . }}-securityinit 19 | namespace: {{ .Release.Namespace }} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /templates/securityinit-job.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable }} 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: {{ template "fullname" . }}-securityinit 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | activeDeadlineSeconds: {{ default 600 .Values.opendistro_security.init.activeDeadlineSeconds }} 13 | template: 14 | metadata: 15 | labels: 16 | app: {{ template "fullname" . }} 17 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 18 | release: "{{ .Release.Name }}" 19 | heritage: "{{ .Release.Service }}" 20 | spec: 21 | serviceAccountName: "{{ template "fullname" . }}-securityinit" 22 | subdomain: "{{ template "fullname" . }}" 23 | initContainers: 24 | - name: generate-tls-pair 25 | image: "{{ .Values.tls.image }}:{{ .Values.tls.imageTag }}" 26 | imagePullPolicy: {{ .Values.tls.imagePullPolicy }} 27 | env: 28 | - name: NAMESPACE 29 | valueFrom: 30 | fieldRef: 31 | fieldPath: metadata.namespace 32 | - name: POD_NAME 33 | valueFrom: 34 | fieldRef: 35 | fieldPath: metadata.name 36 | - name: SUBDOMAIN 37 | value: {{ template "fullname" . }} 38 | - name: POD_IP 39 | valueFrom: 40 | fieldRef: 41 | fieldPath: status.podIP 42 | args: 43 | - "-namespace=$(NAMESPACE)" 44 | - "-pod-ip=$(POD_IP)" 45 | - "-pod-name=$(POD_NAME)" 46 | - "-hostname=admin" 47 | - "-subdomain=$(SUBDOMAIN)" 48 | - "-organizational-units=securityadmin" 49 | - "-organizations=logging" 50 | - "-headless-name-as-cn" 51 | - "-pkcs8" 52 | - "-labels=component={{ template "fullname" . }}" 53 | - "-secret-name={{ template "fullname" . }}-securityadmin-credentials" 54 | - name: wait-for-es 55 | image: alpine 56 | imagePullPolicy: IfNotPresent 57 | command: 58 | - "sh" 59 | - "-c" 60 | - "until nc -w 1 -z {{ template "fullname" . }} 9300; do echo waiting for elasticsearch to come up; sleep 2; done" 61 | containers: 62 | - name: securityinit 63 | image: "{{ .Values.opendistro_security.init.image }}:{{ .Values.opendistro_security.init.imageTag }}" 64 | imagePullPolicy: "Always" 65 | args: 66 | - "--configdir" 67 | - "/securityconfig/" 68 | - "-cacert" 69 | - "/tls/ca.crt" 70 | - "--clustername" 71 | - "{{ .Values.common.env.CLUSTER_NAME }}" 72 | - "--hostname" 73 | - "{{ template "fullname" . }}-discovery.{{ .Release.Namespace }}.svc.{{ .Values.tls.clusterDomain }}" 74 | - "-cert" 75 | - "/tls/tls.crt" 76 | - "-key" 77 | - "/tls/tls.key" 78 | volumeMounts: 79 | - name: tls 80 | mountPath: /tls 81 | - name: security-config 82 | mountPath: /securityconfig 83 | volumes: 84 | - name: tls 85 | secret: 86 | secretName: {{ template "fullname" . }}-securityadmin-credentials 87 | defaultMode: 0400 88 | - name: security-config 89 | configMap: 90 | name: {{ template "fullname" . }}-security-config 91 | restartPolicy: {{ .Values.opendistro_security.init.restartPolicy }} 92 | {{- end }} 93 | -------------------------------------------------------------------------------- /templates/securityinit-role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable }} 2 | {{- if .Values.rbac.create -}} 3 | apiVersion: rbac.authorization.k8s.io/v1beta1 4 | kind: Role 5 | metadata: 6 | labels: 7 | app: {{ template "fullname" . }} 8 | component: securityinit 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | name: {{ template "fullname" . }}-securityinit 13 | namespace: {{ .Release.Namespace }} 14 | rules: 15 | - apiGroups: [""] 16 | resources: 17 | - secrets 18 | resourceNames: 19 | - "{{ template "fullname" . }}-securityadmin-credentials" 20 | verbs: 21 | - update 22 | - get 23 | {{- end -}} 24 | {{- end -}} 25 | 26 | -------------------------------------------------------------------------------- /templates/securityinit-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable -}} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: RoleBinding 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" .}} 7 | component: securityinit 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-securityinit 12 | namespace: {{ .Release.Namespace }} 13 | roleRef: 14 | apiGroup: rbac.authorization.k8s.io 15 | kind: Role 16 | name: {{ template "fullname" . }}-securityinit 17 | subjects: 18 | - kind: ServiceAccount 19 | name: {{ template "fullname" . }}-securityinit 20 | namespace: {{ .Release.Namespace }} 21 | {{- end -}} 22 | -------------------------------------------------------------------------------- /templates/securityinit-secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.opendistro_security.enable }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | component: securityinit 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | heritage: "{{ .Release.Service }}" 10 | release: "{{ .Release.Name }}" 11 | name: {{ template "fullname" . }}-securityadmin-credentials 12 | namespace: {{ .Release.Namespace }} 13 | type: tls 14 | data: 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /templates/securityinit-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.opendistro_security.enable }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | labels: 6 | app: {{ template "fullname" . }} 7 | component: securityinit 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "fullname" . }}-securityinit 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: {{ template "fullname" . }} 6 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 7 | heritage: {{ .Release.Service }} 8 | release: {{ .Release.Name }} 9 | name: {{ template "fullname" . }} 10 | -------------------------------------------------------------------------------- /values.yaml: -------------------------------------------------------------------------------- 1 | microk8s: false 2 | common: 3 | image: 4 | repository: blacktop/elasticsearch 5 | tag: "6.6.1" 6 | pullPolicy: IfNotPresent 7 | 8 | # Defines the service type for all outward-facing (non-discovery) services. 9 | serviceType: ClusterIP 10 | # Any extra or specific configuration that is needed can be added here. 11 | config: 12 | index.codec: best_compression 13 | # If you want any plugins installed, give them here as a list. They will be 14 | # passed to elasticsearch-plugin install {line here} 15 | plugins: 16 | # You need to enable this plugin if you want to use the TLS option at the bottom 17 | # - com.floragunn:search-guard-ssl:6.0.0-24.beta1.1 18 | 19 | env: 20 | # Uncomment this if you get the "No up-and-running site-local (private) 21 | # addresses" error. 22 | # NETWORK_HOST: "_eth0_" 23 | # The minimum number of masters that will be able to form a quorum. This 24 | # should be (#masters / 2) + 1. Default is 2. 25 | NUMBER_OF_MASTERS: "2" 26 | 27 | # Client/ingest nodes can execute pre-processing pipelines, composed of 28 | # one or more ingest processors. Depending on the type of operations performed 29 | # by the ingest processors and the required resources, it may make sense to 30 | # have dedicated ingest nodes, that will only perform this specific task. 31 | client: 32 | # It isn't common to need more than 2 client nodes. 33 | replicas: 2 34 | antiAffinity: "soft" 35 | heapSize: 256m 36 | # More info on what this setting does is in the config map. Only change this 37 | # if you set the cpu limit to over 1 full cpu. 38 | processors: 1 39 | labels: 40 | annotations: 41 | resources: 42 | limits: 43 | cpu: 500m 44 | memory: 384Mi 45 | requests: 46 | cpu: 100m 47 | memory: 256Mi 48 | 49 | # Data nodes hold the shards that contain the documents you have indexed. Data 50 | # nodes handle data related operations like CRUD, search, and aggregations. 51 | # These operations are I/O-, memory-, and CPU-intensive. It is important to 52 | # monitor these resources and to add more data nodes if they are overloaded. 53 | # 54 | # The main benefit of having dedicated data nodes is the separation of the 55 | # master and data roles. 56 | data: 57 | # This count will depend on your data and computation needs. 58 | replicas: 2 59 | antiAffinity: "soft" 60 | storage: 12Gi 61 | storageClass: "default" 62 | heapSize: 256m 63 | enableHTTP: false 64 | # More info on what this setting does is in the config map. Only change this 65 | # if you set the cpu limit to over 1 full cpu. 66 | processors: 1 67 | labels: 68 | annotations: 69 | resources: 70 | limits: 71 | cpu: 500m 72 | memory: 384Mi 73 | requests: 74 | cpu: 100m 75 | memory: 256Mi 76 | 77 | # The master node is responsible for lightweight cluster-wide actions such as 78 | # creating or deleting an index, tracking which nodes are part of the 79 | # cluster, and deciding which shards to allocate to which nodes. It is 80 | # important for cluster health to have a stable master node. 81 | master: 82 | # Master replica count should be (#clients / 2) + 1, and generally at least 3. 83 | replicas: 3 84 | antiAffinity: "soft" 85 | storage: 2Gi 86 | storageClass: "default" 87 | heapSize: 256m 88 | enableHTTP: false 89 | # More info on what this setting does is in the config map. Only change this 90 | # if you set the cpu limit to over 1 full cpu. 91 | processors: 1 92 | labels: 93 | annotations: 94 | resources: 95 | limits: 96 | cpu: 500m 97 | memory: 384Mi 98 | requests: 99 | cpu: 100m 100 | memory: 256Mi 101 | 102 | curator: 103 | enable: true 104 | schedule: "0 1 * * *" 105 | image: quay.io/lalamove/elasticsearch-curator 106 | imageTag: "5.4.0" 107 | imagePullPolicy: "IfNotPresent" 108 | # Allows modification of the default age-based filter. If you require more 109 | # sophisticated filtering, modify the action file specified in 110 | # templates/es-curator-config.yaml. 111 | age: 112 | timestring: "%Y.%m.%d" 113 | unit: "days" 114 | unit_count: 3 115 | 116 | service: 117 | httpPort: 9200 118 | transportPort: 9300 119 | 120 | rbac: 121 | create: true 122 | 123 | tls: 124 | enable: false 125 | clusterDomain: cluster.local 126 | image: quay.io/lalamove/certificate-init-container 127 | imageTag: v0.2.0 128 | imagePullPolicy: "IfNotPresent" 129 | 130 | opendistro_security: 131 | # If you enable opendistro_security, you must enable TLS as well, and pay close attention to the instructions after install 132 | enable: false 133 | advanced_modules_enabled: false 134 | kibana_user: kibana 135 | admins: 136 | users: 137 | init: 138 | image: quay.io/lalamove/securityadmin 139 | imageTag: v6.6.1-24.1 140 | imagePullPolicy: "IfNotPresent" 141 | restartPolicy: Never 142 | activeDeadlineSeconds: 600 143 | --------------------------------------------------------------------------------