Skip to content

Instantly share code, notes, and snippets.

@pai911
Created April 28, 2020 03:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pai911/6d0002ad7a64b3b854ff8d48f4d34936 to your computer and use it in GitHub Desktop.
Save pai911/6d0002ad7a64b3b854ff8d48f4d34936 to your computer and use it in GitHub Desktop.
Add Init Script to Solr Helm chart
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "solr.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "solr.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Define the name of the headless service for solr
*/}}
{{- define "solr.headless-service-name" -}}
{{- printf "%s-%s" (include "solr.fullname" .) "headless" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Define the name of the client service for solr
*/}}
{{- define "solr.service-name" -}}
{{- printf "%s-%s" (include "solr.fullname" .) "svc" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Define the name of the solr exporter
*/}}
{{- define "solr.exporter-name" -}}
{{- printf "%s-%s" (include "solr.fullname" .) "exporter" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
The name of the zookeeper service
*/}}
{{- define "solr.zookeeper-name" -}}
{{- printf "%s-%s" .Release.Name "zookeeper" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
The name of the zookeeper headless service
*/}}
{{- define "solr.zookeeper-service-name" -}}
{{ printf "%s-%s" (include "solr.zookeeper-name" .) "headless" | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "solr.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Define the name of the solr PVC
*/}}
{{- define "solr.pvc-name" -}}
{{ printf "%s-%s" (include "solr.fullname" .) "pvc" | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{/*
Define the name of the solr.xml configmap
*/}}
{{- define "solr.configmap-name" -}}
{{- printf "%s-%s" (include "solr.fullname" .) "config-map" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Define the name of the custom script configmap
*/}}
{{- define "solr.custom-script.configmap-name" -}}
{{- printf "%s-%s" (include "solr.fullname" .) "custom-script-config-map" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Define the labels that should be applied to all resources in the chart
*/}}
{{- define "solr.common.labels" -}}
app.kubernetes.io/name: {{ include "solr.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ include "solr.chart" . }}
{{- end -}}
{{/*
Return the proper Docker Image Registry Secret Names
*/}}
{{- define "solr.imagePullSecrets" -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
Also, we can not use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.global.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- else if or .Values.image.pullSecrets .Values.exporter.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- range .Values.exporter.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end -}}
{{- else if or .Values.image.pullSecrets .Values.exporter.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- range .Values.exporter.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end -}}
{{- end -}}
{{ if not ( eq .Values.initScript "" ) }}
---
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "{{ include "solr.custom-script.configmap-name" . }}"
labels:
{{ include "solr.common.labels" . | indent 4}}
data:
solr-init.sh: |
{{ .Files.Get .Values.initScript | indent 4}}
{{ end }}
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "solr.fullname" . }}
labels:
{{ include "solr.common.labels" . | indent 4 }}
app.kubernetes.io/component: server
spec:
selector:
matchLabels:
app.kubernetes.io/name: "{{ include "solr.name" . }}"
app.kubernetes.io/instance: "{{ .Release.Name }}"
app.kubernetes.io/component: "server"
serviceName: {{ include "solr.headless-service-name" . }}
replicas: {{ .Values.replicaCount }}
updateStrategy:
{{ toYaml .Values.updateStrategy | indent 4}}
template:
metadata:
labels:
app.kubernetes.io/name: "{{ include "solr.name" . }}"
app.kubernetes.io/instance: "{{ .Release.Name }}"
app.kubernetes.io/component: "server"
annotations:
{{ toYaml .Values.podAnnotations | indent 8 }}
spec:
{{- include "solr.imagePullSecrets" . | indent 6 }}
{{- if .Values.schedulerName }}
schedulerName: "{{ .Values.schedulerName }}"
{{- end }}
securityContext:
fsGroup: 8983
runAsUser: 8983
affinity:
{{ tpl (toYaml .Values.affinity) . | indent 8 }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
volumes:
{{- if .Values.tls.enabled }}
- name: keystore-volume
emptyDir: {}
- name: "tls-secret"
secret:
secretName: {{ .Values.tls.certSecret.name }}
{{- if not (eq .Values.tls.caSecret.name "") }}
- name: "tls-ca"
secret:
secretName: {{ .Values.tls.caSecret.name }}
{{- end }}
{{- end }}
- name: solr-xml
configMap:
name: {{ include "solr.configmap-name" . }}
items:
- key: solr.xml
path: solr.xml
{{- if not ( eq .Values.initScript "" ) }}
- name: solr-init-script
configMap:
name: {{ include "solr.custom-script.configmap-name" . }}
items:
- key: solr-init.sh
path: solr-init.sh
{{- end }}
initContainers:
- name: check-zk
image: busybox:latest
command:
- 'sh'
- '-c'
- |
COUNTER=0;
while [ $COUNTER -lt 120 ]; do
addr=$(nslookup -type=a {{ include "solr.zookeeper-service-name" . }} | grep "Address:" | awk 'NR>1 {print $2}')
if [ ! -z "$addr" ]; then
while read -r line; do
echo $line;
mode=$(echo srvr | nc $line 2181 | grep "Mode");
echo $mode;
if [ "$mode" = "Mode: leader" ] || [ "$mode" = "Mode: standalone" ]; then
echo "Found a leader!";
exit 0;
fi;
done <<EOF
$addr
EOF
fi;
let COUNTER=COUNTER+1;
sleep 2;
done;
echo "Did NOT see a ZK leader after 240 secs!";
exit 1;
- name: "cp-solr-xml"
image: busybox:latest
command: ['sh', '-c', 'cp /tmp/solr.xml /tmp-config/solr.xml']
volumeMounts:
- name: "solr-xml"
mountPath: "/tmp"
- name: "{{ include "solr.pvc-name" . }}"
mountPath: "/tmp-config"
{{- if .Values.tls.enabled }}
- name: "setup-keystore-and-properties"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
command:
- "sh"
- "-c"
- |
set -e
PKCS12_OUTPUT=/tmp/keystore.pkcs12
DEST_KEYSTORE="/tmp/keystore/solr.jks"
TRUST_KEYSTORE="/tmp/keystore/solr-truststore.jks"
PASSWORD={{ .Values.tls.keystorePassword }}
openssl "pkcs12" -export -inkey "/tmp/tls_secret/{{.Values.tls.certSecret.keyPath }}" -in "/tmp/tls_secret/{{.Values.tls.certSecret.certPath }}" -out "${PKCS12_OUTPUT}" -password "pass:${PASSWORD}"
keytool -importkeystore -noprompt -srckeystore "${PKCS12_OUTPUT}" -srcstoretype "pkcs12" -destkeystore "${DEST_KEYSTORE}" -storepass "${PASSWORD}" -srcstorepass "${PASSWORD}"
{{ if .Values.tls.importKubernetesCA }}
csplit -z -f crt- /var/run/secrets/kubernetes.io/serviceaccount/ca.crt '/-----BEGIN CERTIFICATE-----/' '{*}'
for file in crt-*; do
keytool -import -noprompt -keystore "${TRUST_KEYSTORE}" -file "${file}" -storepass "${PASSWORD}" -alias service-$file;
done
rm crt-*
{{ end }}
{{ if not (eq .Values.tls.caSecret.name "") }}
csplit -z -f crt- /tmp/tls_ca/{{ .Values.tls.caSecret.bundlePath }} '/-----BEGIN CERTIFICATE-----/' '{*}'
for file in crt-*; do
keytool -import -noprompt -keystore "${TRUST_KEYSTORE}" -file "${file}" -storepass "${PASSWORD}" -alias service-$file;
done
rm crt-*
{{ end }}
/opt/solr/server/scripts/cloud-scripts/zkcli.sh -zkhost "{{ include "solr.zookeeper-service-name" . }}:2181" -cmd clusterprop -name urlScheme -val https
volumeMounts:
- name: "keystore-volume"
mountPath: "/tmp/keystore"
- name: "tls-secret"
mountPath: "/tmp/tls_secret"
readOnly: true
{{ if not (eq .Values.tls.caSecret.name "") }}
- name: "tls-ca"
mountPath: "/tmp/tls_ca"
readOnly: true
{{ end }}
{{ end }}
containers:
- name: solr
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources:
{{ toYaml .Values.resources | indent 12 }}
ports:
- containerPort: {{ .Values.port }}
name: solr-client
env:
- name: "SOLR_JAVA_MEM"
value: "{{ .Values.javaMem }}"
- name: "SOLR_HOME"
value: "/opt/solr/server/home"
- name: "SOLR_PORT"
value: "{{ .Values.port }}"
- name: "POD_HOSTNAME"
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: "SOLR_HOST"
value: "$(POD_HOSTNAME).{{ include "solr.headless-service-name" . }}.{{ .Release.Namespace }}"
- name: "ZK_HOST"
value: "{{ include "solr.zookeeper-service-name" . }}:2181"
- name: "SOLR_LOG_LEVEL"
value: "{{ .Values.logLevel }}"
{{- if .Values.extraEnvVars }}
{{ toYaml .Values.extraEnvVars | indent 12 }}
{{- end }}
{{ if .Values.tls.enabled }}
- name: "SOLR_SSL_ENABLED"
value: "true"
- name: "SOLR_SSL_KEY_STORE"
value: "/etc/ssl/keystores/solr.jks"
- name: "SOLR_SSL_KEY_STORE_PASSWORD"
value: "{{ .Values.tls.keystorePassword }}"
- name: "SOLR_SSL_TRUST_STORE"
value: "/etc/ssl/keystores/solr-truststore.jks"
- name: "SOLR_SSL_TRUST_STORE_PASSWORD"
value: "{{ .Values.tls.keystorePassword }}"
- name: "SOLR_SSL_WANT_CLIENT_AUTH"
value: "{{ .Values.tls.wantClientAuth }}"
- name: "SOLR_SSL_NEED_CLIENT_AUTH"
value: "{{ .Values.tls.needClientAuth }}"
- name: "SOLR_SSL_CHECK_PEER_NAME"
value: "{{ .Values.tls.checkPeerName }}"
{{ end }}
livenessProbe:
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
httpGet:
scheme: "{{ .Values.tls.enabled | ternary "HTTPS" "HTTP" }}"
path: /solr/admin/info/system
port: {{ .Values.port }}
readinessProbe:
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
httpGet:
scheme: "{{ .Values.tls.enabled | ternary "HTTPS" "HTTP" }}"
path: /solr/admin/info/system
port: {{ .Values.port }}
volumeMounts:
- name: {{ include "solr.pvc-name" . }}
mountPath: /opt/solr/server/home
{{- if not ( eq .Values.initScript "" ) }}
- name: solr-init-script
mountPath: /docker-entrypoint-initdb.d
{{- end }}
{{ if .Values.tls.enabled }}
- name: "keystore-volume"
mountPath: "/etc/ssl/keystores"
{{ end }}
volumeClaimTemplates:
- metadata:
name: {{ include "solr.pvc-name" . }}
annotations:
pv.beta.kubernetes.io/gid: "8983"
spec:
accessModes:
{{ toYaml .Values.volumeClaimTemplates.accessModes | indent 10 }}
{{- if not ( eq .Values.volumeClaimTemplates.storageClassName "" ) }}
storageClassName: "{{ .Values.volumeClaimTemplates.storageClassName }}"
{{- end }}
resources:
requests:
storage: {{ .Values.volumeClaimTemplates.storageSize }}
---
## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imagePullSecrets
##
# global:
# imagePullSecrets:
# - myRegistryKeySecretName
# Which port should solr listen on
port: 8983
# Number of solr instances to run
replicaCount: 3
# Settings for solr java memory
javaMem: "-Xms2g -Xmx3g"
# Set the limits and requests on solr pod resources
resources: {}
# Extra environment variables - allows yaml definitions
extraEnvVars: []
# Specify the initial script file name here to be executed before starting Solr
# The file is located relative to the solr chart root folder
initScript: ""
# Sets the termination Grace period for the solr pods
# This can take a while for shards to elect new leaders
terminationGracePeriodSeconds: 180
# Solr image settings
image:
repository: solr
tag: 8.4.0
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistryKeySecretName
# Solr pod liveness
livenessProbe:
initialDelaySeconds: 45
periodSeconds: 10
# Solr pod readiness
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 5
# Annotations to apply to the solr pods
podAnnotations: {}
# Affinity group rules or the solr pods
affinity: {}
# Update Strategy for solr pods
updateStrategy:
type: "RollingUpdate"
# The log level of the Solr instances
logLevel: "INFO"
# Solr pod disruption budget
podDisruptionBudget:
maxUnavailable: 1
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
# Configuration for the solr PVC
volumeClaimTemplates:
storageClassName: ""
storageSize: "20Gi"
accessModes:
- "ReadWriteOnce"
# Configuration for solr TLS handling, see README.md for more instructions
tls:
enabled: false
wantClientAuth: "false"
needClientAuth: "false"
keystorePassword: "changeit"
importKubernetesCA: "false"
checkPeerName: "false"
caSecret:
name: ""
bundlePath: ""
certSecret:
name: ""
keyPath: "tls.key"
certPath: "tls.crt"
# Configuration for the solr service
service:
type: ClusterIP
annotations: {}
# Configuration for the solr prometheus exporter
exporter:
image: {}
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistryKeySecretName
enabled: false # Deploy the exporter
configFile: "/opt/solr/contrib/prometheus-exporter/conf/solr-exporter-config.xml" # The config file to point the exporter to
updateStrategy: {}
podAnnotations: {} # Annotations to apply to the exporter pod
resources: {} # Resource limits for the exporter
port: 9983 # The port to run the exporter on
threads: 7 # The number of threads the exporter uses to query solr
livenessProbe: # Liveness configuration for exporter pod
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe: # Readiness configuration for exporter pod
initialDelaySeconds: 15
periodSeconds: 5
service:
type: "ClusterIP"
annotations: {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment