title: 45.k8s安装MySQL MGR集群 CreateTime: 2019-07-11 00:00:45 UpdateTime: 2019-07-11 00:00:45 CategoryName: cloudnative --- --- title: "45.k8s安装MySQL MGR集群" date: 2019-07-11T00:00:45+08:00 draft: false tags: ["mysql"] categories: ["cloudnative"] author: "springrain" --- ## 参考资料 https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/ https://mysqlhighavailability.com/setting-up-mysql-group-replication-with-mysql-docker-images/ https://github.com/gites/k8s-mysql-group-replication/blob/master/README.md https://segmentfault.com/a/1190000014966962 ## 单实例MySQL ```yaml ###定义ConfigMap,把脚本和配置文件放到ConfigMap### apiVersion: v1 kind: ConfigMap metadata: name: mysql-configmap #labels: # app: mysql data: ###mysql的配置文件,添加基本的配置### mysqld.cnf: |+ [mysqld] user=mysql max_connections = 2000 default_password_lifetime=0 character_set_server=utf8mb4 lower_case_table_names=1 binlog_expire_logs_seconds=8553600 max_allowed_packet = 128M innodb_buffer_pool_size=500M binlog_cache_size = 2M innodb_open_files = 4096 table_definition_cache = 4096 table_open_cache_instances = 128 thread_cache_size = 64 innodb_online_alter_log_max_size=100M default_authentication_plugin=mysql_native_password --- ###声明 Deployment#### apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql spec: replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql ###mysql的镜像,使用最新的8.0创建### image: mysql:8.0 ###设置mysql可以使用的cpu和内存### resources: limits: cpu: "4" memory: 8Gi requests: cpu: "4" memory: 8Gi ###设置mysql的端口### ports: - containerPort: 3306 name: client - containerPort: 33060 name: xclient - containerPort: 33061 name: mgr env: ###设置root的密码### - name: MYSQL_ROOT_PASSWORD value: "Root+123456789" ######健康检查 开始###### ###pod启动之后,需要检查应用服务是否已经启动,服务正常才加入到service.这里是调用mysql-cli的ping方法,检查mysql是否正常启动### livenessProbe: exec: command: - /bin/sh - "-c" - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" - mysql -h 127.0.0.1 -u root -e "SELECT 1" initialDelaySeconds: 30 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3 readinessProbe: exec: command: - /bin/sh - "-c" - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" - mysql -h 127.0.0.1 -u root -e "SELECT 1" initialDelaySeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 3 ######健康检查 结束###### ###挂载的卷### volumeMounts: - name: conf mountPath: /etc/mysql/conf.d - name: mysql-pvc ###指定子目录,会在cephfs里创建子文件夹#### subPath: basesoft/mysql/pvc mountPath: /var/lib/mysql ###卷的描述 volumes: ###卷名称,对应上面的挂载名称### - name: mysql-pvc persistentVolumeClaim: ###对应cephfs-pvc.yaml的metadata.name### claimName: k8s-pvc ###和上面的volumeMounts -name对应#### - name: conf ###来自于configMap### configMap: ###configMap.metadata.name是mysql-mgr### name: mysql-configmap --- ###创建 mysql 服务#### apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - port: 3306 targetPort: 3306 nodePort: 30306 ###node的端口,用于开发人员直连### name: client - port: 33060 targetPort: 33060 name: xclient - port: 33061 targetPort: 33061 name: mgr ###使用NodePort方式,也固定虚拟IP### clusterIP: 10.98.239.104 selector: app: mysql ###节点类型是NodePort### type: NodePort ``` ## MySQL MGR 1. 创建cephfs账号和文件夹 ```shell ceph fs authorize cephfs client.mysql-mgr /mysql-mgr rw mkdir /mnt/mycephfs/mysql-mgr rm -rf /mnt/mycephfs/mysql-mgr/* mkdir /mnt/mycephfs/mysql-mgr/data-mysql-mgr-0 mkdir /mnt/mycephfs/mysql-mgr/data-mysql-mgr-1 mkdir /mnt/mycephfs/mysql-mgr/data-mysql-mgr-2 ``` 2. 创建mysqlmgr ```yaml apiVersion: v1 kind: Secret metadata: name: mysql-mgr-ceph-secret data: ###通过ceph auth get-key client.mysql-mgr |base64 获取 ### key: QVFCZEgwbGNWbEVSSkJBQXQ4MjAwdVdINzhzbFl5ZmZFZWNNdVE9PQ== --- apiVersion: v1 kind: PersistentVolume metadata: name: mysql-mgr-pv-0 labels: pv: mysql-mgr-pv-0 spec: capacity: storage: 1Gi accessModes: - ReadWriteMany cephfs: monitors: - node1:6789 - node2:6789 - node3:6789 ###可以配置cephfs的子目录,绑定不同的用户,用于权限隔离#### path: /mysql-mgr/data-mysql-mgr-0 ###ceph的账号### user: mysql-mgr secretRef: ###和mysql-mgr-secret.yaml中的metadata.name保持一致### name: mysql-mgr-ceph-secret readOnly: false ###回收策略:Retain手动回收,Recycle需要擦出后才能再使用,Delete相关联的存储资产被删除#### persistentVolumeReclaimPolicy: Recycle --- apiVersion: v1 kind: PersistentVolume metadata: name: mysql-mgr-pv-1 labels: pv: mysql-mgr-pv-1 spec: capacity: storage: 1Gi accessModes: - ReadWriteMany cephfs: monitors: - node1:6789 - node2:6789 - node3:6789 ###可以配置cephfs的子目录,绑定不同的用户,用于权限隔离#### path: /mysql-mgr/data-mysql-mgr-1 ###ceph的账号### user: mysql-mgr secretRef: ###和mysql-mgr-secret.yaml中的metadata.name保持一致### name: mysql-mgr-ceph-secret readOnly: false ###回收策略:Retain手动回收,Recycle需要擦出后才能再使用,Delete相关联的存储资产被删除#### persistentVolumeReclaimPolicy: Recycle --- apiVersion: v1 kind: PersistentVolume metadata: name: mysql-mgr-pv-2 labels: pv: mysql-mgr-pv-2 spec: capacity: storage: 1Gi accessModes: - ReadWriteMany cephfs: monitors: - node1:6789 - node2:6789 - node3:6789 ###可以配置cephfs的子目录,绑定不同的用户,用于权限隔离#### path: /mysql-mgr/data-mysql-mgr-2 ###ceph的账号### user: mysql-mgr secretRef: ###和mysql-mgr-secret.yaml中的metadata.name保持一致### name: mysql-mgr-ceph-secret readOnly: false ###回收策略:Retain手动回收,Recycle需要擦出后才能再使用,Delete相关联的存储资产被删除#### persistentVolumeReclaimPolicy: Recycle --- ###mysql的bug:https://bugs.mysql.com/bug.php?id=94004### ###如果禁用了IPV6,无法创建MGR的端口,官方的docker镜像是禁用IPV6的### ###cat /proc/sys/net/ipv6/conf/all/disable_ipv6### ###定义ConfigMap,把脚本和配置文件放到ConfigMap### apiVersion: v1 kind: ConfigMap metadata: name: mysql-mgr labels: app: mysql-mgr data: ###根据podname修改mysqld.cnf的参数### ###ConfigMap的文件都是只读,无法修改,把/etc/mysql/conf.d/目录挂载到emptyDir,把ConfigMap中的mysqld.cnf文件复制到/etc/mysql/conf.d/,然后sed替换变量### ###主要是server-id和loose-group_replication_local_address需要使用hostname变量### fix-ip.sh: | #!/bin/sh set -ex [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} cat /mnt/config-map/mysqld.cnf >> /etc/mysql/conf.d/mysqld.cnf sed -i "s/sedtempserverid/$((100 + $ordinal))/g" /etc/mysql/conf.d/mysqld.cnf sed -i "s/sedtempgroupreplicationlocaladdress/`hostname`.mysql-mgr/g" /etc/mysql/conf.d/mysqld.cnf chown -R mysql:mysql /etc/mysql/conf.d ###mysql的配置文件,添加基本的配置### mysqld.cnf: |+ [mysqld] user=mysql #datadir=/var/lib/mysql #socket=/var/lib/mysql/mysql.sock #log-error=/var/log/mysqld.log #pid-file=/var/run/mysqld/mysqld.pid server-id=sedtempserverid gtid_mode = on enforce_gtid_consistency=ON master_info_repository=TABLE relay_log_info_repository=TABLE relay_log_recovery=ON binlog_format=ROW log_bin = mysql-bin log_bin_index = mysql-bin.index relay-log=relay-bin relay-log-index=relay-bin.index log_slave_updates=1 plugin-load='group_replication.so' transaction_write_set_extraction = XXHASH64 loose-group_replication_group_name = "94d832dc-f9eb-11e8-a6be-fa163edb2b17" loose-group_replication_start_on_boot = ON loose-group_replication_bootstrap_group = OFF loose-group_replication_local_address = sedtempgroupreplicationlocaladdress:33061 loose-group_replication_group_seeds = mysql-mgr-0.mysql-mgr:33061,mysql-mgr-1.mysql-mgr:33061,mysql-mgr-2.mysql-mgr:33061 loose-group_replication_ip_whitelist = '127.0.0.1/8,192.168.0.0/16,10.0.67.0/24' loose-group_replication_single_primary_mode = off loose-group_replication_enforce_update_everywhere_checks = on loose-group_replication_flow_control_certifier_threshold=250000 loose-group_replication_flow_control_applier_threshold=250000 binlog_checksum = NONE max_connections = 2000 default_password_lifetime=0 character_set_server=utf8mb4 lower_case_table_names=1 binlog_expire_logs_seconds=8553600 innodb_flush_log_at_trx_commit=2 max_allowed_packet = 128M innodb_buffer_pool_size=500M binlog_cache_size = 2M innodb_open_files = 4096 table_definition_cache = 4096 table_open_cache_instances = 128 thread_cache_size = 64 innodb_online_alter_log_max_size=100M --- ###创建一个Headless(无头)Service,就是没有clusterIP,默认访问域名是:mysql-mgr### ###podName是StatefulSet.metadata.name-序号,例如本例:mysql-mgr-0### ###服务下pod的默认访问域名是podName-Service域名,例如本例:mysql-mgr-0-mysql-mgr### ###资料参考:https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ ### apiVersion: v1 kind: Service metadata: name: mysql-mgr labels: app: mysql-mgr spec: ports: - port: 3306 targetPort: 3306 name: client - port: 33060 targetPort: 33060 name: xclient - port: 33061 targetPort: 33061 name: mgr ###无头Service### clusterIP: None selector: app: mysql-mgr --- ###创建StatefulSet,用于有状态的服务### ###注意:StatefulSet默认使用StorageClass进行PVC的创建,cephfs还没有稳定的StorageClass,所以手动创建pv和pvc,用于绑定#### apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql-mgr labels: app: mysql-mgr spec: ###服务名称### serviceName: mysql-mgr ###创建3个副本### replicas: 3 selector: matchLabels: ###mysql容器的标签### app: mysql-mgr template: metadata: labels: ###mysql容器的标签### app: mysql-mgr spec: initContainers: - name: init-mysql image: mysql:8.0 command: ["bash", "/mnt/config-map/fix-ip.sh"] ###挂载的卷### volumeMounts: - name: conf mountPath: /etc/mysql/conf.d - name: conf-map mountPath: /mnt/config-map containers: - name: mysql-mgr ###mysql的镜像,使用最新的8.0创建### image: mysql:8.0 ###设置mysql可以使用的cpu和内存### resources: limits: cpu: "2" memory: 4Gi requests: cpu: "2" memory: 4Gi ###设置mysql的端口### ports: - containerPort: 3306 name: client - containerPort: 33060 name: xclient - containerPort: 33061 name: mgr ###执行的命令,设置ip的fix-ip.sh,启动mysqld #command: ["mysqld"] ###设置环境变量,用于获取pod的Name### env: ###fix-ip.sh脚本中,用于获取${POD_Name},使用环境变量获取POD_Name### - name: POD_Name valueFrom: fieldRef: fieldPath: metadata.name ###设置root的密码### - name: MYSQL_ROOT_PASSWORD value: "Root+123456789" ###挂载的卷### volumeMounts: - name: conf mountPath: /etc/mysql/conf.d - name: conf-map mountPath: /mnt/config-map - name: data mountPath: /var/lib/mysql ###卷的描述 volumes: - name: conf emptyDir: {} ###和上面的volumeMounts -name对应#### - name: conf-map ###来自于configMap### configMap: ###configMap.metadata.name是mysql-mgr### name: mysql-mgr ###默认可执行的权限,这样才能执行fix-ip.sh这个脚本### ##defaultMode: 0755 ###PVC的创建模板,名称为 {volumeClaimTemplates.metadata.name}-{serviceName}-{序号},例如本例中的pvc名称是 data-mysql-mgr-0 /1......### volumeClaimTemplates: - metadata: ###模板的名称### name: data labels: name: mysql-mgr spec: ###访问模式### accessModes: [ "ReadWriteOnce" ] resources: requests: ###Gi是二进制1024Mi,G是十进制1000M### storage: 1Gi ``` ###33061端口无法访问,bug!!!### https://bugs.mysql.com/bug.php?id=94004 默认的官方mysql镜像ipv6是关闭的,日了狗了,搞了两天...... cat /proc/sys/net/ipv6/conf/all/disable_ipv6 ![](/public/45/image3.jpeg) ```shell ###进入mysql-mgr-0### kubectl exec -it mysql-mgr-0 -- /bin/bash ###查看配置文件是否正确### cat /etc/mysql/conf.d/mysqld.cnf ###登陆mysql### mysql -uroot -pRoot+1qazxsw2 ###执行初始化复制### create user 'mysqlmgruser'@'%' identified with 'mysql_native_password' by '5j2;hoqbkbUF'; grant replication slave on *.* to 'mysqlmgruser'@'%' with grant option; reset master; change master to master_user='mysqlmgruser',master_password='5j2;hoqbkbUF' for channel 'group_replication_recovery'; ###配置文件里已经配置了加载### #install PLUGIN group_replication SONAME 'group_replication.so'; set global group_replication_bootstrap_group=ON; start group_replication; set global group_replication_bootstrap_group=OFF; ```