mysql-statefulset.yaml 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: mysql
  5. namespace: my-statefulset
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: mysql
  10. serviceName: mysql
  11. replicas: 3
  12. template:
  13. metadata:
  14. labels:
  15. app: mysql
  16. spec:
  17. initContainers:
  18. - name: init-mysql
  19. image: biarms/mysql:5.7.30
  20. command:
  21. - bash
  22. - "-c"
  23. - |
  24. set -ex
  25. # Generate mysql server-id from pod ordinal index.
  26. [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
  27. ordinal=${BASH_REMATCH[1]}
  28. echo [mysqld] > /mnt/conf.d/server-id.cnf
  29. # Add an offset to avoid reserved server-id=0 value.
  30. echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
  31. # Copy appropriate conf.d files from config-map to emptyDir.
  32. if [[ $ordinal -eq 0 ]]; then
  33. cp /mnt/config-map/primary.cnf /mnt/conf.d/
  34. else
  35. cp /mnt/config-map/replica.cnf /mnt/conf.d/
  36. fi
  37. volumeMounts:
  38. - name: conf
  39. mountPath: /mnt/conf.d
  40. - name: config-map
  41. mountPath: /mnt/config-map
  42. - name: clone-mysql
  43. image: gcr.io/google-samples/xtrabackup:1.0
  44. command:
  45. - bash
  46. - "-c"
  47. - |
  48. set -ex
  49. # Skip the clone if data already exists.
  50. [[ -d /var/lib/mysql/mysql ]] && exit 0
  51. # Skip the clone on primary (ordinal index 0).
  52. [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
  53. ordinal=${BASH_REMATCH[1]}
  54. [[ $ordinal -eq 0 ]] && exit 0
  55. # Clone data from previous peer.
  56. ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
  57. # Prepare the backup.
  58. xtrabackup --prepare --target-dir=/var/lib/mysql
  59. volumeMounts:
  60. - name: data
  61. mountPath: /var/lib/mysql
  62. subPath: mysql
  63. - name: conf
  64. mountPath: /etc/mysql/conf.d
  65. containers:
  66. - name: mysql
  67. image: biarms/mysql:5.7.30
  68. env:
  69. - name: MYSQL_ALLOW_EMPTY_PASSWORD
  70. value: "1"
  71. ports:
  72. - name: mysql
  73. containerPort: 3306
  74. volumeMounts:
  75. - name: data
  76. mountPath: /var/lib/mysql
  77. subPath: mysql
  78. - name: conf
  79. mountPath: /etc/mysql/conf.d
  80. resources:
  81. requests:
  82. cpu: 500m
  83. memory: 1Gi
  84. livenessProbe:
  85. exec:
  86. command: ["mysqladmin", "ping"]
  87. initialDelaySeconds: 30
  88. periodSeconds: 10
  89. timeoutSeconds: 5
  90. readinessProbe:
  91. exec:
  92. # Check we can execute queries over TCP (skip-networking is off).
  93. command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
  94. initialDelaySeconds: 5
  95. periodSeconds: 2
  96. timeoutSeconds: 1
  97. - name: xtrabackup
  98. image: gcr.io/google-samples/xtrabackup:1.0
  99. ports:
  100. - name: xtrabackup
  101. containerPort: 3307
  102. command:
  103. - bash
  104. - "-c"
  105. - |
  106. set -ex
  107. cd /var/lib/mysql
  108. # Determine binlog position of cloned data, if any.
  109. if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
  110. # XtraBackup already generated a partial "CHANGE MASTER TO" query
  111. # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
  112. cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
  113. # Ignore xtrabackup_binlog_info in this case (it's useless).
  114. rm -f xtrabackup_slave_info xtrabackup_binlog_info
  115. elif [[ -f xtrabackup_binlog_info ]]; then
  116. # We're cloning directly from primary. Parse binlog position.
  117. [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
  118. rm -f xtrabackup_binlog_info xtrabackup_slave_info
  119. echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
  120. MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
  121. fi
  122. # Check if we need to complete a clone by starting replication.
  123. if [[ -f change_master_to.sql.in ]]; then
  124. echo "Waiting for mysqld to be ready (accepting connections)"
  125. until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
  126. echo "Initializing replication from clone position"
  127. mysql -h 127.0.0.1 \
  128. -e "$(<change_master_to.sql.in), \
  129. MASTER_HOST='mysql-0.mysql', \
  130. MASTER_USER='root', \
  131. MASTER_PASSWORD='', \
  132. MASTER_CONNECT_RETRY=10; \
  133. START SLAVE;" || exit 1
  134. # In case of container restart, attempt this at-most-once.
  135. mv change_master_to.sql.in change_master_to.sql.orig
  136. fi
  137. # Start a server to send backups when requested by peers.
  138. exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
  139. "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
  140. volumeMounts:
  141. - name: data
  142. mountPath: /var/lib/mysql
  143. subPath: mysql
  144. - name: conf
  145. mountPath: /etc/mysql/conf.d
  146. resources:
  147. requests:
  148. cpu: 100m
  149. memory: 100Mi
  150. volumes:
  151. - name: conf
  152. emptyDir: {}
  153. - name: config-map
  154. configMap:
  155. name: mysql
  156. volumeClaimTemplates:
  157. - metadata:
  158. name: data
  159. spec:
  160. accessModes: ["ReadWriteOnce"]
  161. resources:
  162. requests:
  163. storage: 10Gi