| apiVersion: apps/v1beta1 |
| kind: StatefulSet |
| metadata: |
| name: {{ include "common.fullname" . }} |
| namespace: {{ include "common.namespace" . }} |
| labels: |
| app: {{ include "common.name" . }} |
| chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} |
| release: {{ .Release.Name }} |
| heritage: {{ .Release.Service }} |
| spec: |
| serviceName: {{ .Values.service.name }} |
| replicas: {{ .Values.replicaCount }} |
| template: |
| metadata: |
| labels: |
| app: {{ include "common.name" . }} |
| release: {{ .Release.Name }} |
| spec: |
| initContainers: |
| #{{ if not .Values.disableNfsProvisioner }} |
| - name: {{ include "common.name" . }}-readiness |
| command: |
| - /root/ready.py |
| args: |
| - --container-name |
| - {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner |
| env: |
| - name: NAMESPACE |
| valueFrom: |
| fieldRef: |
| apiVersion: v1 |
| fieldPath: metadata.namespace |
| image: "{{ .Values.global.readinessRepository }}/{{ .Values.global.readinessImage }}" |
| imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} |
| #{{ end }} |
| - name: init-mysql |
| image: "{{ .Values.repository | default .Values.repository }}/{{ .Values.image }}" |
| imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} |
| command: |
| - bash |
| - "-c" |
| - | |
| set -ex |
| # Generate mysql server-id from pod ordinal index. |
| [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 |
| ordinal=${BASH_REMATCH[1]} |
| echo BASH_REMATCH=${BASH_REMATCH} |
| echo [mysqld] > /mnt/conf.d/server-id.cnf |
| # Add an offset to avoid reserved server-id=0 value. |
| echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf |
| # Copy appropriate conf.d files from config-map to emptyDir. |
| if [[ $ordinal -eq 0 ]]; then |
| cp /mnt/config-map/master.cnf /mnt/conf.d/ |
| else |
| cp /mnt/config-map/slave.cnf /mnt/conf.d/ |
| fi |
| volumeMounts: |
| - name: conf |
| mountPath: /mnt/conf.d |
| - name: config-map |
| mountPath: /mnt/config-map |
| |
| - name: clone-mysql |
| image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}" |
| imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} |
| env: |
| - name: MYSQL_ROOT_PASSWORD |
| valueFrom: |
| secretKeyRef: |
| name: {{ template "common.fullname" . }} |
| key: db-root-password |
| command: |
| - bash |
| - "-c" |
| - | |
| set -ex |
| # Skip the clone if data already exists. |
| [[ -d /var/lib/mysql/mysql ]] && exit 0 |
| # Skip the clone on master (ordinal index 0). |
| [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 |
| ordinal=${BASH_REMATCH[1]} |
| echo ${BASH_REMATCH} |
| [[ $ordinal -eq 0 ]] && exit 0 |
| # Clone data from previous peer. |
| ncat --recv-only {{ template "common.name" . }}-$(($ordinal-1)).{{ .Values.service.name }}.{{ include "common.namespace" . }} 3307 | xbstream -x -C /var/lib/mysql |
| # Prepare the backup. |
| xtrabackup --user=root --password=$MYSQL_ROOT_PASSWORD --prepare --target-dir=/var/lib/mysql |
| ls -l /var/lib/mysql |
| volumeMounts: |
| - name: {{ include "common.fullname" . }}-data |
| mountPath: /var/lib/mysql |
| subPath: mysql |
| - name: conf |
| mountPath: /etc/mysql/conf.d |
| |
| containers: |
| #sdnc-db-container |
| - name: {{ include "common.name" . }} |
| image: "{{ .Values.repository | default .Values.repository }}/{{ .Values.image }}" |
| imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} |
| ports: |
| - containerPort: {{ .Values.service.internalPort }} |
| # disable liveness probe when breakpoints set in debugger |
| # so K8s doesn't restart unresponsive container |
| {{- if eq .Values.liveness.enabled true }} |
| livenessProbe: |
| exec: |
| command: ["mysqladmin", "ping"] |
| initialDelaySeconds: {{ .Values.liveness.initialDelaySeconds }} |
| periodSeconds: {{ .Values.liveness.periodSeconds }} |
| timeoutSeconds: {{ .Values.liveness.timeoutSeconds }} |
| {{end -}} |
| readinessProbe: |
| tcpSocket: |
| port: {{ .Values.service.internalPort }} |
| initialDelaySeconds: {{ .Values.readiness.initialDelaySeconds }} |
| periodSeconds: {{ .Values.readiness.periodSeconds }} |
| env: |
| - name: MYSQL_ROOT_PASSWORD |
| valueFrom: |
| secretKeyRef: |
| name: {{ template "common.fullname" . }} |
| key: db-root-password |
| - name: MYSQL_ROOT_HOST |
| value: '%' |
| - name: MYSQL_ALLOW_EMPTY_PASSWORD |
| value: {{ .Values.config.dbAllowEmptyPassword | default "0" | quote }} |
| volumeMounts: |
| - mountPath: /var/lib/mysql |
| name: {{ include "common.fullname" . }}-data |
| subPath: mysql |
| - mountPath: /etc/mysql/conf.d |
| name: conf |
| resources: |
| {{ toYaml .Values.resources | indent 12 }} |
| {{- if .Values.nodeSelector }} |
| nodeSelector: |
| {{ toYaml .Values.nodeSelector | indent 10 }} |
| {{- end -}} |
| {{- if .Values.affinity }} |
| affinity: |
| {{ toYaml .Values.affinity | indent 10 }} |
| {{- end }} |
| |
| - name: xtrabackup |
| image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}" |
| imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} |
| env: |
| - name: MYSQL_ROOT_PASSWORD |
| valueFrom: |
| secretKeyRef: |
| name: {{ template "common.fullname" . }} |
| key: db-root-password |
| ports: |
| - containerPort: {{ .Values.xtrabackup.internalPort }} |
| name: xtrabackup |
| command: |
| - bash |
| - "-c" |
| - | |
| set -ex |
| cd /var/lib/mysql |
| ls -l |
| # Determine binlog position of cloned data, if any. |
| if [[ -f xtrabackup_slave_info ]]; then |
| echo "Inside xtrabackup_slave_info" |
| # XtraBackup already generated a partial "CHANGE MASTER TO" query |
| # because we're cloning from an existing slave. |
| mv xtrabackup_slave_info change_master_to.sql.in |
| # Ignore xtrabackup_binlog_info in this case (it's useless). |
| rm -f xtrabackup_binlog_info |
| elif [[ -f xtrabackup_binlog_info ]]; then |
| echo "Inside xtrabackup_binlog_info" |
| # We're cloning directly from master. Parse binlog position. |
| [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 |
| rm xtrabackup_binlog_info |
| echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\ |
| MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in |
| fi |
| |
| # Check if we need to complete a clone by starting replication. |
| if [[ -f change_master_to.sql.in ]]; then |
| echo "Waiting for mysqld to be ready (accepting connections)" |
| [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 |
| ordinal=${BASH_REMATCH[1]} |
| echo $ordinal |
| until mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h localhost -e "SELECT 1"; do sleep 1; done |
| |
| echo "Initializing replication from clone position" |
| # In case of container restart, attempt this at-most-once. |
| mv change_master_to.sql.in change_master_to.sql.orig |
| mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h localhost <<EOF |
| $(<change_master_to.sql.orig), |
| MASTER_HOST="{{ template "common.name" . }}-0.{{ .Values.service.name }}.{{ include "common.namespace" . }}", |
| MASTER_USER="root", |
| MASTER_PASSWORD="$MYSQL_ROOT_PASSWORD", |
| MASTER_CONNECT_RETRY=10; |
| START SLAVE; |
| EOF |
| fi |
| |
| # Start a server to send backups when requested by peers. |
| exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \ |
| "xtrabackup --user=root --password=$MYSQL_ROOT_PASSWORD --backup --slave-info --stream=xbstream --host=localhost" |
| volumeMounts: |
| - name: {{ include "common.fullname" . }}-data |
| mountPath: /var/lib/mysql |
| subPath: mysql |
| - name: conf |
| mountPath: /etc/mysql/conf.d |
| volumes: |
| - name: conf |
| emptyDir: {} |
| - name: config-map |
| configMap: |
| name: {{ include "common.fullname" . }}-db-configmap |
| - name: localtime |
| hostPath: |
| path: /etc/localtime |
| - name: {{ include "common.fullname" . }}-data |
| #{{ if not .Values.disableNfsProvisioner }} |
| volumeClaimTemplates: |
| - metadata: |
| name: {{ include "common.fullname" . }}-data |
| annotations: |
| volume.beta.kubernetes.io/storage-class: "{{ include "common.fullname" . }}-data" |
| spec: |
| accessModes: ["ReadWriteMany"] |
| resources: |
| requests: |
| storage: 1Gi |
| #{{ else if .Values.persistence.enabled }} |
| persistentVolumeClaim: |
| claimName: {{ include "common.fullname" . }}-data |
| #{{ else }} |
| emptyDir: {} |
| #{{ end }} |