--- # MySQL configurations apiVersion:v1 kind:ConfigMap metadata: name:mysql labels: app:mysql data: master.cnf:| # Apply this config only on the master. [mysqld] log-bin default-time-zone='+8:00' character-set-client-handshake=FALSE character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci' slave.cnf:| # Apply this config only on slaves. [mysqld] super-read-only default-time-zone='+8:00' character-set-client-handshake=FALSE character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci' --- # Headless service for stable DNS entries of StatefulSet members. apiVersion:v1 kind:Service metadata: name:mysql labels: app:mysql spec: ports: -name:mysql port:3306 clusterIP:None selector: app:mysql
--- # Client service for connecting to any MySQL instance for reads. # For writes, you must instead connect to the master: mysql-0.mysql. apiVersion:v1 kind:Service metadata: name:mysql-read labels: app:mysql spec: ports: -name:mysql port:3306 selector: app:mysql --- # Applications apiVersion:apps/v1 kind:StatefulSet metadata: name:mysql spec: selector: matchLabels: app:mysql serviceName:mysql replicas:3 template: metadata: labels: app:mysql spec: initContainers: -name:init-mysql image:mysql:5.7 command: -bash -"-c" -| set -ex # Generate mysql server-id from pod ordinal index. [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} 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:ipunktbs/xtrabackup 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]} [[ $ordinal -eq 0 ]] && exit 0 # Clone data from previous peer. ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql # Prepare the backup. xtrabackup --prepare --target-dir=/var/lib/mysql volumeMounts: -name:data mountPath:/var/lib/mysql subPath:mysql -name:conf mountPath:/etc/mysql/conf.d containers: -name:mysql image:mysql:5.7 env: -name:MYSQL_ALLOW_EMPTY_PASSWORD value:"1" ports: -name:mysql containerPort:3306 volumeMounts: -name:data mountPath:/var/lib/mysql subPath:mysql -name:conf mountPath:/etc/mysql/conf.d resources: requests: cpu:500m memory:512m livenessProbe: exec: command: ["mysqladmin", "ping"] initialDelaySeconds:30 periodSeconds:10 timeoutSeconds:5 readinessProbe: exec: # Check we can execute queries over TCP (skip-networking is off). command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"] initialDelaySeconds:5 periodSeconds:2 timeoutSeconds:1 -name:xtrabackup image:ipunktbs/xtrabackup ports: -name:xtrabackup containerPort:3307 command: -bash -"-c" -| set -ex cd /var/lib/mysql # Determine binlog position of cloned data, if any. if [[ -fxtrabackup_slave_info&&"x$(<xtrabackup_slave_info)"!="x" ]];then # XtraBackup already generated a partial "CHANGE MASTER TO" query # because we're cloning from an existing slave. (Need to remove the tailing semicolon!) catxtrabackup_slave_info|sed-E's/;$//g'>change_master_to.sql.in # Ignore xtrabackup_binlog_info in this case (it's useless). rm-fxtrabackup_slave_infoxtrabackup_binlog_info elif [[ -fxtrabackup_binlog_info ]];then # We're cloning directly from master. Parse binlog position. [[ `catxtrabackup_binlog_info`=~^(.*?)[[:space:]]+(.*?)$ ]] ||exit1 rm-fxtrabackup_binlog_infoxtrabackup_slave_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 [[ -fchange_master_to.sql.in ]];then echo"Waiting for mysqld to be ready (accepting connections)" untilmysql-h127.0.0.1-e"SELECT 1";dosleep1;done
echo"Initializing replication from clone position" mysql-h127.0.0.1\ -e"$(<change_master_to.sql.in), \ MASTER_HOST='mysql-0.mysql', \ MASTER_USER='root', \ MASTER_PASSWORD='', \ MASTER_CONNECT_RETRY=10; \ START SLAVE;"||exit1 # In case of container restart, attempt this at-most-once. mvchange_master_to.sql.inchange_master_to.sql.orig fi
# Start a server to send backups when requested by peers. execncat--listen--keep-open--send-only--max-conns=13307-c\ "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root" volumeMounts: -name:data mountPath:/var/lib/mysql subPath:mysql -name:conf mountPath:/etc/mysql/conf.d resources: requests: cpu:100m memory:100Mi volumes: -name:conf emptyDir: {} -name:config-map configMap: name:mysql volumeClaimTemplates: -metadata: name:data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage:5Gi
8. Horizontal Pod AutoScalling
应用的资源使用率通常有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,HPA 提供了 Pod 的水平自动缩放功能