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