diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..deb5a7f7 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + \ No newline at end of file diff --git a/charts/opensearch/Chart.yaml b/charts/opensearch/Chart.yaml index a46d3189..54242ed9 100644 --- a/charts/opensearch/Chart.yaml +++ b/charts/opensearch/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.17.0 +version: 2.17.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/opensearch/templates/_helpers.tpl b/charts/opensearch/templates/_helpers.tpl index f7dc47d0..bda91eeb 100755 --- a/charts/opensearch/templates/_helpers.tpl +++ b/charts/opensearch/templates/_helpers.tpl @@ -87,8 +87,8 @@ app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} {{- define "opensearch.endpoints" -}} -{{- $replicas := int (toString (.Values.replicas)) }} -{{- $uname := (include "opensearch.uname" .) }} +{{- $replicas := int (toString (.Values.master.replicas)) }} +{{- $uname := .Values.master.name }} {{- range $i, $e := untilStep 0 $replicas 1 -}} {{ $uname }}-{{ $i }}, {{- end -}} @@ -98,7 +98,7 @@ app.kubernetes.io/instance: {{ .Release.Name }} {{- if .Values.majorVersion }} {{- .Values.majorVersion }} {{- else }} - {{- $version := semver (coalesce .Values.image.tag .Chart.AppVersion "1") }} + {{- $version := semver (coalesce .Values.master.image.tag .Chart.AppVersion "1") }} {{- $version.Major }} {{- end }} {{- end }} @@ -111,8 +111,14 @@ app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} {{- end -}} -{{- define "opensearch.roles" -}} -{{- range $.Values.roles -}} +{{- define "opensearch.master.roles" -}} +{{- range $.Values.master.roles -}} +{{ . }}, +{{- end -}} +{{- end -}} + +{{- define "opensearch.data.roles" -}} +{{- range $.Values.data.roles -}} {{ . }}, {{- end -}} {{- end -}} diff --git a/charts/opensearch/templates/configmap.yaml b/charts/opensearch/templates/dataConfigmap.yaml similarity index 58% rename from charts/opensearch/templates/configmap.yaml rename to charts/opensearch/templates/dataConfigmap.yaml index 4f2961be..a0c83577 100644 --- a/charts/opensearch/templates/configmap.yaml +++ b/charts/opensearch/templates/dataConfigmap.yaml @@ -1,13 +1,15 @@ {{- $root := . }} -{{- if .Values.config }} +{{- if .Values.data.config }} apiVersion: v1 kind: ConfigMap metadata: - name: {{ template "opensearch.uname" . }}-config + name: {{ .Values.data.name }}-config labels: - {{- include "opensearch.labels" . | nindent 4 }} + {{- with .Values.data.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} data: -{{- range $configName, $configYaml := .Values.config }} +{{- range $configName, $configYaml := .Values.data.config }} {{ $configName }}: | {{- if (eq (kindOf $configYaml) "map")}} {{- tpl (toYaml $configYaml) $root | nindent 4 }} diff --git a/charts/opensearch/templates/dataPoddisruptionbudget.yaml b/charts/opensearch/templates/dataPoddisruptionbudget.yaml new file mode 100644 index 00000000..758c5f50 --- /dev/null +++ b/charts/opensearch/templates/dataPoddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Values.data.maxUnavailable }} +{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: "{{ .Values.data.name }}-pdb" + labels: + {{- with .Values.data.labels }} +{{- toYaml . | nindent 4 }} + {{- end }} +spec: + maxUnavailable: {{ .Values.data.maxUnavailable }} + selector: + matchLabels: + {{- with .Values.data.selectorLabels }} +{{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/opensearch/templates/dataService.yaml b/charts/opensearch/templates/dataService.yaml new file mode 100644 index 00000000..bd18db16 --- /dev/null +++ b/charts/opensearch/templates/dataService.yaml @@ -0,0 +1,80 @@ +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ .Values.data.serviceName }} + labels: +{{- with .Values.data.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} +{{- if .Values.data.service.labels }} +{{ toYaml .Values.data.service.labels | indent 4 }} +{{- end }} + annotations: +{{ toYaml .Values.data.service.annotations | indent 4 }} +spec: + type: {{ .Values.data.service.type }} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.data.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.data.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.data.service.ipFamilies }} + ipFamilies: {{ .Values.data.service.ipFamilies }} + {{- end }} + {{- end }} + selector: + {{- with .Values.data.selectorLabels }} +{{- toYaml . | nindent 4 }} + {{- end }} + ports: + - name: {{ .Values.data.service.httpPortName | default "http" }} + protocol: TCP + port: {{ .Values.data.httpPort }} +{{- if .Values.data.service.nodePort }} + nodePort: {{ .Values.data.service.nodePort }} +{{- end }} + - name: {{ .Values.data.service.transportPortName | default "transport" }} + protocol: TCP + port: {{ .Values.data.transportPort }} +{{- if .Values.data.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.data.service.loadBalancerIP }} +{{- end }} +{{- with .Values.data.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if .Values.data.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.data.service.externalTrafficPolicy }} +{{- end }} +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ .Values.data.serviceName }}-headless + labels: +{{- with .Values.data.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} +{{- if .Values.data.service.labelsHeadless }} +{{ toYaml .Values.data.service.labelsHeadless | indent 4 }} +{{- end }} + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +{{- if .Values.data.service.headless.annotations }} +{{ toYaml .Values.data.service.headless.annotations | indent 4 }} +{{- end }} +spec: + clusterIP: None # This is needed for statefulset hostnames like opensearch-0 to resolve + # Create endpoints also if the related pod isn't ready + publishNotReadyAddresses: true + selector: + {{- with .Values.data.selectorLabels }} +{{- toYaml . | nindent 4 }} + {{- end }} + ports: + - name: {{ .Values.data.service.httpPortName | default "http" }} + port: {{ .Values.data.httpPort }} + - name: {{ .Values.data.service.transportPortName | default "transport" }} + port: {{ .Values.data.transportPort }} + - name: {{ .Values.data.service.metricsPortName | default "metrics" }} + port: {{ .Values.data.metricsPort }} diff --git a/charts/opensearch/templates/dataStatefulset .yaml b/charts/opensearch/templates/dataStatefulset .yaml new file mode 100644 index 00000000..99bdb20e --- /dev/null +++ b/charts/opensearch/templates/dataStatefulset .yaml @@ -0,0 +1,556 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Values.data.name }} + labels: + {{- with .Values.data.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + majorVersion: "{{ include "opensearch.majorVersion" . }}" + {{- with .Values.data.openSearchAnnotations }} +{{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceName: {{ .Values.data.serviceName }}-headless + selector: + matchLabels: + {{- with .Values.data.selectorLabels }} +{{- toYaml . | nindent 6 }} + {{- end }} + {{- if .Values.data.singleNode }} + replicas: 1 + {{- else }} + replicas: {{ .Values.data.replicas }} + {{- end }} + podManagementPolicy: {{ .Values.data.podManagementPolicy }} + updateStrategy: + type: {{ .Values.data.updateStrategy }} + {{- if .Values.data.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: {{ .Values.data.name }} + {{- if .Values.data.persistence.labels.enabled }} + labels: + {{- with .Values.data.labels }} +{{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.data.persistence.annotations }} + annotations: +{{ toYaml . | indent 8 }} + {{- end }} + spec: + accessModes: + {{- range .Values.data.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.data.persistence.size | quote }} + {{- if .Values.data.persistence.storageClass }} + {{- if (eq "-" .Values.data.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.data.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- end }} + template: + metadata: + name: "{{ .Values.data.name }}" + labels: + {{- with .Values.data.labels }} +{{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- range $key, $value := .Values.data.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- /* This forces a restart if the configmap has changed */}} + {{- if .Values.data.config }} + configchecksum: {{ include (print .Template.BasePath "/dataConfigmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + {{- if .Values.data.securityConfig.config.data }} + securityconfigchecksum: {{ include (print .Template.BasePath "/securityconfig.yaml") . | sha256sum | trunc 63 }} + {{- end }} + spec: + {{- if .Values.data.schedulerName }} + schedulerName: "{{ .Values.data.schedulerName }}" + {{- end }} + securityContext: +{{ toYaml .Values.data.podSecurityContext | indent 8 }} + {{- if .Values.data.sysctl.enabled }} + sysctls: + - name: vm.max_map_count + value: {{ .Values.data.sysctlVmMaxMapCount | quote }} + {{- end }} + {{- if .Values.data.fsGroup }} + fsGroup: {{ .Values.data.fsGroup }} # Deprecated value, please use .Values.podSecurityContext.fsGroup + {{- end }} + {{- if and .Values.rbac.create (eq .Values.rbac.serviceAccountName "") }} + serviceAccountName: "{{ template "opensearch.uname" . }}" + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- else if and .Values.rbac.create (ne .Values.rbac.serviceAccountName "") }} + serviceAccountName: {{ .Values.rbac.serviceAccountName | quote }} + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- else }} + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- end }} + {{- if .Values.master.imagePullSecrets }} + {{- end }} + {{- with .Values.master.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.data.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if or (eq .Values.data.antiAffinity "hard") (eq .Values.data.antiAffinity "soft") .Values.master.nodeAffinity }} + {{- if .Values.data.priorityClassName }} + priorityClassName: {{ .Values.data.priorityClassName }} + {{- end }} + affinity: + {{- end }} + {{- if eq .Values.data.antiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/name + operator: In + values: + - {{ include "opensearch.name" . }} + topologyKey: {{ .Values.data.antiAffinityTopologyKey }} + {{- else if eq .Values.data.antiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: {{ .Values.data.antiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/name + operator: In + values: + - {{ .Values.data.name }} + {{- end }} + {{- with .Values.data.nodeAffinity }} + nodeAffinity: +{{ toYaml . | indent 10 }} + {{- end }} + {{- if .Values.data.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml .Values.data.topologySpreadConstraints | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.data.terminationGracePeriod }} + volumes: + {{- range .Values.data.secretMounts }} + - name: {{ .name | required "secretMount .name is required" }} + secret: + secretName: {{ .secretName | required "secretMount .secretName is required" }} + {{- if .defaultMode }} + defaultMode: {{ .defaultMode }} + {{- end }} + {{- end }} + {{- if .Values.data.config }} + - name: config + configMap: + name: {{ .Values.data.name }}-config + {{- end }} + {{- if and .Values.data.securityConfig.config.data .Values.data.securityConfig.config.securityConfigSecret }} + {{ fail "Only one of .Values.securityConfig.config.data and .Values.securityConfig.config.securityConfigSecret may be defined. Please see the comment in values.yaml describing usage." }} + {{- end }} + {{- if .Values.data.securityConfig.config.data }} + - name: security-config-data + secret: + secretName: {{ .Values.data.name }}-securityconfig + {{- end }} + {{- with .Values.data.securityConfig.config.securityConfigSecret }} + - name: security-config-complete + secret: + secretName: {{ . | quote }} + {{- end }} + {{- if .Values.data.securityConfig.actionGroupsSecret }} + - name: action-groups + secret: + secretName: {{ .Values.data.securityConfig.actionGroupsSecret }} + {{- end }} + {{- if .Values.master.securityConfig.configSecret }} + - name: security-config + secret: + secretName: {{ .Values.data.securityConfig.configSecret }} + {{- end }} + {{- if .Values.data.securityConfig.internalUsersSecret }} + - name: internal-users-config + secret: + secretName: {{ .Values.data.securityConfig.internalUsersSecret }} + {{- end }} + {{- if .Values.data.securityConfig.rolesSecret }} + - name: roles + secret: + secretName: {{ .Values.data.securityConfig.rolesSecret }} + {{- end }} + {{- if .Values.data.securityConfig.rolesMappingSecret }} + - name: role-mapping + secret: + secretName: {{ .Values.data.securityConfig.rolesMappingSecret }} + {{- end -}} + {{- if .Values.data.securityConfig.tenantsSecret }} + - name: tenants + secret: + secretName: {{ .Values.data.securityConfig.tenantsSecret }} + {{- end }} +{{- if .Values.data.keystore }} + - name: keystore + emptyDir: {} + {{- range .Values.data.keystore }} + - name: keystore-{{ .secretName }} + secret: {{ toYaml . | nindent 12 }} + {{- end }} +{{ end }} + {{- if .Values.data.extraVolumes }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.data.extraVolumes) }} +{{ tpl .Values.data.extraVolumes . | indent 6 }} + {{- else }} +{{ toYaml .Values.data.extraVolumes | indent 6 }} + {{- end }} + {{- end }} + {{- if .Values.data.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.data.imagePullSecrets | indent 8 }} + {{- end }} + enableServiceLinks: {{ .Values.data.enableServiceLinks }} + {{- if .Values.data.hostAliases }} + hostAliases: {{ toYaml .Values.data.hostAliases | nindent 8 }} + {{- end }} + {{- if or (.Values.data.extraInitContainers) (.Values.data.keystore) (.Values.data.persistence.enabled) (.Values.data.sysctlInit.enabled) }} + initContainers: +{{- if and .Values.data.persistence.enabled .Values.data.persistence.enableInitChown }} + - name: fsgroup-volume + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.data.persistence.image | default "busybox" }}:{{ .Values.data.persistence.imageTag | default "latest" }}" + imagePullPolicy: "{{ .Values.data.image.pullPolicy }}" + command: ['sh', '-c'] + args: + - 'chown -R 1000:1000 /usr/share/opensearch/data' + securityContext: + runAsUser: 0 + resources: + {{- toYaml .Values.data.initResources | nindent 10 }} + volumeMounts: + - name: "{{ .Values.data.name }}" + mountPath: {{ .Values.data.opensearchHome }}/data +{{- end }} +{{- if .Values.data.sysctlInit.enabled }} + - name: sysctl + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.data.sysctlInit.image | default "busybox" }}:{{ .Values.data.sysctlInit.imageTag | default "latest" }}" + imagePullPolicy: "{{ .Values.data.image.pullPolicy }}" + command: + - sh + - -c + - | + set -xe + DESIRED="{{ .Values.data.sysctlVmMaxMapCount }}" + CURRENT=$(sysctl -n vm.max_map_count) + if [ "$DESIRED" -gt "$CURRENT" ]; then + sysctl -w vm.max_map_count=$DESIRED + fi + securityContext: + runAsUser: 0 + privileged: true + resources: + {{- toYaml .Values.data.initResources | nindent 10 }} +{{- end }} +{{- if .Values.data.keystore }} + - name: keystore + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.data.image.repository }}:{{ .Values.data.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.data.image.pullPolicy }}" + command: + - sh + - -c + - | + #!/usr/bin/env bash + set -euo pipefail + + {{ .Values.data.opensearchHome }}/bin/opensearch-keystore create + + for i in /tmp/keystoreSecrets/*/*; do + [ -f "$i" ] || continue + key=$(basename $i) + echo "Adding file $i to keystore key $key" + {{ .Values.data.opensearchHome }}/bin/opensearch-keystore add-file "$key" "$i" + done + + # Add the bootstrap password since otherwise the opensearch entrypoint tries to do this on startup + if [ ! -z ${PASSWORD+x} ]; then + echo 'Adding env $PASSWORD to keystore as key bootstrap.password' + echo "$PASSWORD" | {{ .Values.data.opensearchHome }}/bin/opensearch-keystore add -x bootstrap.password + fi + + cp -a {{ .Values.data.opensearchHome }}/config/opensearch.keystore /tmp/keystore/ + env: {{ toYaml .Values.data.extraEnvs | nindent 10 }} + envFrom: {{ toYaml .Values.data.envFrom | nindent 10 }} + resources: + {{- toYaml .Values.data.initResources | nindent 10 }} + volumeMounts: + - name: keystore + mountPath: /tmp/keystore + {{- range .Values.data.keystore }} + - name: keystore-{{ .secretName }} + mountPath: /tmp/keystoreSecrets/{{ .secretName }} + {{- end }} +{{- end }} + {{- if .Values.data.extraInitContainers }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.master.extraInitContainers) }} +{{ tpl .Values.data.extraInitContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.data.extraInitContainers | indent 6 }} + {{- end }} + {{- end }} + {{- end }} + containers: + - name: "{{ .Values.data.name }}" + securityContext: +{{ toYaml .Values.data.securityContext | indent 10 }} + {{- if .Values.data.plugins.enabled }} + command: + - sh + - -c + - | + #!/usr/bin/env bash + set -euo pipefail + + {{- range $plugin := .Values.data.plugins.installList }} + ./bin/opensearch-plugin install -b {{ $plugin }} + {{- end }} + + bash opensearch-docker-entrypoint.sh + {{- end }} + + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.data.image.repository }}:{{ .Values.data.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.data.image.pullPolicy }}" + readinessProbe: +{{ toYaml .Values.data.readinessProbe | indent 10 }} + {{- if .Values.data.livenessProbe }} + livenessProbe: +{{ toYaml .Values.data.livenessProbe | indent 10 }} + {{- end }} + {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.Version }} + startupProbe: +{{ toYaml .Values.data.startupProbe | indent 10 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.data.httpPort }} + {{- if .Values.data.httpHostPort }} + hostPort: {{ .Values.data.httpHostPort }} + {{- end }} + - name: transport + containerPort: {{ .Values.data.transportPort }} + {{- if .Values.data.transportHostPort }} + hostPort: {{ .Values.data.transportHostPort }} + {{- end }} + - name: metrics + containerPort: {{ .Values.data.metricsPort }} + resources: + {{- toYaml .Values.data.resources | nindent 10 }} + env: + - name: node.name + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if (and (has "master" .Values.data.roles) (not .Values.data.singleNode)) }} + - name: cluster.initial_master_nodes + value: "{{ template "opensearch.endpoints" . }}" + {{- end }} + - name: discovery.seed_hosts + value: "{{ .Values.data.serviceName }}-headless" + - name: cluster.name + value: "{{ .Values.data.clusterName }}" + - name: network.host + value: "{{ .Values.data.networkHost }}" + - name: OPENSEARCH_JAVA_OPTS + value: "{{ .Values.data.opensearchJavaOpts }}" + - name: node.roles + value: "{{ template "opensearch.data.roles" . }}" + {{- if .Values.data.singleNode }} + - name: discovery.type + value: "single-node" + {{- end }} +{{- if .Values.data.extraEnvs }} +{{ toYaml .Values.data.extraEnvs | indent 8 }} +{{- end }} +{{- if .Values.data.envFrom }} + envFrom: +{{ toYaml .Values.data.envFrom | indent 8 }} +{{- end }} +{{- if .Values.data.opensearchLifecycle }} + lifecycle: +{{ toYaml .Values.data.opensearchLifecycle | indent 10 }} +{{- end }} + volumeMounts: + {{- if .Values.data.persistence.enabled }} + - name: "{{ .Values.data.name }}" + mountPath: {{ .Values.data.opensearchHome }}/data + {{- end }} + {{- if .Values.data.keystore }} + - name: keystore + mountPath: {{ .Values.data.opensearchHome }}/config/opensearch.keystore + subPath: opensearch.keystore + {{- end }} + {{- if .Values.data.securityConfig.enabled }} + {{- if .Values.data.securityConfig.actionGroupsSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/action_groups.yml + name: action-groups + subPath: action_groups.yml + {{- end }} + {{- if .Values.data.securityConfig.configSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/config.yml + name: security-config + subPath: config.yml + {{- end }} + {{- if .Values.data.securityConfig.internalUsersSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/internal_users.yml + name: internal-users-config + subPath: internal_users.yml + {{- end }} + {{- if .Values.securityConfig.rolesSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/roles.yml + name: roles + subPath: roles.yml + {{- end }} + {{- if .Values.data.securityConfig.rolesMappingSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/roles_mapping.yml + name: role-mapping + subPath: roles_mapping.yml + {{- end }} + {{- if .Values.data.securityConfig.tenantsSecret }} + - mountPath: {{ .Values.data.securityConfig.path }}/tenants.yml + name: tenants + subPath: tenants.yml + {{- end }} + {{- if .Values.data.securityConfig.config.data }} + {{- if .Values.data.securityConfig.config.dataComplete }} + - mountPath: {{ .Values.data.securityConfig.path }} + name: security-config-data + {{- else }} + {{- range $key, $_ := .Values.data.securityConfig.config.data }} + - mountPath: {{ $.Values.data.securityConfig.path }}/{{ $key }} + name: security-config-data + subPath: {{ $key }} + {{- end }} + {{- end }} + {{- else if .Values.data.securityConfig.config.securityConfigSecret }} + - mountPath: {{ .Values.data.securityConfig.path }} + name: security-config-complete + {{- end }} + {{- end }} + {{- range .Values.data.secretMounts }} + - name: {{ .name | required "secretMount .name is required" }} + mountPath: {{ .path | required "secretMount .path is required" }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.data.config }} + - name: config + mountPath: {{ $.Values.data.opensearchHome }}/config/{{ $path }} + subPath: {{ $path }} + {{- end -}} + {{- if .Values.data.extraVolumeMounts }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.data.extraVolumeMounts) }} +{{ tpl .Values.data.extraVolumeMounts . | indent 8 }} + {{- else }} +{{ toYaml .Values.data.extraVolumeMounts | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.data.masterTerminationFix }} + {{- if has "master" .Values.data.roles }} + # This sidecar will prevent slow master re-election + - name: opensearch-master-graceful-termination-handler + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.data.image.repository }}:{{ .Values.data.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.data.image.pullPolicy }}" + command: + - "sh" + - -c + - | + #!/usr/bin/env bash + set -eo pipefail + + http () { + local path="${1}" + if [ -n "${USERNAME}" ] && [ -n "${PASSWORD}" ]; then + BASIC_AUTH="-u ${USERNAME}:${PASSWORD}" + else + BASIC_AUTH='' + fi + curl -XGET -s -k --fail ${BASIC_AUTH} {{ .Values.data.protocol }}://{{ template "opensearch.masterService" . }}:{{ .Values.data.httpPort }}${path} + } + + cleanup () { + while true ; do + local master="$(http "/_cat/master?h=node" || echo "")" + if [[ $master == "{{ template "opensearch.masterService" . }}"* && $master != "${NODE_NAME}" ]]; then + echo "This node is not master." + break + fi + echo "This node is still master, waiting gracefully for it to step down" + sleep 1 + done + + exit 0 + } + + trap cleanup SIGTERM + + sleep infinity & + wait $! + resources: + {{- toYaml .Values.data.sidecarResources | nindent 10 }} + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if .Values.data.extraEnvs }} +{{ toYaml .Values.data.extraEnvs | indent 8 }} + {{- end }} + {{- if .Values.data.envFrom }} + envFrom: +{{ toYaml .Values.data.envFrom | indent 8 }} + {{- end }} + {{- end }} + {{- end }} +{{- if .Values.data.lifecycle }} + lifecycle: +{{ toYaml .Values.data.lifecycle | indent 10 }} +{{- end }} + {{- if .Values.data.extraContainers }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.data.extraContainers) }} +{{ tpl .Values.data.extraContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.data.extraContainers | indent 6 }} + {{- end }} + {{- end }} diff --git a/charts/opensearch/templates/extraManifests.yaml b/charts/opensearch/templates/extraManifests.yaml index d6abe5fb..2a07cad8 100644 --- a/charts/opensearch/templates/extraManifests.yaml +++ b/charts/opensearch/templates/extraManifests.yaml @@ -5,4 +5,4 @@ {{- else }} {{- tpl (toYaml .) $ }} {{- end }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/charts/opensearch/templates/masterConfigmap.yaml b/charts/opensearch/templates/masterConfigmap.yaml new file mode 100644 index 00000000..d5843db4 --- /dev/null +++ b/charts/opensearch/templates/masterConfigmap.yaml @@ -0,0 +1,20 @@ +{{- $root := . }} +{{- if .Values.master.config }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.master.name }}-config + labels: + {{- with .Values.master.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: +{{- range $configName, $configYaml := .Values.master.config }} + {{ $configName }}: | + {{- if (eq (kindOf $configYaml) "map")}} + {{- tpl (toYaml $configYaml) $root | nindent 4 }} + {{- else -}} + {{- tpl $configYaml $root | nindent 4 }} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/opensearch/templates/masterPoddisruptionbudget.yaml b/charts/opensearch/templates/masterPoddisruptionbudget.yaml new file mode 100644 index 00000000..0eb18b6f --- /dev/null +++ b/charts/opensearch/templates/masterPoddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Values.master.maxUnavailable }} +{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: "{{ .Values.master.name }}-pdb" + labels: + {{- with .Values.master.labels }} +{{- toYaml . | nindent 4 }} + {{- end }} +spec: + maxUnavailable: {{ .Values.data.maxUnavailable }} + selector: + matchLabels: + {{- with .Values.master.selectorLabels }} +{{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/opensearch/templates/masterService.yaml b/charts/opensearch/templates/masterService.yaml new file mode 100644 index 00000000..ddc43aa6 --- /dev/null +++ b/charts/opensearch/templates/masterService.yaml @@ -0,0 +1,80 @@ +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ .Values.master.serviceName }} + labels: +{{- with .Values.master.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} +{{- if .Values.master.service.labels }} +{{ toYaml .Values.master.service.labels | indent 4 }} +{{- end }} + annotations: +{{ toYaml .Values.master.service.annotations | indent 4 }} +spec: + type: {{ .Values.master.service.type }} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.master.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.master.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.master.service.ipFamilies }} + ipFamilies: {{ .Values.master.service.ipFamilies }} + {{- end }} + {{- end }} + selector: + {{- with .Values.master.selectorLabels }} +{{- toYaml . | nindent 4 }} + {{- end }} + ports: + - name: {{ .Values.master.service.httpPortName | default "http" }} + protocol: TCP + port: {{ .Values.master.httpPort }} +{{- if .Values.master.service.nodePort }} + nodePort: {{ .Values.master.service.nodePort }} +{{- end }} + - name: {{ .Values.master.service.transportPortName | default "transport" }} + protocol: TCP + port: {{ .Values.master.transportPort }} +{{- if .Values.master.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.master.service.loadBalancerIP }} +{{- end }} +{{- with .Values.master.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if .Values.master.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.master.service.externalTrafficPolicy }} +{{- end }} +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ .Values.master.serviceName }}-headless + labels: +{{- with .Values.master.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} +{{- if .Values.master.service.labelsHeadless }} +{{ toYaml .Values.master.service.labelsHeadless | indent 4 }} +{{- end }} + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +{{- if .Values.master.service.headless.annotations }} +{{ toYaml .Values.master.service.headless.annotations | indent 4 }} +{{- end }} +spec: + clusterIP: None # This is needed for statefulset hostnames like opensearch-0 to resolve + # Create endpoints also if the related pod isn't ready + publishNotReadyAddresses: true + selector: + {{- with .Values.master.selectorLabels }} +{{- toYaml . | nindent 4 }} + {{- end }} + ports: + - name: {{ .Values.master.service.httpPortName | default "http" }} + port: {{ .Values.master.httpPort }} + - name: {{ .Values.master.service.transportPortName | default "transport" }} + port: {{ .Values.master.transportPort }} + - name: {{ .Values.master.service.metricsPortName | default "metrics" }} + port: {{ .Values.master.metricsPort }} diff --git a/charts/opensearch/templates/masterStatefulset.yaml b/charts/opensearch/templates/masterStatefulset.yaml new file mode 100644 index 00000000..0958b1d8 --- /dev/null +++ b/charts/opensearch/templates/masterStatefulset.yaml @@ -0,0 +1,556 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Values.master.name }} + labels: + {{- with .Values.master.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + majorVersion: "{{ include "opensearch.majorVersion" . }}" + {{- with .Values.master.openSearchAnnotations }} +{{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceName: {{ .Values.master.serviceName }}-headless + selector: + matchLabels: + {{- with .Values.master.selectorLabels }} +{{- toYaml . | nindent 6 }} + {{- end }} + {{- if .Values.master.singleNode }} + replicas: 1 + {{- else }} + replicas: {{ .Values.master.replicas }} + {{- end }} + podManagementPolicy: {{ .Values.master.podManagementPolicy }} + updateStrategy: + type: {{ .Values.master.updateStrategy }} + {{- if .Values.master.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: {{ .Values.master.name }} + {{- if .Values.master.persistence.labels.enabled }} + labels: + {{- with .Values.master.labels }} +{{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.master.persistence.annotations }} + annotations: +{{ toYaml . | indent 8 }} + {{- end }} + spec: + accessModes: + {{- range .Values.master.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.master.persistence.size | quote }} + {{- if .Values.master.persistence.storageClass }} + {{- if (eq "-" .Values.master.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.master.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- end }} + template: + metadata: + name: "{{ .Values.master.name }}" + labels: + {{- with .Values.master.labels }} +{{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- range $key, $value := .Values.master.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- /* This forces a restart if the configmap has changed */}} + {{- if .Values.master.config }} + configchecksum: {{ include (print .Template.BasePath "/masterConfigmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + {{- if .Values.master.securityConfig.config.data }} + securityconfigchecksum: {{ include (print .Template.BasePath "/securityconfig.yaml") . | sha256sum | trunc 63 }} + {{- end }} + spec: + {{- if .Values.master.schedulerName }} + schedulerName: "{{ .Values.master.schedulerName }}" + {{- end }} + securityContext: +{{ toYaml .Values.master.podSecurityContext | indent 8 }} + {{- if .Values.master.sysctl.enabled }} + sysctls: + - name: vm.max_map_count + value: {{ .Values.master.sysctlVmMaxMapCount | quote }} + {{- end }} + {{- if .Values.master.fsGroup }} + fsGroup: {{ .Values.master.fsGroup }} # Deprecated value, please use .Values.podSecurityContext.fsGroup + {{- end }} + {{- if and .Values.rbac.create (eq .Values.rbac.serviceAccountName "") }} + serviceAccountName: "{{ template "opensearch.uname" . }}" + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- else if and .Values.rbac.create (ne .Values.rbac.serviceAccountName "") }} + serviceAccountName: {{ .Values.rbac.serviceAccountName | quote }} + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- else }} + automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} + {{- end }} + {{- if .Values.master.imagePullSecrets }} + {{- end }} + {{- with .Values.master.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.master.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if or (eq .Values.master.antiAffinity "hard") (eq .Values.master.antiAffinity "soft") .Values.master.nodeAffinity }} + {{- if .Values.master.priorityClassName }} + priorityClassName: {{ .Values.master.priorityClassName }} + {{- end }} + affinity: + {{- end }} + {{- if eq .Values.master.antiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/name + operator: In + values: + - {{ include "opensearch.name" . }} + topologyKey: {{ .Values.master.antiAffinityTopologyKey }} + {{- else if eq .Values.master.antiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: {{ .Values.master.antiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/name + operator: In + values: + - {{ .Values.master.name }} + {{- end }} + {{- with .Values.master.nodeAffinity }} + nodeAffinity: +{{ toYaml . | indent 10 }} + {{- end }} + {{- if .Values.master.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml .Values.master.topologySpreadConstraints | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.master.terminationGracePeriod }} + volumes: + {{- range .Values.master.secretMounts }} + - name: {{ .name | required "secretMount .name is required" }} + secret: + secretName: {{ .secretName | required "secretMount .secretName is required" }} + {{- if .defaultMode }} + defaultMode: {{ .defaultMode }} + {{- end }} + {{- end }} + {{- if .Values.master.config }} + - name: config + configMap: + name: {{ .Values.master.name }}-config + {{- end }} + {{- if and .Values.master.securityConfig.config.data .Values.master.securityConfig.config.securityConfigSecret }} + {{ fail "Only one of .Values.securityConfig.config.data and .Values.securityConfig.config.securityConfigSecret may be defined. Please see the comment in values.yaml describing usage." }} + {{- end }} + {{- if .Values.master.securityConfig.config.data }} + - name: security-config-data + secret: + secretName: {{ .Values.master.name }}-securityconfig + {{- end }} + {{- with .Values.master.securityConfig.config.securityConfigSecret }} + - name: security-config-complete + secret: + secretName: {{ . | quote }} + {{- end }} + {{- if .Values.master.securityConfig.actionGroupsSecret }} + - name: action-groups + secret: + secretName: {{ .Values.master.securityConfig.actionGroupsSecret }} + {{- end }} + {{- if .Values.master.securityConfig.configSecret }} + - name: security-config + secret: + secretName: {{ .Values.master.securityConfig.configSecret }} + {{- end }} + {{- if .Values.master.securityConfig.internalUsersSecret }} + - name: internal-users-config + secret: + secretName: {{ .Values.master.securityConfig.internalUsersSecret }} + {{- end }} + {{- if .Values.master.securityConfig.rolesSecret }} + - name: roles + secret: + secretName: {{ .Values.master.securityConfig.rolesSecret }} + {{- end }} + {{- if .Values.master.securityConfig.rolesMappingSecret }} + - name: role-mapping + secret: + secretName: {{ .Values.master.securityConfig.rolesMappingSecret }} + {{- end -}} + {{- if .Values.master.securityConfig.tenantsSecret }} + - name: tenants + secret: + secretName: {{ .Values.master.securityConfig.tenantsSecret }} + {{- end }} +{{- if .Values.master.keystore }} + - name: keystore + emptyDir: {} + {{- range .Values.master.keystore }} + - name: keystore-{{ .secretName }} + secret: {{ toYaml . | nindent 12 }} + {{- end }} +{{ end }} + {{- if .Values.master.extraVolumes }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.master.extraVolumes) }} +{{ tpl .Values.master.extraVolumes . | indent 6 }} + {{- else }} +{{ toYaml .Values.master.extraVolumes | indent 6 }} + {{- end }} + {{- end }} + {{- if .Values.master.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.master.imagePullSecrets | indent 8 }} + {{- end }} + enableServiceLinks: {{ .Values.master.enableServiceLinks }} + {{- if .Values.master.hostAliases }} + hostAliases: {{ toYaml .Values.master.hostAliases | nindent 8 }} + {{- end }} + {{- if or (.Values.master.extraInitContainers) (.Values.master.keystore) (.Values.master.persistence.enabled) (.Values.master.sysctlInit.enabled) }} + initContainers: +{{- if and .Values.master.persistence.enabled .Values.master.persistence.enableInitChown }} + - name: fsgroup-volume + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.master.persistence.image | default "busybox" }}:{{ .Values.master.persistence.imageTag | default "latest" }}" + imagePullPolicy: "{{ .Values.master.image.pullPolicy }}" + command: ['sh', '-c'] + args: + - 'chown -R 1000:1000 /usr/share/opensearch/data' + securityContext: + runAsUser: 0 + resources: + {{- toYaml .Values.master.initResources | nindent 10 }} + volumeMounts: + - name: "{{ .Values.master.name }}" + mountPath: {{ .Values.master.opensearchHome }}/data +{{- end }} +{{- if .Values.master.sysctlInit.enabled }} + - name: sysctl + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.master.sysctlInit.image | default "busybox" }}:{{ .Values.master.sysctlInit.imageTag | default "latest" }}" + imagePullPolicy: "{{ .Values.master.image.pullPolicy }}" + command: + - sh + - -c + - | + set -xe + DESIRED="{{ .Values.master.sysctlVmMaxMapCount }}" + CURRENT=$(sysctl -n vm.max_map_count) + if [ "$DESIRED" -gt "$CURRENT" ]; then + sysctl -w vm.max_map_count=$DESIRED + fi + securityContext: + runAsUser: 0 + privileged: true + resources: + {{- toYaml .Values.master.initResources | nindent 10 }} +{{- end }} +{{- if .Values.master.keystore }} + - name: keystore + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.master.image.repository }}:{{ .Values.master.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.master.image.pullPolicy }}" + command: + - sh + - -c + - | + #!/usr/bin/env bash + set -euo pipefail + + {{ .Values.master.opensearchHome }}/bin/opensearch-keystore create + + for i in /tmp/keystoreSecrets/*/*; do + [ -f "$i" ] || continue + key=$(basename $i) + echo "Adding file $i to keystore key $key" + {{ .Values.master.opensearchHome }}/bin/opensearch-keystore add-file "$key" "$i" + done + + # Add the bootstrap password since otherwise the opensearch entrypoint tries to do this on startup + if [ ! -z ${PASSWORD+x} ]; then + echo 'Adding env $PASSWORD to keystore as key bootstrap.password' + echo "$PASSWORD" | {{ .Values.master.opensearchHome }}/bin/opensearch-keystore add -x bootstrap.password + fi + + cp -a {{ .Values.master.opensearchHome }}/config/opensearch.keystore /tmp/keystore/ + env: {{ toYaml .Values.master.extraEnvs | nindent 10 }} + envFrom: {{ toYaml .Values.master.envFrom | nindent 10 }} + resources: + {{- toYaml .Values.master.initResources | nindent 10 }} + volumeMounts: + - name: keystore + mountPath: /tmp/keystore + {{- range .Values.master.keystore }} + - name: keystore-{{ .secretName }} + mountPath: /tmp/keystoreSecrets/{{ .secretName }} + {{- end }} +{{- end }} + {{- if .Values.master.extraInitContainers }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.master.extraInitContainers) }} +{{ tpl .Values.master.extraInitContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.master.extraInitContainers | indent 6 }} + {{- end }} + {{- end }} + {{- end }} + containers: + - name: "{{ .Values.master.name }}" + securityContext: +{{ toYaml .Values.master.securityContext | indent 10 }} + {{- if .Values.master.plugins.enabled }} + command: + - sh + - -c + - | + #!/usr/bin/env bash + set -euo pipefail + + {{- range $plugin := .Values.master.plugins.installList }} + ./bin/opensearch-plugin install -b {{ $plugin }} + {{- end }} + + bash opensearch-docker-entrypoint.sh + {{- end }} + + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.master.image.repository }}:{{ .Values.master.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.master.image.pullPolicy }}" + readinessProbe: +{{ toYaml .Values.master.readinessProbe | indent 10 }} + {{- if .Values.master.livenessProbe }} + livenessProbe: +{{ toYaml .Values.master.livenessProbe | indent 10 }} + {{- end }} + {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.Version }} + startupProbe: +{{ toYaml .Values.master.startupProbe | indent 10 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.master.httpPort }} + {{- if .Values.master.httpHostPort }} + hostPort: {{ .Values.master.httpHostPort }} + {{- end }} + - name: transport + containerPort: {{ .Values.master.transportPort }} + {{- if .Values.master.transportHostPort }} + hostPort: {{ .Values.master.transportHostPort }} + {{- end }} + - name: metrics + containerPort: {{ .Values.master.metricsPort }} + resources: + {{- toYaml .Values.master.resources | nindent 10 }} + env: + - name: node.name + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if (and (has "master" .Values.master.roles) (not .Values.master.singleNode)) }} + - name: cluster.initial_master_nodes + value: "{{ template "opensearch.endpoints" . }}" + {{- end }} + - name: discovery.seed_hosts + value: "{{ .Values.master.serviceName }}-headless" + - name: cluster.name + value: "{{ .Values.master.clusterName }}" + - name: network.host + value: "{{ .Values.master.networkHost }}" + - name: OPENSEARCH_JAVA_OPTS + value: "{{ .Values.master.opensearchJavaOpts }}" + - name: node.roles + value: "{{ template "opensearch.master.roles" . }}" + {{- if .Values.master.singleNode }} + - name: discovery.type + value: "single-node" + {{- end }} +{{- if .Values.master.extraEnvs }} +{{ toYaml .Values.master.extraEnvs | indent 8 }} +{{- end }} +{{- if .Values.master.envFrom }} + envFrom: +{{ toYaml .Values.master.envFrom | indent 8 }} +{{- end }} +{{- if .Values.master.opensearchLifecycle }} + lifecycle: +{{ toYaml .Values.master.opensearchLifecycle | indent 10 }} +{{- end }} + volumeMounts: + {{- if .Values.master.persistence.enabled }} + - name: "{{ .Values.master.name }}" + mountPath: {{ .Values.master.opensearchHome }}/data + {{- end }} + {{- if .Values.master.keystore }} + - name: keystore + mountPath: {{ .Values.master.opensearchHome }}/config/opensearch.keystore + subPath: opensearch.keystore + {{- end }} + {{- if .Values.master.securityConfig.enabled }} + {{- if .Values.master.securityConfig.actionGroupsSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/action_groups.yml + name: action-groups + subPath: action_groups.yml + {{- end }} + {{- if .Values.master.securityConfig.configSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/config.yml + name: security-config + subPath: config.yml + {{- end }} + {{- if .Values.master.securityConfig.internalUsersSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/internal_users.yml + name: internal-users-config + subPath: internal_users.yml + {{- end }} + {{- if .Values.securityConfig.rolesSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/roles.yml + name: roles + subPath: roles.yml + {{- end }} + {{- if .Values.master.securityConfig.rolesMappingSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/roles_mapping.yml + name: role-mapping + subPath: roles_mapping.yml + {{- end }} + {{- if .Values.master.securityConfig.tenantsSecret }} + - mountPath: {{ .Values.master.securityConfig.path }}/tenants.yml + name: tenants + subPath: tenants.yml + {{- end }} + {{- if .Values.master.securityConfig.config.data }} + {{- if .Values.master.securityConfig.config.dataComplete }} + - mountPath: {{ .Values.master.securityConfig.path }} + name: security-config-data + {{- else }} + {{- range $key, $_ := .Values.master.securityConfig.config.data }} + - mountPath: {{ $.Values.master.securityConfig.path }}/{{ $key }} + name: security-config-data + subPath: {{ $key }} + {{- end }} + {{- end }} + {{- else if .Values.master.securityConfig.config.securityConfigSecret }} + - mountPath: {{ .Values.master.securityConfig.path }} + name: security-config-complete + {{- end }} + {{- end }} + {{- range .Values.master.secretMounts }} + - name: {{ .name | required "secretMount .name is required" }} + mountPath: {{ .path | required "secretMount .path is required" }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.master.config }} + - name: config + mountPath: {{ $.Values.master.opensearchHome }}/config/{{ $path }} + subPath: {{ $path }} + {{- end -}} + {{- if .Values.master.extraVolumeMounts }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.master.extraVolumeMounts) }} +{{ tpl .Values.master.extraVolumeMounts . | indent 8 }} + {{- else }} +{{ toYaml .Values.master.extraVolumeMounts | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.master.masterTerminationFix }} + {{- if has "master" .Values.master.roles }} + # This sidecar will prevent slow master re-election + - name: opensearch-master-graceful-termination-handler + image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.master.image.repository }}:{{ .Values.master.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.master.image.pullPolicy }}" + command: + - "sh" + - -c + - | + #!/usr/bin/env bash + set -eo pipefail + + http () { + local path="${1}" + if [ -n "${USERNAME}" ] && [ -n "${PASSWORD}" ]; then + BASIC_AUTH="-u ${USERNAME}:${PASSWORD}" + else + BASIC_AUTH='' + fi + curl -XGET -s -k --fail ${BASIC_AUTH} {{ .Values.master.protocol }}://{{ template "opensearch.masterService" . }}:{{ .Values.master.httpPort }}${path} + } + + cleanup () { + while true ; do + local master="$(http "/_cat/master?h=node" || echo "")" + if [[ $master == "{{ template "opensearch.masterService" . }}"* && $master != "${NODE_NAME}" ]]; then + echo "This node is not master." + break + fi + echo "This node is still master, waiting gracefully for it to step down" + sleep 1 + done + + exit 0 + } + + trap cleanup SIGTERM + + sleep infinity & + wait $! + resources: + {{- toYaml .Values.master.sidecarResources | nindent 10 }} + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if .Values.master.extraEnvs }} +{{ toYaml .Values.master.extraEnvs | indent 8 }} + {{- end }} + {{- if .Values.master.envFrom }} + envFrom: +{{ toYaml .Values.master.envFrom | indent 8 }} + {{- end }} + {{- end }} + {{- end }} +{{- if .Values.master.lifecycle }} + lifecycle: +{{ toYaml .Values.master.lifecycle | indent 10 }} +{{- end }} + {{- if .Values.master.extraContainers }} + # Currently some extra blocks accept strings + # to continue with backwards compatibility this is being kept + # whilst also allowing for yaml to be specified too. + {{- if eq "string" (printf "%T" .Values.master.extraContainers) }} +{{ tpl .Values.master.extraContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.master.extraContainers | indent 6 }} + {{- end }} + {{- end }} diff --git a/charts/opensearch/templates/poddisruptionbudget.yaml b/charts/opensearch/templates/poddisruptionbudget.yaml deleted file mode 100644 index 68ab5b69..00000000 --- a/charts/opensearch/templates/poddisruptionbudget.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.maxUnavailable }} -{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: policy/v1 -{{- else -}} -apiVersion: policy/v1beta1 -{{- end }} -kind: PodDisruptionBudget -metadata: - name: "{{ template "opensearch.uname" . }}-pdb" - labels: - {{- include "opensearch.labels" . | nindent 4 }} -spec: - maxUnavailable: {{ .Values.maxUnavailable }} - selector: - matchLabels: - {{- include "opensearch.selectorLabels" . | nindent 6 }} -{{- end }} diff --git a/charts/opensearch/templates/service.yaml b/charts/opensearch/templates/service.yaml deleted file mode 100644 index 4c28b2f3..00000000 --- a/charts/opensearch/templates/service.yaml +++ /dev/null @@ -1,72 +0,0 @@ ---- -kind: Service -apiVersion: v1 -metadata: - name: {{ template "opensearch.serviceName" . }} - labels: - {{- include "opensearch.labels" . | nindent 4 }} -{{- if .Values.service.labels }} -{{ toYaml .Values.service.labels | indent 4 }} -{{- end }} - annotations: -{{ toYaml .Values.service.annotations | indent 4 }} -spec: - type: {{ .Values.service.type }} - {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} - {{- if .Values.service.ipFamilyPolicy }} - ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} - {{- end }} - {{- if .Values.service.ipFamilies }} - ipFamilies: {{ .Values.service.ipFamilies }} - {{- end }} - {{- end }} - selector: - {{- include "opensearch.selectorLabels" . | nindent 4 }} - ports: - - name: {{ .Values.service.httpPortName | default "http" }} - protocol: TCP - port: {{ .Values.httpPort }} -{{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} -{{- end }} - - name: {{ .Values.service.transportPortName | default "transport" }} - protocol: TCP - port: {{ .Values.transportPort }} -{{- if .Values.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} -{{- end }} -{{- with .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: -{{ toYaml . | indent 4 }} -{{- end }} -{{- if .Values.service.externalTrafficPolicy }} - externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} -{{- end }} ---- -kind: Service -apiVersion: v1 -metadata: - name: {{ template "opensearch.serviceName" . }}-headless - labels: - {{- include "opensearch.labels" . | nindent 4 }} -{{- if .Values.service.labelsHeadless }} -{{ toYaml .Values.service.labelsHeadless | indent 4 }} -{{- end }} - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" -{{- if .Values.service.headless.annotations }} -{{ toYaml .Values.service.headless.annotations | indent 4 }} -{{- end }} -spec: - clusterIP: None # This is needed for statefulset hostnames like opensearch-0 to resolve - # Create endpoints also if the related pod isn't ready - publishNotReadyAddresses: true - selector: - {{- include "opensearch.selectorLabels" . | nindent 4 }} - ports: - - name: {{ .Values.service.httpPortName | default "http" }} - port: {{ .Values.httpPort }} - - name: {{ .Values.service.transportPortName | default "transport" }} - port: {{ .Values.transportPort }} - - name: {{ .Values.service.metricsPortName | default "metrics" }} - port: {{ .Values.metricsPort }} diff --git a/charts/opensearch/templates/statefulset.yaml b/charts/opensearch/templates/statefulset.yaml deleted file mode 100644 index d5c91a80..00000000 --- a/charts/opensearch/templates/statefulset.yaml +++ /dev/null @@ -1,548 +0,0 @@ ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "opensearch.uname" . }} - labels: - {{- include "opensearch.labels" . | nindent 4 }} - annotations: - majorVersion: "{{ include "opensearch.majorVersion" . }}" - {{- with .Values.openSearchAnnotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - serviceName: {{ template "opensearch.serviceName" . }}-headless - selector: - matchLabels: - {{- include "opensearch.selectorLabels" . | nindent 6 }} - {{- if .Values.singleNode }} - replicas: 1 - {{- else }} - replicas: {{ .Values.replicas }} - {{- end }} - podManagementPolicy: {{ .Values.podManagementPolicy }} - updateStrategy: - type: {{ .Values.updateStrategy }} - {{- if .Values.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: {{ template "opensearch.uname" . }} - {{- if .Values.persistence.labels.enabled }} - labels: - {{- include "opensearch.labels" . | nindent 8 }} - {{- end }} - {{- with .Values.persistence.annotations }} - annotations: -{{ toYaml . | indent 8 }} - {{- end }} - spec: - accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{- if .Values.persistence.storageClass }} - {{- if (eq "-" .Values.persistence.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: "{{ .Values.persistence.storageClass }}" - {{- end }} - {{- end }} - {{- end }} - template: - metadata: - name: "{{ template "opensearch.uname" . }}" - labels: - {{- include "opensearch.labels" . | nindent 8 }} - annotations: - {{- range $key, $value := .Values.podAnnotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} - {{- /* This forces a restart if the configmap has changed */}} - {{- if .Values.config }} - configchecksum: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }} - {{- end }} - {{- if .Values.securityConfig.config.data }} - securityconfigchecksum: {{ include (print .Template.BasePath "/securityconfig.yaml") . | sha256sum | trunc 63 }} - {{- end }} - spec: - {{- if .Values.schedulerName }} - schedulerName: "{{ .Values.schedulerName }}" - {{- end }} - securityContext: -{{ toYaml .Values.podSecurityContext | indent 8 }} - {{- if .Values.sysctl.enabled }} - sysctls: - - name: vm.max_map_count - value: {{ .Values.sysctlVmMaxMapCount | quote }} - {{- end }} - {{- if .Values.fsGroup }} - fsGroup: {{ .Values.fsGroup }} # Deprecated value, please use .Values.podSecurityContext.fsGroup - {{- end }} - {{- if and .Values.rbac.create (eq .Values.rbac.serviceAccountName "") }} - serviceAccountName: "{{ template "opensearch.uname" . }}" - automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} - {{- else if and .Values.rbac.create (ne .Values.rbac.serviceAccountName "") }} - serviceAccountName: {{ .Values.rbac.serviceAccountName | quote }} - automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} - {{- else }} - automountServiceAccountToken: {{ ne .Values.rbac.automountServiceAccountToken false }} - {{- end }} - {{- if .Values.imagePullSecrets }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 6 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- if or (eq .Values.antiAffinity "hard") (eq .Values.antiAffinity "soft") .Values.nodeAffinity }} - {{- if .Values.priorityClassName }} - priorityClassName: {{ .Values.priorityClassName }} - {{- end }} - affinity: - {{- end }} - {{- if eq .Values.antiAffinity "hard" }} - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/instance - operator: In - values: - - {{ .Release.Name }} - - key: app.kubernetes.io/name - operator: In - values: - - {{ include "opensearch.name" . }} - topologyKey: {{ .Values.antiAffinityTopologyKey }} - {{- else if eq .Values.antiAffinity "soft" }} - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - podAffinityTerm: - topologyKey: {{ .Values.antiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - key: app.kubernetes.io/instance - operator: In - values: - - {{ .Release.Name }} - - key: app.kubernetes.io/name - operator: In - values: - - {{ include "opensearch.name" . }} - {{- end }} - {{- with .Values.nodeAffinity }} - nodeAffinity: -{{ toYaml . | indent 10 }} - {{- end }} - {{- if .Values.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} - volumes: - {{- range .Values.secretMounts }} - - name: {{ .name | required "secretMount .name is required" }} - secret: - secretName: {{ .secretName | required "secretMount .secretName is required" }} - {{- if .defaultMode }} - defaultMode: {{ .defaultMode }} - {{- end }} - {{- end }} - {{- if .Values.config }} - - name: config - configMap: - name: {{ template "opensearch.uname" . }}-config - {{- end }} - {{- if and .Values.securityConfig.config.data .Values.securityConfig.config.securityConfigSecret }} - {{ fail "Only one of .Values.securityConfig.config.data and .Values.securityConfig.config.securityConfigSecret may be defined. Please see the comment in values.yaml describing usage." }} - {{- end }} - {{- if .Values.securityConfig.config.data }} - - name: security-config-data - secret: - secretName: {{ include "opensearch.uname" . }}-securityconfig - {{- end }} - {{- with .Values.securityConfig.config.securityConfigSecret }} - - name: security-config-complete - secret: - secretName: {{ . | quote }} - {{- end }} - {{- if .Values.securityConfig.actionGroupsSecret }} - - name: action-groups - secret: - secretName: {{ .Values.securityConfig.actionGroupsSecret }} - {{- end }} - {{- if .Values.securityConfig.configSecret }} - - name: security-config - secret: - secretName: {{ .Values.securityConfig.configSecret }} - {{- end }} - {{- if .Values.securityConfig.internalUsersSecret }} - - name: internal-users-config - secret: - secretName: {{ .Values.securityConfig.internalUsersSecret }} - {{- end }} - {{- if .Values.securityConfig.rolesSecret }} - - name: roles - secret: - secretName: {{ .Values.securityConfig.rolesSecret }} - {{- end }} - {{- if .Values.securityConfig.rolesMappingSecret }} - - name: role-mapping - secret: - secretName: {{ .Values.securityConfig.rolesMappingSecret }} - {{- end -}} - {{- if .Values.securityConfig.tenantsSecret }} - - name: tenants - secret: - secretName: {{ .Values.securityConfig.tenantsSecret }} - {{- end }} -{{- if .Values.keystore }} - - name: keystore - emptyDir: {} - {{- range .Values.keystore }} - - name: keystore-{{ .secretName }} - secret: {{ toYaml . | nindent 12 }} - {{- end }} -{{ end }} - {{- if .Values.extraVolumes }} - # Currently some extra blocks accept strings - # to continue with backwards compatibility this is being kept - # whilst also allowing for yaml to be specified too. - {{- if eq "string" (printf "%T" .Values.extraVolumes) }} -{{ tpl .Values.extraVolumes . | indent 6 }} - {{- else }} -{{ toYaml .Values.extraVolumes | indent 6 }} - {{- end }} - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} - {{- end }} - enableServiceLinks: {{ .Values.enableServiceLinks }} - {{- if .Values.hostAliases }} - hostAliases: {{ toYaml .Values.hostAliases | nindent 8 }} - {{- end }} - {{- if or (.Values.extraInitContainers) (.Values.keystore) (.Values.persistence.enabled) (.Values.sysctlInit.enabled) }} - initContainers: -{{- if and .Values.persistence.enabled .Values.persistence.enableInitChown }} - - name: fsgroup-volume - image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.persistence.image | default "busybox" }}:{{ .Values.persistence.imageTag | default "latest" }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - command: ['sh', '-c'] - args: - - 'chown -R 1000:1000 /usr/share/opensearch/data' - securityContext: - runAsUser: 0 - resources: - {{- toYaml .Values.initResources | nindent 10 }} - volumeMounts: - - name: "{{ template "opensearch.uname" . }}" - mountPath: {{ .Values.opensearchHome }}/data -{{- end }} -{{- if .Values.sysctlInit.enabled }} - - name: sysctl - image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.sysctlInit.image | default "busybox" }}:{{ .Values.sysctlInit.imageTag | default "latest" }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - command: - - sh - - -c - - | - set -xe - DESIRED="{{ .Values.sysctlVmMaxMapCount }}" - CURRENT=$(sysctl -n vm.max_map_count) - if [ "$DESIRED" -gt "$CURRENT" ]; then - sysctl -w vm.max_map_count=$DESIRED - fi - securityContext: - runAsUser: 0 - privileged: true - resources: - {{- toYaml .Values.initResources | nindent 10 }} -{{- end }} -{{- if .Values.keystore }} - - name: keystore - image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - command: - - sh - - -c - - | - #!/usr/bin/env bash - set -euo pipefail - - {{ .Values.opensearchHome }}/bin/opensearch-keystore create - - for i in /tmp/keystoreSecrets/*/*; do - [ -f "$i" ] || continue - key=$(basename $i) - echo "Adding file $i to keystore key $key" - {{ .Values.opensearchHome }}/bin/opensearch-keystore add-file "$key" "$i" - done - - # Add the bootstrap password since otherwise the opensearch entrypoint tries to do this on startup - if [ ! -z ${PASSWORD+x} ]; then - echo 'Adding env $PASSWORD to keystore as key bootstrap.password' - echo "$PASSWORD" | {{ .Values.opensearchHome }}/bin/opensearch-keystore add -x bootstrap.password - fi - - cp -a {{ .Values.opensearchHome }}/config/opensearch.keystore /tmp/keystore/ - env: {{ toYaml .Values.extraEnvs | nindent 10 }} - envFrom: {{ toYaml .Values.envFrom | nindent 10 }} - resources: - {{- toYaml .Values.initResources | nindent 10 }} - volumeMounts: - - name: keystore - mountPath: /tmp/keystore - {{- range .Values.keystore }} - - name: keystore-{{ .secretName }} - mountPath: /tmp/keystoreSecrets/{{ .secretName }} - {{- end }} -{{- end }} - {{- if .Values.extraInitContainers }} - # Currently some extra blocks accept strings - # to continue with backwards compatibility this is being kept - # whilst also allowing for yaml to be specified too. - {{- if eq "string" (printf "%T" .Values.extraInitContainers) }} -{{ tpl .Values.extraInitContainers . | indent 6 }} - {{- else }} -{{ toYaml .Values.extraInitContainers | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - containers: - - name: "{{ template "opensearch.name" . }}" - securityContext: -{{ toYaml .Values.securityContext | indent 10 }} - {{- if .Values.plugins.enabled }} - command: - - sh - - -c - - | - #!/usr/bin/env bash - set -euo pipefail - - {{- range $plugin := .Values.plugins.installList }} - ./bin/opensearch-plugin install -b {{ $plugin }} - {{- end }} - - bash opensearch-docker-entrypoint.sh - {{- end }} - - image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - readinessProbe: -{{ toYaml .Values.readinessProbe | indent 10 }} - {{- if .Values.livenessProbe }} - livenessProbe: -{{ toYaml .Values.livenessProbe | indent 10 }} - {{- end }} - {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.Version }} - startupProbe: -{{ toYaml .Values.startupProbe | indent 10 }} - {{- end }} - ports: - - name: http - containerPort: {{ .Values.httpPort }} - {{- if .Values.httpHostPort }} - hostPort: {{ .Values.httpHostPort }} - {{- end }} - - name: transport - containerPort: {{ .Values.transportPort }} - {{- if .Values.transportHostPort }} - hostPort: {{ .Values.transportHostPort }} - {{- end }} - - name: metrics - containerPort: {{ .Values.metricsPort }} - resources: - {{- toYaml .Values.resources | nindent 10 }} - env: - - name: node.name - valueFrom: - fieldRef: - fieldPath: metadata.name - {{- if (and (has "master" .Values.roles) (not .Values.singleNode)) }} - - name: cluster.initial_master_nodes - value: "{{ template "opensearch.endpoints" . }}" - {{- end }} - - name: discovery.seed_hosts - value: "{{ template "opensearch.masterService" . }}-headless" - - name: cluster.name - value: "{{ .Values.clusterName }}" - - name: network.host - value: "{{ .Values.networkHost }}" - - name: OPENSEARCH_JAVA_OPTS - value: "{{ .Values.opensearchJavaOpts }}" - - name: node.roles - value: "{{ template "opensearch.roles" . }}" - {{- if .Values.singleNode }} - - name: discovery.type - value: "single-node" - {{- end }} -{{- if .Values.extraEnvs }} -{{ toYaml .Values.extraEnvs | indent 8 }} -{{- end }} -{{- if .Values.envFrom }} - envFrom: -{{ toYaml .Values.envFrom | indent 8 }} -{{- end }} -{{- if .Values.opensearchLifecycle }} - lifecycle: -{{ toYaml .Values.opensearchLifecycle | indent 10 }} -{{- end }} - volumeMounts: - {{- if .Values.persistence.enabled }} - - name: "{{ template "opensearch.uname" . }}" - mountPath: {{ .Values.opensearchHome }}/data - {{- end }} - {{- if .Values.keystore }} - - name: keystore - mountPath: {{ .Values.opensearchHome }}/config/opensearch.keystore - subPath: opensearch.keystore - {{- end }} - {{- if .Values.securityConfig.enabled }} - {{- if .Values.securityConfig.actionGroupsSecret }} - - mountPath: {{ .Values.securityConfig.path }}/action_groups.yml - name: action-groups - subPath: action_groups.yml - {{- end }} - {{- if .Values.securityConfig.configSecret }} - - mountPath: {{ .Values.securityConfig.path }}/config.yml - name: security-config - subPath: config.yml - {{- end }} - {{- if .Values.securityConfig.internalUsersSecret }} - - mountPath: {{ .Values.securityConfig.path }}/internal_users.yml - name: internal-users-config - subPath: internal_users.yml - {{- end }} - {{- if .Values.securityConfig.rolesSecret }} - - mountPath: {{ .Values.securityConfig.path }}/roles.yml - name: roles - subPath: roles.yml - {{- end }} - {{- if .Values.securityConfig.rolesMappingSecret }} - - mountPath: {{ .Values.securityConfig.path }}/roles_mapping.yml - name: role-mapping - subPath: roles_mapping.yml - {{- end }} - {{- if .Values.securityConfig.tenantsSecret }} - - mountPath: {{ .Values.securityConfig.path }}/tenants.yml - name: tenants - subPath: tenants.yml - {{- end }} - {{- if .Values.securityConfig.config.data }} - {{- if .Values.securityConfig.config.dataComplete }} - - mountPath: {{ .Values.securityConfig.path }} - name: security-config-data - {{- else }} - {{- range $key, $_ := .Values.securityConfig.config.data }} - - mountPath: {{ $.Values.securityConfig.path }}/{{ $key }} - name: security-config-data - subPath: {{ $key }} - {{- end }} - {{- end }} - {{- else if .Values.securityConfig.config.securityConfigSecret }} - - mountPath: {{ .Values.securityConfig.path }} - name: security-config-complete - {{- end }} - {{- end }} - {{- range .Values.secretMounts }} - - name: {{ .name | required "secretMount .name is required" }} - mountPath: {{ .path | required "secretMount .path is required" }} - {{- if .subPath }} - subPath: {{ .subPath }} - {{- end }} - {{- end }} - {{- range $path, $config := .Values.config }} - - name: config - mountPath: {{ $.Values.opensearchHome }}/config/{{ $path }} - subPath: {{ $path }} - {{- end -}} - {{- if .Values.extraVolumeMounts }} - # Currently some extra blocks accept strings - # to continue with backwards compatibility this is being kept - # whilst also allowing for yaml to be specified too. - {{- if eq "string" (printf "%T" .Values.extraVolumeMounts) }} -{{ tpl .Values.extraVolumeMounts . | indent 8 }} - {{- else }} -{{ toYaml .Values.extraVolumeMounts | indent 8 }} - {{- end }} - {{- end }} - {{- if .Values.masterTerminationFix }} - {{- if has "master" .Values.roles }} - # This sidecar will prevent slow master re-election - - name: opensearch-master-graceful-termination-handler - image: "{{ template "opensearch.dockerRegistry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - command: - - "sh" - - -c - - | - #!/usr/bin/env bash - set -eo pipefail - - http () { - local path="${1}" - if [ -n "${USERNAME}" ] && [ -n "${PASSWORD}" ]; then - BASIC_AUTH="-u ${USERNAME}:${PASSWORD}" - else - BASIC_AUTH='' - fi - curl -XGET -s -k --fail ${BASIC_AUTH} {{ .Values.protocol }}://{{ template "opensearch.masterService" . }}:{{ .Values.httpPort }}${path} - } - - cleanup () { - while true ; do - local master="$(http "/_cat/master?h=node" || echo "")" - if [[ $master == "{{ template "opensearch.masterService" . }}"* && $master != "${NODE_NAME}" ]]; then - echo "This node is not master." - break - fi - echo "This node is still master, waiting gracefully for it to step down" - sleep 1 - done - - exit 0 - } - - trap cleanup SIGTERM - - sleep infinity & - wait $! - resources: - {{- toYaml .Values.sidecarResources | nindent 10 }} - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - {{- if .Values.extraEnvs }} -{{ toYaml .Values.extraEnvs | indent 8 }} - {{- end }} - {{- if .Values.envFrom }} - envFrom: -{{ toYaml .Values.envFrom | indent 8 }} - {{- end }} - {{- end }} - {{- end }} -{{- if .Values.lifecycle }} - lifecycle: -{{ toYaml .Values.lifecycle | indent 10 }} -{{- end }} - {{- if .Values.extraContainers }} - # Currently some extra blocks accept strings - # to continue with backwards compatibility this is being kept - # whilst also allowing for yaml to be specified too. - {{- if eq "string" (printf "%T" .Values.extraContainers) }} -{{ tpl .Values.extraContainers . | indent 6 }} - {{- else }} -{{ toYaml .Values.extraContainers | indent 6 }} - {{- end }} - {{- end }} diff --git a/charts/opensearch/values.yaml b/charts/opensearch/values.yaml index 090cb0c8..1404c9be 100644 --- a/charts/opensearch/values.yaml +++ b/charts/opensearch/values.yaml @@ -1,174 +1,73 @@ --- -clusterName: "opensearch-cluster" -nodeGroup: "master" - -# If discovery.type in the opensearch configuration is set to "single-node", -# this should be set to "true" -# If "true", replicas will be forced to 1 -singleNode: false - -# The service that non master groups will try to connect to when joining the cluster -# This should be set to clusterName + "-" + nodeGroup for your master group -masterService: "opensearch-cluster-master" - -# OpenSearch roles that will be applied to this nodeGroup -# These will be set as environment variable "node.roles". E.g. node.roles=master,ingest,data,remote_cluster_client -roles: - - master - - ingest - - data - - remote_cluster_client - -replicas: 3 - -# if not set, falls back to parsing .Values.imageTag, then .Chart.appVersion. -majorVersion: "" - -global: - # Set if you want to change the default docker registry, e.g. a private one. - dockerRegistry: "" - -# Allows you to add any config files in {{ .Values.opensearchHome }}/config -opensearchHome: /usr/share/opensearch -# such as opensearch.yml and log4j2.properties -config: - # Values must be YAML literal style scalar / YAML multiline string. - # : | - # - # log4j2.properties: | - # status = error - # - # appender.console.type = Console - # appender.console.name = console - # appender.console.layout.type = PatternLayout - # appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n - # - # rootLogger.level = info - # rootLogger.appenderRef.console.ref = console - opensearch.yml: | - cluster.name: opensearch-cluster - - # Bind to all interfaces because we don't know what IP address Docker will assign to us. - network.host: 0.0.0.0 - - # Setting network.host to a non-loopback address enables the annoying bootstrap checks. "Single-node" mode disables them again. - # Implicitly done if ".singleNode" is set to "true". - # discovery.type: single-node - - # Start OpenSearch Security Demo Configuration - # WARNING: revise all the lines below before you go into production - plugins: - security: - ssl: - transport: - pemcert_filepath: esnode.pem - pemkey_filepath: esnode-key.pem - pemtrustedcas_filepath: root-ca.pem - enforce_hostname_verification: false - http: - enabled: true - pemcert_filepath: esnode.pem - pemkey_filepath: esnode-key.pem - pemtrustedcas_filepath: root-ca.pem - allow_unsafe_democertificates: true - allow_default_init_securityindex: true - authcz: - admin_dn: - - CN=kirk,OU=client,O=client,L=test,C=de - audit.type: internal_opensearch - enable_snapshot_restore_privilege: true - check_snapshot_restore_write_privileges: true - restapi: - roles_enabled: ["all_access", "security_rest_api_access"] - system_indices: - enabled: true - indices: - [ - ".opendistro-alerting-config", - ".opendistro-alerting-alert*", - ".opendistro-anomaly-results*", - ".opendistro-anomaly-detector*", - ".opendistro-anomaly-checkpoints", - ".opendistro-anomaly-detection-state", - ".opendistro-reports-*", - ".opendistro-notifications-*", - ".opendistro-notebooks", - ".opendistro-asynchronous-search-response*", - ] - ######## End OpenSearch Security Demo Configuration ######## - # log4j2.properties: +# -- Array of extra K8s manifests to deploy +extraObjects: [] + # - apiVersion: secrets-store.csi.x-k8s.io/v1 + # kind: SecretProviderClass + # metadata: + # name: argocd-secrets-store + # spec: + # provider: aws + # parameters: + # objects: | + # - objectName: "argocd" + # objectType: "secretsmanager" + # jmesPath: + # - path: "client_id" + # objectAlias: "client_id" + # - path: "client_secret" + # objectAlias: "client_secret" + # secretObjects: + # - data: + # - key: client_id + # objectName: client_id + # - key: client_secret + # objectName: client_secret + # secretName: argocd-secrets-store + # type: Opaque + # labels: + # app.kubernetes.io/part-of: argocd + # - | + # apiVersion: policy/v1 + # kind: PodDisruptionBudget + # metadata: + # name: {{ template "opensearch.uname" . }} + # labels: + # {{- include "opensearch.labels" . | nindent 4 }} + # spec: + # minAvailable: 1 + # selector: + # matchLabels: + # {{- include "opensearch.selectorLabels" . | nindent 6 }} -# Extra environment variables to append to this nodeGroup -# This will be appended to the current 'env:' key. You can use any of the kubernetes env -# syntax here -extraEnvs: [] -# - name: MY_ENVIRONMENT_VAR -# value: the_value_goes_here - -# Allows you to load environment variables from kubernetes secret or config map -envFrom: [] -# - secretRef: -# name: env-secret -# - configMapRef: -# name: config-map - -# A list of secrets and their paths to mount inside the pod -# This is useful for mounting certificates for security and for mounting -# the X-Pack license -secretMounts: [] - -hostAliases: [] -# - ip: "127.0.0.1" -# hostnames: -# - "foo.local" -# - "bar.local" - -image: - repository: "opensearchproject/opensearch" - # override image tag, which is .Chart.AppVersion by default - tag: "" - pullPolicy: "IfNotPresent" - -podAnnotations: {} - # iam.amazonaws.com/role: es-cluster - -# OpenSearch Statefulset annotations -openSearchAnnotations: {} - -# additionals labels -labels: {} - -opensearchJavaOpts: "-Xmx512M -Xms512M" - -resources: - requests: - cpu: "1000m" - memory: "100Mi" - -initResources: {} -# limits: -# cpu: "25m" -# memory: "128Mi" -# requests: -# cpu: "25m" -# memory: "128Mi" - -sidecarResources: {} -# limits: -# cpu: "25m" -# memory: "128Mi" -# requests: -# cpu: "25m" -# memory: "128Mi" - -networkHost: "0.0.0.0" +# Enabling this will publically expose your OpenSearch instance. +# Only enable this if you have security enabled on your cluster +ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - chart-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local -rbac: +networkPolicy: create: false - serviceAccountAnnotations: {} - serviceAccountName: "" - # Controls whether or not the Service Account token is automatically mounted to /var/run/secrets/kubernetes.io/serviceaccount - automountServiceAccountToken: false + ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## In order for a Pod to access OpenSearch, it needs to have the following label: + ## {{ template "uname" . }}-client: "true" + ## Example for default configuration to access HTTP port: + ## opensearch-master-http-client: "true" + ## Example for default configuration to access transport port: + ## opensearch-master-transport-client: "true" + http: + enabled: false podSecurityPolicy: create: false @@ -189,126 +88,12 @@ podSecurityPolicy: - persistentVolumeClaim - emptyDir -persistence: - enabled: true - # Set to false to disable the `fsgroup-volume` initContainer that will update permissions on the persistent disk. - enableInitChown: true - # override image, which is busybox by default - # image: busybox - # override image tag, which is latest by default - # imageTag: - labels: - # Add default labels for the volumeClaimTemplate of the StatefulSet - enabled: false - # OpenSearch Persistent Volume Storage Class - # If defined, storageClassName: - # If set to "-", storageClassName: "", which disables dynamic provisioning - # If undefined (the default) or set to null, no storageClassName spec is - # set, choosing the default provisioner. (gp2 on AWS, standard on - # GKE, AWS & OpenStack) - # - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - annotations: {} - -extraVolumes: [] - # - name: extras - # emptyDir: {} - -extraVolumeMounts: [] - # - name: extras - # mountPath: /usr/share/extras - # readOnly: true - -extraContainers: [] - # - name: do-something - # image: busybox - # command: ['do', 'something'] - -extraInitContainers: [] - # - name: do-somethings - # image: busybox - # command: ['do', 'something'] - -# This is the PriorityClass settings as defined in -# https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass -priorityClassName: "" - -# By default this will make sure two pods don't end up on the same node -# Changing this to a region would allow you to spread pods across regions -antiAffinityTopologyKey: "kubernetes.io/hostname" - -# Hard means that by default pods will only be scheduled if there are enough nodes for them -# and that they will never end up on the same node. Setting this to soft will do this "best effort" -antiAffinity: "soft" - -# This is the node affinity settings as defined in -# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature -nodeAffinity: {} - -# This is the pod topology spread constraints -# https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ -topologySpreadConstraints: [] - -# The default is to deploy all pods serially. By setting this to parallel all pods are started at -# the same time when bootstrapping the cluster -podManagementPolicy: "Parallel" - -# The environment variables injected by service links are not used, but can lead to slow OpenSearch boot times when -# there are many services in the current namespace. -# If you experience slow pod startups you probably want to set this to `false`. -enableServiceLinks: true - -protocol: https -httpPort: 9200 -transportPort: 9300 -metricsPort: 9600 -httpHostPort: "" -transportHostPort: "" - - -service: - labels: {} - labelsHeadless: {} - headless: - annotations: {} - type: ClusterIP - # The IP family and IP families options are to set the behaviour in a dual-stack environment - # Omitting these values will let the service fall back to whatever the CNI dictates the defaults - # should be - # - # ipFamilyPolicy: SingleStack - # ipFamilies: - # - IPv4 - nodePort: "" - annotations: {} - httpPortName: http - transportPortName: transport - metricsPortName: metrics - loadBalancerIP: "" - loadBalancerSourceRanges: [] - externalTrafficPolicy: "" - -updateStrategy: RollingUpdate - -# This is the max unavailable setting for the pod disruption budget -# The default value of 1 will make sure that kubernetes won't allow more than 1 -# of your pods to be unavailable during maintenance -maxUnavailable: 1 - -podSecurityContext: - fsGroup: 1000 - runAsUser: 1000 - -securityContext: - capabilities: - drop: - - ALL - # readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 +rbac: + create: false + serviceAccountAnnotations: {} + serviceAccountName: "" + # Controls whether or not the Service Account token is automatically mounted to /var/run/secrets/kubernetes.io/serviceaccount + automountServiceAccountToken: false securityConfig: enabled: true @@ -343,173 +128,763 @@ securityConfig: # action_groups.yml: |- # tenants.yml: |- -# How long to wait for opensearch to stop gracefully -terminationGracePeriod: 120 - -sysctlVmMaxMapCount: 262144 - -startupProbe: - tcpSocket: - port: 9200 - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 3 - failureThreshold: 30 - -livenessProbe: {} - # periodSeconds: 20 - # timeoutSeconds: 5 - # failureThreshold: 10 - # successThreshold: 1 - # initialDelaySeconds: 10 - # tcpSocket: - # port: 9200 - -readinessProbe: - tcpSocket: - port: 9200 - periodSeconds: 5 - timeoutSeconds: 3 - failureThreshold: 3 - -## Use an alternate scheduler. -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -schedulerName: "" - -imagePullSecrets: [] -nodeSelector: {} -tolerations: [] - -# Enabling this will publically expose your OpenSearch instance. -# Only enable this if you have security enabled on your cluster -ingress: - enabled: false - # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName - # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress - # ingressClassName: nginx - - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - path: / - hosts: - - chart-example.local - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local + # if not set, falls back to parsing .Values.imageTag, then .Chart.appVersion. +majorVersion: "" -nameOverride: "" -fullnameOverride: "" - -masterTerminationFix: false - -opensearchLifecycle: {} - # preStop: - # exec: - # command: ["/bin/sh", "-c", "echo Hello from the preStart handler > /usr/share/message"] - # postStart: - # exec: - # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] - -lifecycle: {} - # preStop: - # exec: - # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] - # postStart: - # exec: - # command: - # - bash - # - -c - # - | - # #!/bin/bash - # # Add a template to adjust number of shards/replicas1 - # TEMPLATE_NAME=my_template - # INDEX_PATTERN="logstash-*" - # SHARD_COUNT=8 - # REPLICA_COUNT=1 - # ES_URL=http://localhost:9200 - # while [[ "$(curl -s -o /dev/null -w '%{http_code}\n' $ES_URL)" != "200" ]]; do sleep 1; done - # curl -XPUT "$ES_URL/_template/$TEMPLATE_NAME" -H 'Content-Type: application/json' -d'{"index_patterns":['\""$INDEX_PATTERN"\"'],"settings":{"number_of_shards":'$SHARD_COUNT',"number_of_replicas":'$REPLICA_COUNT'}}' - -keystore: [] -# To add secrets to the keystore: -# - secretName: opensearch-encryption-key +global: + # Set if you want to change the default docker registry, e.g. a private one. + dockerRegistry: "" -networkPolicy: - create: false - ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. - ## In order for a Pod to access OpenSearch, it needs to have the following label: - ## {{ template "uname" . }}-client: "true" - ## Example for default configuration to access HTTP port: - ## opensearch-master-http-client: "true" - ## Example for default configuration to access transport port: - ## opensearch-master-transport-client: "true" +master: + name: "opensearch-cluster-master" + clusterName: "opensearch-cluster" + nodeGroup: "master" + serviceName: "opensearch-cluster-master" + # If discovery.type in the opensearch configuration is set to "single-node", + # this should be set to "true" + # If "true", replicas will be forced to 1 + singleNode: false + # The service that non master groups will try to connect to when joining the cluster + # This should be set to clusterName + "-" + nodeGroup for your master group + masterService: "opensearch-cluster-master" + # OpenSearch roles that will be applied to this nodeGroup + # These will be set as environment variable "node.roles". E.g. node.roles=master,ingest,data,remote_cluster_client + roles: + - master + + replicas: 3 + + global: + # Set if you want to change the default docker registry, e.g. a private one. + dockerRegistry: "" + + # Allows you to add any config files in {{ .Values.opensearchHome }}/config + opensearchHome: /usr/share/opensearch + # such as opensearch.yml and log4j2.properties + config: + # Values must be YAML literal style scalar / YAML multiline string. + # : | + # + # log4j2.properties: | + # status = error + # + # appender.console.type = Console + # appender.console.name = console + # appender.console.layout.type = PatternLayout + # appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n + # + # rootLogger.level = info + # rootLogger.appenderRef.console.ref = console + opensearch.yml: | + cluster.name: opensearch-cluster + network.host: 0.0.0.0 + plugins: + security: + ssl: + transport: + pemcert_filepath: esnode.pem + pemkey_filepath: esnode-key.pem + pemtrustedcas_filepath: root-ca.pem + enforce_hostname_verification: false + http: + enabled: true + pemcert_filepath: esnode.pem + pemkey_filepath: esnode-key.pem + pemtrustedcas_filepath: root-ca.pem + allow_unsafe_democertificates: true + allow_default_init_securityindex: true + authcz: + admin_dn: + - CN=kirk,OU=client,O=client,L=test,C=de + audit.type: internal_opensearch + enable_snapshot_restore_privilege: true + check_snapshot_restore_write_privileges: true + restapi: + roles_enabled: ["all_access", "security_rest_api_access"] + system_indices: + enabled: true + indices: + [ + ".opendistro-alerting-config", + ".opendistro-alerting-alert*", + ".opendistro-anomaly-results*", + ".opendistro-anomaly-detector*", + ".opendistro-anomaly-checkpoints", + ".opendistro-anomaly-detection-state", + ".opendistro-reports-*", + ".opendistro-notifications-*", + ".opendistro-notebooks", + ".opendistro-asynchronous-search-response*", + ] + ######## End OpenSearch Security Demo Configuration ######## + # log4j2.properties: + # Extra environment variables to append to this nodeGroup + # This will be appended to the current 'env:' key. You can use any of the kubernetes env + # syntax here + extraEnvs: [] + # - name: MY_ENVIRONMENT_VAR + # value: the_value_goes_here + + # Allows you to load environment variables from kubernetes secret or config map + envFrom: [] + # - secretRef: + # name: env-secret + # - configMapRef: + # name: config-map + + # A list of secrets and their paths to mount inside the pod + # This is useful for mounting certificates for security and for mounting + # the X-Pack license + secretMounts: [] + + hostAliases: [] + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - "bar.local" + + image: + repository: "opensearchproject/opensearch" + # override image tag, which is .Chart.AppVersion by default + tag: "" + pullPolicy: "IfNotPresent" + + podAnnotations: {} + # iam.amazonaws.com/role: es-cluster + + # OpenSearch Statefulset annotations + openSearchAnnotations: {} + + # additionals labels + labels: + app.kubernetes.io/component: opensearch-cluster-master + app.kubernetes.io/instance: opensearch-master + + selectorLabels: + app.kubernetes.io/component: opensearch-cluster-master + app.kubernetes.io/instance: opensearch-master + + opensearchJavaOpts: "-Xmx1512M -Xms1512M" + + resources: + requests: + cpu: "1000m" + memory: "100Mi" + + initResources: {} + # limits: + # cpu: "25m" + # memory: "128Mi" + # requests: + # cpu: "25m" + # memory: "128Mi" + + sidecarResources: {} + # limits: + # cpu: "25m" + # memory: "128Mi" + # requests: + # cpu: "25m" + # memory: "128Mi" + + networkHost: "0.0.0.0" + + persistence: + enabled: true + # Set to false to disable the `fsgroup-volume` initContainer that will update permissions on the persistent disk. + enableInitChown: true + # override image, which is busybox by default + # image: busybox + # override image tag, which is latest by default + # imageTag: + labels: + # Add default labels for the volumeClaimTemplate of the StatefulSet + enabled: false + # OpenSearch Persistent Volume Storage Class + # If defined, storageClassName: + # If set to "-", storageClassName: "", which disables dynamic provisioning + # If undefined (the default) or set to null, no storageClassName spec is + # set, choosing the default provisioner. (gp2 on AWS, standard on + # GKE, AWS & OpenStack) + # + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + annotations: {} - http: + extraVolumes: [] + # - name: extras + # emptyDir: {} + + extraVolumeMounts: [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + + extraContainers: [] + # - name: do-something + # image: busybox + # command: ['do', 'something'] + + extraInitContainers: [] + # - name: do-somethings + # image: busybox + # command: ['do', 'something'] + + # This is the PriorityClass settings as defined in + # https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + priorityClassName: "" + + # By default this will make sure two pods don't end up on the same node + # Changing this to a region would allow you to spread pods across regions + antiAffinityTopologyKey: "kubernetes.io/hostname" + + # Hard means that by default pods will only be scheduled if there are enough nodes for them + # and that they will never end up on the same node. Setting this to soft will do this "best effort" + antiAffinity: "soft" + + # This is the node affinity settings as defined in + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature + nodeAffinity: {} + + # This is the pod topology spread constraints + # https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: [] + + # The default is to deploy all pods serially. By setting this to parallel all pods are started at + # the same time when bootstrapping the cluster + podManagementPolicy: "Parallel" + + # The environment variables injected by service links are not used, but can lead to slow OpenSearch boot times when + # there are many services in the current namespace. + # If you experience slow pod startups you probably want to set this to `false`. + enableServiceLinks: true + + protocol: https + httpPort: 9200 + transportPort: 9300 + metricsPort: 9600 + httpHostPort: "" + transportHostPort: "" + + service: + labels: {} + labelsHeadless: {} + headless: + annotations: {} + type: ClusterIP + # The IP family and IP families options are to set the behaviour in a dual-stack environment + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be + # + # ipFamilyPolicy: SingleStack + # ipFamilies: + # - IPv4 + nodePort: "" + annotations: {} + httpPortName: http + transportPortName: transport + metricsPortName: metrics + loadBalancerIP: "" + loadBalancerSourceRanges: [] + externalTrafficPolicy: "" + + updateStrategy: RollingUpdate + + # This is the max unavailable setting for the pod disruption budget + # The default value of 1 will make sure that kubernetes won't allow more than 1 + # of your pods to be unavailable during maintenance + maxUnavailable: 1 + + podSecurityContext: + fsGroup: 1000 + runAsUser: 1000 + + securityContext: + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + + securityConfig: + enabled: true + path: "/usr/share/opensearch/config/opensearch-security" + actionGroupsSecret: + configSecret: + internalUsersSecret: + rolesSecret: + rolesMappingSecret: + tenantsSecret: + # The following option simplifies securityConfig by using a single secret and + # specifying the config files as keys in the secret instead of creating + # different secrets for for each config file. + # Note that this is an alternative to the individual secret configuration + # above and shouldn't be used if the above secrets are used. + config: + # There are multiple ways to define the configuration here: + # * If you define anything under data, the chart will automatically create + # a secret and mount it. This is best option to choose if you want to override all the + # existing yml files at once. + # * If you define securityConfigSecret, the chart will assume this secret is + # created externally and mount it. This is best option to choose if your intention is to + # only update a single yml file. + # * It is an error to define both data and securityConfigSecret. + securityConfigSecret: "" + dataComplete: true + data: {} + # config.yml: |- + # internal_users.yml: |- + # roles.yml: |- + # roles_mapping.yml: |- + # action_groups.yml: |- + # tenants.yml: |- + + # How long to wait for opensearch to stop gracefully + terminationGracePeriod: 120 + + sysctlVmMaxMapCount: 262144 + + startupProbe: + tcpSocket: + port: 9200 + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 30 + + livenessProbe: {} + # periodSeconds: 20 + # timeoutSeconds: 5 + # failureThreshold: 10 + # successThreshold: 1 + # initialDelaySeconds: 10 + # tcpSocket: + # port: 9200 + + readinessProbe: + tcpSocket: + port: 9200 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + + ## Use an alternate scheduler. + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + + imagePullSecrets: [] + nodeSelector: {} + tolerations: [] + + nameOverride: "" + fullnameOverride: "" + + masterTerminationFix: false + + opensearchLifecycle: {} + # preStop: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the preStart handler > /usr/share/message"] + # postStart: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] + + lifecycle: {} + + keystore: [] + # To add secrets to the keystore: + # - secretName: opensearch-encryption-key + + # Deprecated + # please use the above podSecurityContext.fsGroup instead + fsGroup: "" + + ## Set optimal sysctl's through securityContext. This requires privilege. Can be disabled if + ## the system has already been preconfigured. (Ex: https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html) + ## Also see: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ + sysctl: enabled: false -# Deprecated -# please use the above podSecurityContext.fsGroup instead -fsGroup: "" - -## Set optimal sysctl's through securityContext. This requires privilege. Can be disabled if -## the system has already been preconfigured. (Ex: https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html) -## Also see: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ -sysctl: - enabled: false - -## Set optimal sysctl's through privileged initContainer. -sysctlInit: - enabled: false + ## Set optimal sysctl's through privileged initContainer. + sysctlInit: + enabled: false # override image, which is busybox by default # image: busybox # override image tag, which is latest by default # imageTag: -## Enable to add 3rd Party / Custom plugins not offered in the default OpenSearch image. -plugins: - enabled: false - installList: [] + ## Enable to add 3rd Party / Custom plugins not offered in the default OpenSearch image. + plugins: + enabled: false + installList: [] # - example-fake-plugin -# -- Array of extra K8s manifests to deploy -extraObjects: [] - # - apiVersion: secrets-store.csi.x-k8s.io/v1 - # kind: SecretProviderClass - # metadata: - # name: argocd-secrets-store - # spec: - # provider: aws - # parameters: - # objects: | - # - objectName: "argocd" - # objectType: "secretsmanager" - # jmesPath: - # - path: "client_id" - # objectAlias: "client_id" - # - path: "client_secret" - # objectAlias: "client_secret" - # secretObjects: - # - data: - # - key: client_id - # objectName: client_id - # - key: client_secret - # objectName: client_secret - # secretName: argocd-secrets-store - # type: Opaque - # labels: - # app.kubernetes.io/part-of: argocd - # - | - # apiVersion: policy/v1 - # kind: PodDisruptionBudget - # metadata: - # name: {{ template "opensearch.uname" . }} - # labels: - # {{- include "opensearch.labels" . | nindent 4 }} - # spec: - # minAvailable: 1 - # selector: - # matchLabels: - # {{- include "opensearch.selectorLabels" . | nindent 6 }} +data: + name: "opensearch-cluster-data" + clusterName: "opensearch-cluster" + nodeGroup: "data" + serviceName: "opensearch-cluster-data" + # If discovery.type in the opensearch configuration is set to "single-node", + # this should be set to "true" + # If "true", replicas will be forced to 1 + singleNode: false + # The service that non master groups will try to connect to when joining the cluster + # This should be set to clusterName + "-" + nodeGroup for your master group + masterService: "opensearch-cluster-data" + # OpenSearch roles that will be applied to this nodeGroup + # These will be set as environment variable "node.roles". E.g. node.roles=master,ingest,data,remote_cluster_client + roles: + - ingest + - data + - remote_cluster_client + + replicas: 3 + + global: + # Set if you want to change the default docker registry, e.g. a private one. + dockerRegistry: "" + + # Allows you to add any config files in {{ .Values.opensearchHome }}/config + opensearchHome: /usr/share/opensearch + # such as opensearch.yml and log4j2.properties + config: + # Values must be YAML literal style scalar / YAML multiline string. + # : | + # + # log4j2.properties: | + # status = error + # + # appender.console.type = Console + # appender.console.name = console + # appender.console.layout.type = PatternLayout + # appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n + # + # rootLogger.level = info + # rootLogger.appenderRef.console.ref = console + opensearch.yml: | + cluster.name: opensearch-cluster + network.host: 0.0.0.0 + plugins: + security: + ssl: + transport: + pemcert_filepath: esnode.pem + pemkey_filepath: esnode-key.pem + pemtrustedcas_filepath: root-ca.pem + enforce_hostname_verification: false + http: + enabled: true + pemcert_filepath: esnode.pem + pemkey_filepath: esnode-key.pem + pemtrustedcas_filepath: root-ca.pem + allow_unsafe_democertificates: true + allow_default_init_securityindex: true + authcz: + admin_dn: + - CN=kirk,OU=client,O=client,L=test,C=de + audit.type: internal_opensearch + enable_snapshot_restore_privilege: true + check_snapshot_restore_write_privileges: true + restapi: + roles_enabled: ["all_access", "security_rest_api_access"] + system_indices: + enabled: true + indices: + [ + ".opendistro-alerting-config", + ".opendistro-alerting-alert*", + ".opendistro-anomaly-results*", + ".opendistro-anomaly-detector*", + ".opendistro-anomaly-checkpoints", + ".opendistro-anomaly-detection-state", + ".opendistro-reports-*", + ".opendistro-notifications-*", + ".opendistro-notebooks", + ".opendistro-asynchronous-search-response*", + ] + ######## End OpenSearch Security Demo Configuration ######## + # log4j2.properties: + + + # Extra environment variables to append to this nodeGroup + # This will be appended to the current 'env:' key. You can use any of the kubernetes env + # syntax here + extraEnvs: [] + # - name: MY_ENVIRONMENT_VAR + # value: the_value_goes_here + # Allows you to load environment variables from kubernetes secret or config map + envFrom: [] + # - secretRef: + # name: env-secret + # - configMapRef: + # name: config-map + # A list of secrets and their paths to mount inside the pod + # This is useful for mounting certificates for security and for mounting + # the X-Pack license + secretMounts: [] + hostAliases: [] + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - "bar.local" + + image: + repository: "opensearchproject/opensearch" + # override image tag, which is .Chart.AppVersion by default + tag: "" + pullPolicy: "IfNotPresent" + + podAnnotations: {} + # iam.amazonaws.com/role: es-cluster + + # OpenSearch Statefulset annotations + openSearchAnnotations: {} + + # additionals labels + labels: + app.kubernetes.io/component: opensearch-cluster-data + app.kubernetes.io/instance: opensearch-data + + selectorLabels: + app.kubernetes.io/component: opensearch-cluster-data + app.kubernetes.io/instance: opensearch-data + + opensearchJavaOpts: "-Xmx1512M -Xms1512M" + + resources: + requests: + cpu: "1000m" + memory: "100Mi" + + initResources: {} + # limits: + # cpu: "25m" + # memory: "128Mi" + # requests: + # cpu: "25m" + # memory: "128Mi" + + sidecarResources: {} + # limits: + # cpu: "25m" + # memory: "128Mi" + # requests: + # cpu: "25m" + # memory: "128Mi" + networkHost: "0.0.0.0" + + persistence: + enabled: true + # Set to false to disable the `fsgroup-volume` initContainer that will update permissions on the persistent disk. + enableInitChown: true + # override image, which is busybox by default + # image: busybox + # override image tag, which is latest by default + # imageTag: + labels: + # Add default labels for the volumeClaimTemplate of the StatefulSet + enabled: false + # OpenSearch Persistent Volume Storage Class + # If defined, storageClassName: + # If set to "-", storageClassName: "", which disables dynamic provisioning + # If undefined (the default) or set to null, no storageClassName spec is + # set, choosing the default provisioner. (gp2 on AWS, standard on + # GKE, AWS & OpenStack) + # + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 20Gi + annotations: {} + + extraVolumes: [] + # - name: extras + # emptyDir: {} + extraVolumeMounts: [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + extraContainers: [] + # - name: do-something + # image: busybox + # command: ['do', 'something'] + extraInitContainers: [] + # - name: do-somethings + # image: busybox + # command: ['do', 'something'] + + # This is the PriorityClass settings as defined in + # https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + priorityClassName: "" + # By default this will make sure two pods don't end up on the same node + # Changing this to a region would allow you to spread pods across regions + antiAffinityTopologyKey: "kubernetes.io/hostname" + + # Hard means that by default pods will only be scheduled if there are enough nodes for them + # and that they will never end up on the same node. Setting this to soft will do this "best effort" + antiAffinity: "soft" + + # This is the node affinity settings as defined in + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature + nodeAffinity: {} + + # This is the pod topology spread constraints + # https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: [] + # The default is to deploy all pods serially. By setting this to parallel all pods are started at + # the same time when bootstrapping the cluster + podManagementPolicy: "Parallel" + + # The environment variables injected by service links are not used, but can lead to slow OpenSearch boot times when + # there are many services in the current namespace. + # If you experience slow pod startups you probably want to set this to `false`. + enableServiceLinks: true + + protocol: https + httpPort: 9200 + transportPort: 9300 + metricsPort: 9600 + httpHostPort: "" + transportHostPort: "" + + service: + labels: {} + labelsHeadless: {} + headless: + annotations: {} + type: ClusterIP + # The IP family and IP families options are to set the behaviour in a dual-stack environment + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be + # + # ipFamilyPolicy: SingleStack + # ipFamilies: + # - IPv4 + nodePort: "" + annotations: {} + httpPortName: http + transportPortName: transport + metricsPortName: metrics + loadBalancerIP: "" + loadBalancerSourceRanges: [] + externalTrafficPolicy: "" + + updateStrategy: RollingUpdate + + # This is the max unavailable setting for the pod disruption budget + # The default value of 1 will make sure that kubernetes won't allow more than 1 + # of your pods to be unavailable during maintenance + maxUnavailable: 1 + + podSecurityContext: + fsGroup: 1000 + runAsUser: 1000 + + securityContext: + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + + securityConfig: + enabled: true + path: "/usr/share/opensearch/config/opensearch-security" + actionGroupsSecret: + configSecret: + internalUsersSecret: + rolesSecret: + rolesMappingSecret: + tenantsSecret: + # The following option simplifies securityConfig by using a single secret and + # specifying the config files as keys in the secret instead of creating + # different secrets for for each config file. + # Note that this is an alternative to the individual secret configuration + # above and shouldn't be used if the above secrets are used. + config: + # There are multiple ways to define the configuration here: + # * If you define anything under data, the chart will automatically create + # a secret and mount it. This is best option to choose if you want to override all the + # existing yml files at once. + # * If you define securityConfigSecret, the chart will assume this secret is + # created externally and mount it. This is best option to choose if your intention is to + # only update a single yml file. + # * It is an error to define both data and securityConfigSecret. + securityConfigSecret: "" + dataComplete: true + data: {} + # config.yml: |- + # internal_users.yml: |- + # roles.yml: |- + # roles_mapping.yml: |- + # action_groups.yml: |- + # tenants.yml: |- + # How long to wait for opensearch to stop gracefully + terminationGracePeriod: 120 + sysctlVmMaxMapCount: 262144 + startupProbe: + tcpSocket: + port: 9200 + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 30 + + livenessProbe: {} + # periodSeconds: 20 + # timeoutSeconds: 5 + # failureThreshold: 10 + # successThreshold: 1 + # initialDelaySeconds: 10 + # tcpSocket: + # port: 9200 + + readinessProbe: + tcpSocket: + port: 9200 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + + ## Use an alternate scheduler. + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + imagePullSecrets: [] + nodeSelector: {} + tolerations: [] + nameOverride: "" + fullnameOverride: "" + masterTerminationFix: false + opensearchLifecycle: {} + # preStop: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the preStart handler > /usr/share/message"] + # postStart: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] + lifecycle: {} + keystore: [] + # To add secrets to the keystore: + # - secretName: opensearch-encryption-key + # Deprecated + # please use the above podSecurityContext.fsGroup instead + fsGroup: "" + ## Set optimal sysctl's through securityContext. This requires privilege. Can be disabled if + ## the system has already been preconfigured. (Ex: https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html) + ## Also see: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ + sysctl: + enabled: false + ## Set optimal sysctl's through privileged initContainer. + sysctlInit: + enabled: false + ## Enable to add 3rd Party / Custom plugins not offered in the default OpenSearch image. + plugins: + enabled: false + installList: [] + # - example-fake-plugin