vvp -- VNF Validation Platform
[oom.git] / kubernetes / common / mysql / templates / statefulset.yaml
1 {{/*
2 # Copyright © 2017 Amdocs, Bell Canada
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #       http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 */}}
16
17 apiVersion: apps/v1beta1
18 kind: StatefulSet
19 metadata:
20   name: {{ include "common.fullname" . }}
21   namespace: {{ include "common.namespace" . }}
22   labels:
23     app: {{ include "common.name" . }}
24     chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
25     release: {{ .Release.Name }}
26     heritage: {{ .Release.Service }}
27 spec:
28   serviceName: {{ .Values.service.name }}
29   replicas: {{ .Values.replicaCount }}
30   template:
31     metadata:
32       labels:
33         app: {{ include "common.name" . }}
34         release: {{ .Release.Name }}
35     spec:
36       initContainers:
37 #{{ if not .Values.disableNfsProvisioner }}
38       - name: {{ include "common.name" . }}-readiness
39         command:
40         - /root/ready.py
41         args:
42         - --container-name
43         - {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner
44         env:
45         - name: NAMESPACE
46           valueFrom:
47             fieldRef:
48               apiVersion: v1
49               fieldPath: metadata.namespace
50         image: "{{ .Values.global.readinessRepository }}/{{ .Values.global.readinessImage }}"
51         imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
52 #{{ end }}
53       - name: init-mysql
54         image: "{{ .Values.dockerHubRepository }}/{{ .Values.image }}"
55         imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
56         command:
57         - bash
58         - "-c"
59         - |
60           set -ex
61           # Generate mysql server-id from pod ordinal index.
62           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
63           ordinal=${BASH_REMATCH[1]}
64           siteId={{ .Values.geoSiteId }}
65           echo BASH_REMATCH=${BASH_REMATCH}
66           echo [mysqld] > /mnt/conf.d/server-id.cnf
67           # Add an offset to avoid reserved server-id=0 value.
68           echo server-id=$(($siteId*100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
69           # Copy appropriate conf.d files from config-map to emptyDir.
70           if [[ $ordinal -eq 0 ]]; then
71             cp /mnt/config-map/master.cnf /mnt/conf.d/
72           else
73             cp /mnt/config-map/slave.cnf /mnt/conf.d/
74           fi
75         volumeMounts:
76         - name: conf
77           mountPath: /mnt/conf.d
78         - name: config-map
79           mountPath: /mnt/config-map
80
81       - name: clone-mysql
82         image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}"
83         imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
84         env:
85           - name: MYSQL_ROOT_PASSWORD
86             valueFrom:
87               secretKeyRef:
88                 name: {{ template "common.fullname" . }}
89                 key: db-root-password
90         command:
91         - bash
92         - "-c"
93         - |
94           set -ex
95           # Skip the clone if data already exists.
96           [[ -d /var/lib/mysql/mysql ]] && exit 0
97           # Skip the clone on master (ordinal index 0).
98           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
99           ordinal=${BASH_REMATCH[1]}
100           echo ${BASH_REMATCH}
101           [[ $ordinal -eq 0 ]] && exit 0
102           # Clone data from previous peer.
103           ncat --recv-only {{ include "common.fullname" . }}-$(($ordinal-1)).{{ .Values.service.name }}.{{ include "common.namespace" . }} 3307 | xbstream -x -C {{ .Values.persistence.mysqlPath }}
104           # Prepare the backup.
105           xtrabackup --user=root --password=$MYSQL_ROOT_PASSWORD --prepare --target-dir=/var/lib/mysql
106           ls -l {{ .Values.persistence.mysqlPath }}
107         volumeMounts:
108         - name: {{ include "common.fullname" . }}-mysql
109           mountPath: {{ .Values.persistence.mysqlPath }}
110         - name: conf
111           mountPath: /etc/mysql/conf.d
112
113       containers:
114         - name: {{ include "common.name" . }}
115           image: "{{ .Values.dockerHubRepository }}/{{ .Values.image }}"
116           imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
117           ports:
118           - containerPort: {{ .Values.service.internalPort }}
119           # disable liveness probe when breakpoints set in debugger
120           # so K8s doesn't restart unresponsive container
121           {{- if eq .Values.liveness.enabled true }}
122           livenessProbe:
123             exec:
124               command: ["mysqladmin", "ping"]
125             initialDelaySeconds: {{ .Values.liveness.initialDelaySeconds }}
126             periodSeconds: {{ .Values.liveness.periodSeconds }}
127             timeoutSeconds: {{ .Values.liveness.timeoutSeconds }}
128           {{end -}}
129           readinessProbe:
130             tcpSocket:
131               port: {{ .Values.service.internalPort }}
132             initialDelaySeconds: {{ .Values.readiness.initialDelaySeconds }}
133             periodSeconds: {{ .Values.readiness.periodSeconds }}
134           env:
135             - name: MYSQL_ROOT_PASSWORD
136               valueFrom:
137                 secretKeyRef:
138                   name: {{ template "common.fullname" . }}
139                   key: db-root-password
140             - name: MYSQL_ROOT_HOST
141               value: '%'
142             - name: MYSQL_ALLOW_EMPTY_PASSWORD
143               value: {{ .Values.config.dbAllowEmptyPassword | default "0" | quote }}
144           volumeMounts:
145           - mountPath: {{ .Values.persistence.mysqlPath }}
146             name: {{ include "common.fullname" . }}-mysql
147           - mountPath: /etc/mysql/conf.d
148             name: conf
149           resources:
150 {{ include "common.resources" . | indent 12 }}
151         {{- if .Values.nodeSelector }}
152         nodeSelector:
153 {{ toYaml .Values.nodeSelector | indent 10 }}
154         {{- end -}}
155         {{- if .Values.affinity }}
156         affinity:
157 {{ toYaml .Values.affinity | indent 10 }}
158         {{- end }}
159
160         - name: xtrabackup
161           image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}"
162           imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
163           env:
164             - name: MYSQL_ROOT_PASSWORD
165               valueFrom:
166                 secretKeyRef:
167                   name: {{ template "common.fullname" . }}
168                   key: db-root-password
169           ports:
170           - containerPort: {{ .Values.xtrabackup.internalPort }}
171             name: xtrabackup
172           command:
173           - bash
174           - "-c"
175           - |
176             set -ex
177             cd {{ .Values.persistence.mysqlPath }}
178             ls -l
179             # Determine binlog position of cloned data, if any.
180             if [[ -f xtrabackup_slave_info ]]; then
181               echo "Inside xtrabackup_slave_info"
182               # XtraBackup already generated a partial "CHANGE MASTER TO" query
183               # because we're cloning from an existing slave.
184               mv xtrabackup_slave_info change_master_to.sql.in
185               # Ignore xtrabackup_binlog_info in this case (it's useless).
186               rm -f xtrabackup_binlog_info
187             elif [[ -f xtrabackup_binlog_info ]]; then
188               echo "Inside xtrabackup_binlog_info"
189               # We're cloning directly from master. Parse binlog position.
190               [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
191               rm xtrabackup_binlog_info
192               echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
193                     MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
194             fi
195
196             [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
197             ordinal=${BASH_REMATCH[1]}
198             echo $ordinal
199
200             mysqlhost={{ include "common.fullname" . }}-$(($ordinal)).{{ .Values.service.name }}.{{ include "common.namespace" . }}
201             echo $mysqlhost
202
203             # Check if we need to complete a clone by starting replication.
204             if [[ -f change_master_to.sql.in ]]; then
205               echo "Waiting for mysqld to be ready (accepting connections)"
206               until mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h $mysqlhost -e "SELECT 1"; do sleep 1; done
207
208               echo "Initializing replication from clone position"
209               # In case of container restart, attempt this at-most-once.
210               mv change_master_to.sql.in change_master_to.sql.orig
211               mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h $mysqlhost <<EOF
212             $(<change_master_to.sql.orig),
213               MASTER_HOST="{{ include "common.fullname" . }}-0.{{ .Values.service.name }}.{{ include "common.namespace" . }}",
214               MASTER_USER="root",
215               MASTER_PASSWORD="$MYSQL_ROOT_PASSWORD",
216               MASTER_CONNECT_RETRY=10;
217             START SLAVE;
218             EOF
219             fi
220
221             # Start a server to send backups when requested by peers.
222             exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
223               "xtrabackup --user=root --password=$MYSQL_ROOT_PASSWORD --backup --slave-info --stream=xbstream --host=$mysqlhost"
224           volumeMounts:
225           - name: {{ include "common.fullname" . }}-mysql
226             mountPath: {{ .Values.persistence.mysqlPath }}
227           - name: conf
228             mountPath: /etc/mysql/conf.d
229       volumes:
230       - name: conf
231         emptyDir: {}
232       - name: config-map
233         configMap:
234           name: {{ include "common.fullname" . }}-db-configmap
235       - name: localtime
236         hostPath:
237           path: /etc/localtime
238       - name: {{ include "common.fullname" . }}-mysql
239   {{ if not .Values.persistence.enabled }}
240       - name: {{ include "common.fullname" . }}-mysql
241         emptyDir: {}
242   {{ else }}
243   volumeClaimTemplates:
244   - metadata:
245       name: {{ include "common.fullname" . }}-mysql
246       labels:
247         name: {{ include "common.fullname" . }}
248     spec:
249       accessModes: [ {{ .Values.persistence.accessMode }} ]
250       storageClassName: {{ include "common.fullname" . }}-mysql
251       resources:
252         requests:
253           storage: {{ .Values.persistence.size }}
254   {{ end }}