Introduction à MySql
MySQL est un système de gestion de base de données relationnelle développé par la société suédoise MySQL AB et est un produit d'Oracle. MySQL est l'un des systèmes de gestion de bases de données relationnelles les plus populaires. En termes d'applications Web, MySQL est l'un des meilleurs logiciels d'application RDBMS (Relational Database Management System). MySQL est un système de gestion de base de données relationnelle. Les bases de données relationnelles stockent les données dans différentes tables au lieu de placer toutes les données dans un grand entrepôt, ce qui augmente la vitesse et la flexibilité. Le langage SQL utilisé par MySQL est le langage standardisé le plus couramment utilisé pour accéder aux bases de données. Le logiciel MySQL adopte une politique d'autorisation double, divisée en version communautaire et version commerciale. En raison de sa petite taille, de sa vitesse rapide, de son faible coût total de possession, en particulier des caractéristiques de l'open source, le développement de sites Web de petite et moyenne taille choisit généralement MySQL comme base de données du site Web.
La solution haute disponibilité de MySQL
La solution de haute disponibilité MySQL présentée ci-dessous utilise la réplication maître-esclave + séparation lecture-écriture, qui est composée d'un seul maître et de plusieurs esclaves. Parmi eux, le client écrit dans la base de données via le maître et lit via l'esclave. Une fois que le maître a un problème, vous pouvez basculer l'application du côté esclave. Cette solution est une solution hautement disponible officiellement fournie par MySQL. La synchronisation des données entre les nœuds utilise la technologie de réplication MySQL. La réplication MySQL réplique les données d'un serveur de base de données MySQL (maître) vers un ou plusieurs serveurs de base de données MySQL (esclave). Par défaut, la réplication est asynchrone; l'esclave n'a pas besoin de toujours recevoir les mises à jour de l'hôte. En fonction de la configuration, vous pouvez copier toutes les bases de données de la base de données, des bases de données sélectionnées ou des tables spécifiques.
Installation et déploiement
1. Créez un ConfigMap
Créez un ConfigMap nommé mysql via le fichier YAML
chat mysql-configmap.yaml
apiVersion : v1 genre : métadonnées ConfigMap : nom : libellés mysql : app : données mysql : maître . cnf : | # Appliquez cette configuration uniquement sur le maître. [ mysqld ] log - bin log_bin_trust_function_creators = 1 lower_case_table_names = 1 esclave . cnf : | # N'appliquez cette configuration qu'aux esclaves. [ mysqld ] super
-read-only
log_bin_trust_function_creators=1
kubectl apply -f mysql-configmap.yaml -n kube-public
2. 创建Services
通过yaml文件创建两个service,分别是mysql和mysql-read:
cat mysql-service.yaml
apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - name: mysql port: 3306 clusterIP: None selector: app: mysql --- apiVersion: v1 kind: Service metadata: name: mysql-read labels: app: mysql spec: ports: - name: mysql port: 3306 selector: app: mysql
kubectl apply -f mysql-service.yaml -n kube-public
3.创建StatefulSet
通过yaml文件创建名为mysql的StatefulSet:
cat mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 3
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.beta.kubernetes.io/storage-class: "nfs"
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
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: gcr.io/google-samples/xtrabackup:1.0
command:
- bash
- "-c"
- |
set -ex
[[ -d /var/lib/mysql/mysql ]] && exit 0
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
[[ $ordinal -eq 0 ]] && exit 0
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
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: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
if [[ -f xtrabackup_slave_info ]]; then
mv xtrabackup_slave_info change_master_to.sql.in
rm -f xtrabackup_binlog_info
elif [[ -f xtrabackup_binlog_info ]]; then
[[ `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
if [[ -f change_master_to.sql.in ]]; then
echo "Waiting for mysqld to be ready (accepting connections)"
until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
echo "Initializing replication from clone position"
mv change_master_to.sql.in change_master_to.sql.orig
mysql -h 127.0.0.1 <<EOF
$(<change_master_to.sql.orig),
MASTER_HOST='mysql-0.mysql',
MASTER_USER='root',
MASTER_PASSWORD='',
MASTER_CONNECT_RETRY=10;
START SLAVE;
EOF
fi
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"
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
kubectl apply -f mysql-statefulset.yaml -n kube-public
通过执行如下的命令可以查看启动过程:
$ kubectl get pods -lapp=mysql --watch --namespace=kube-public
在启动后,应该能够看到如下的信息:
注:上面配置说明
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.beta.kubernetes.io/storage-class: "nfs"
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
上面这段表示动态申请pvc,存储类是由nfs创建的,前提是创建nfs的存储类,创建方法如下:
cat class.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
provisioner: example.com/nfs
kubectl apply -f class.yaml
动态pvc创建可参考:
MySQL部署环境验证
1)通过运行一个临时的容器(使用mysql:5.7镜像),使用MySQL 客户端发送测试请求给MySQL master节点(主机名为mysql-0.mysql;跨命名空间的话,主机名请使用mysql-0.mysql.kube-public)
kubectl run mysql-client --image=mysql:5.7 -it --rm --restart=Never -- mysql -h mysql-0.mysql.kube-public
CREATE DATABASE demo;
CREATE TABLE demo.messages (message VARCHAR(250));
INSERT INTO demo.messages VALUES ('hello');
在master节点上创建demo数据库,并创建一个只有message字段的demo.messages的表,并为message字段插入hello值。
2)使用主机名为mysql-read来发送测试请求给服务器:
kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never -- mysql -h mysql-read.kube-public