Install NFS service
## Installation sudo apt install nfs-kernel-server ## start up sudo /etc/init.d/nfs-kernel-server start ## Create a directory mkdir /data/nfs sudo chmod -R 777 /data/nfs ## Share nano /etc/exports ## Add to end of file /var/nfs *(insecure,rw,sync,no_root_squash) ## Restart sudo /etc/init.d/nfs-kernel-server restart
Install Helm
## Installation curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash ## Add and modify the ip to the server's internal network ip helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --set nfs.server=x.x.x.x \ --set nfs.path=/data/nfs
kubectl apply -f mysql.yaml
# mysql secret key apiVersion: v1 Kind: Secret metadata: name: mysql-secret labels: app: mysql type: Opaque data: password: XXXXXXXXX # base64 encrypted password --- # mysql configuration apiVersion: v1 kind: ConfigMap metadata: name: mysql labels: app: mysql data: primary.cnf: | #Master [mysqld] log-bin=mysqllog replica.cnf: | #Slave [mysqld] super-read-only --- #StatefulSet mysql pod apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql labels: app: mysql spec: selector: matchLabels: app: mysql app.kubernetes.io/name: mysql serviceName: mysql replicas: 3 # Number of replicas, number in the cluster template: metadata: labels: app:mysql app.kubernetes.io/name: mysql spec: initContainers: - name: init-mysql image: freelizhun/mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password command: - bash - "-c" - | set-ex # Generate the ID of the MySQL server based on the Pod serial number. [[ $HOSTNAME =~ -([0-9] + )$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} echo [mysqld] > /mnt/conf.d/server-id.cnf # Add an offset to avoid using the reserved value of server-id=0. echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf # Copy the appropriate conf.d file from config-map to emptyDir. if [[ $ordinal -eq 0 ]]; then cp /mnt/config-map/primary.cnf /mnt/conf.d/ else cp /mnt/config-map/replica.cnf /mnt/conf.d/ fi volumeMounts: - name: conf mountPath: /mnt/conf.d - name: config-map mountPath: /mnt/config-map - name: clone-mysql image: freelizhun/xtrabackup:v2 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password command: - bash - "-c" - | set-ex # If data already exists, skip cloning. [[ -d /var/lib/mysql/mysql ]] & amp; & amp; exit 0 # Skip cloning of the master instance (serial index 0). [[ `hostname` =~ -([0-9] + )$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} [[ $ordinal -eq 0 ]] & amp; & amp; exit 0 # Clone data from original peer. ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql # Prepare 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: freelizhun/mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password 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: 1Gi livenessProbe: exec: command: - bash - "-c" - | set-ex mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD} initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: exec: # Check if we can perform the query over TCP (skip-networking is off). command: - bash - "-c" - | set-ex mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD} initialDelaySeconds: 5 periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup image: freelizhun/xtrabackup:v2 ports: - name: xtrabackup containerPort: 3307 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password command: - bash - "-c" - | set-ex cd /var/lib/mysql # Determine the binlog location of cloned data (if any). if [[ -f xtrabackup_slave_info & amp; & amp; "x$(<xtrabackup_slave_info)" != "x" ]]; then # XtraBackup has generated part of the "CHANGE MASTER TO" query # Because we are cloning from an existing copy. (Need to remove the semicolon at the end!) cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in # Ignore xtrabackup_binlog_info here (it is useless). rm -f xtrabackup_slave_info xtrabackup_binlog_info elif [[ -f xtrabackup_binlog_info ]]; then # We clone directly from the master instance. Parse binlog location. [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]] + (.*?)$ ]] || exit 1 rm -f xtrabackup_binlog_info xtrabackup_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 cloning by starting replication. if [[ -f change_master_to.sql.in ]]; then echo "Waiting for mysqld to be ready (accepting connections)" until mysql -h 127.0.0.1 -uroot -p${<!-- -->MYSQL_ROOT_PASSWORD} -e "SELECT 1"; do sleep 1; done echo "Initializing replication from clone position" mysql -h 127.0.0.1 -uroot -p${<!-- -->MYSQL_ROOT_PASSWORD} \ -e "$(<change_master_to.sql.in), \ MASTER_HOST='mysql-0.mysql', \ MASTER_USER='root', \ MASTER_PASSWORD='${<!-- -->MYSQL_ROOT_PASSWORD}', \ MASTER_CONNECT_RETRY=10; \ START SLAVE;" || exit 1 # If the container is restarted, try at most once. mv change_master_to.sql.in change_master_to.sql.orig fi # Start the server to send backups when requested by the peer. exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \ "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=${<!-- -->MYSQL_ROOT_PASSWORD}" volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d volumes: - name: conf emptyDir: {<!-- --> } - name: config-map configMap: name: mysql volumeClaimTemplates: - metadata: name:data spec: accessModes: - "ReadWriteOnce" storageClassName: nfs-client resources: requests: Storage: 2Gi --- #HeadlessService apiVersion: v1 Kind: Service metadata: name: mysql labels: app:mysql app.kubernetes.io/name: mysql spec: ports: - name: mysql port: 3306 clusterIP: None # Headless Service Headless Service selector: app:mysql --- apiVersion: v1 Kind: Service metadata: name: mysql-read labels: app:mysql app.kubernetes.io/name: mysql readonly: "true" spec: ports: - name: mysql port: 3306 selector: app: mysql --- # NodePort Service apiVersion: v1 Kind: Service metadata: name: mysql-node-port labels: app:mysql spec: ports: - nodePort: 30006 port: 3306 targetPort: 3306 protocol:TCP name: mysql type: NodePort selector: app:mysql
Refer to the official documentation: https://kubernetes.io/zh-cn/docs/tasks/run-application/run-replicated-stateful-application/