【从入门到放弃-Kubernetes】Kubernetes入门-部署MySQL
前言
上文【从入门到放弃-Kubernetes】Kubernetes入门-有状态应用扩缩容中,介绍了如何部署有状态应用。有状态应用中,MySQL是我们最常见也是最常用的。本文我们就实战部署一个一组多从的MySQL集群。
配置准备
configMap
#application/mysql/mysql-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: mysql labels: app: mysql data: master.cnf: | # Apply this config only on the master. [mysqld] log-bin slave.cnf: | # Apply this config only on slaves. [mysqld] super-read-only
configMap可以将配置文件和镜像解耦开。
上面的配置意思是,创建一个master.cnf文件配置内容为:log-bin,即开启bin-log日志,供主节点使用。
创建一个slave.cnf文件配置内容为:super-read-only,设为该节点只读,供备用节点使用。
service
# application/mysql/mysql-services.yaml # 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
创建一个服务名为mysql的headless类型的service。
创建一个服务名为mysql-read的service
StatefulSet
#application/mysql/mysql-statefulset.yaml 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 # 为每个MySQL节点配置service-id # 如果节点序号是0,则使用master的配置, 其余节点使用slave的配置 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: gcr.io/google-samples/xtrabackup:1.0 # 为除了节点序号为0的主节点外的其它节点,备份前一个节点的数据 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: # 设置启动pod需要的资源,官方文档上需要500m cpu,1Gi memory。 # 我本地测试的时候,会因为资源不足,报1 Insufficient cpu, 1 Insufficient memory错误,所以我改小了点 requests: # m是千分之一的意思,100m表示需要0.1个cpu cpu: 100m # Mi是兆的意思,需要100M 内存 memory: 100Mi livenessProbe: # 使用mysqladmin ping命令,对MySQL节点进行探活检测 # 在节点部署完30秒后开始,每10秒检测一次,超时时间为5秒 exec: command: ["mysqladmin", "ping"] initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: # 对节点服务可用性进行检测, 启动5秒后开始,每2秒检测一次,超时时间1秒 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: gcr.io/google-samples/xtrabackup:1.0 ports: - name: xtrabackup containerPort: 3307 # 开始进行备份文件校验、解析和开始同步 command: - bash - "-c" - | set -ex cd /var/lib/mysql # Determine binlog position of cloned data, if any. if [[ -f xtrabackup_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!) cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in # Ignore xtrabackup_binlog_info in this case (it's useless). rm -f xtrabackup_slave_info xtrabackup_binlog_info elif [[ -f xtrabackup_binlog_info ]]; then # We're cloning directly from master. Parse binlog position. [[ `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 a clone 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 -e "SELECT 1"; do sleep 1; done echo "Initializing replication from clone position" mysql -h 127.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;" || exit 1 # In case of container restart, attempt this at-most-once. mv change_master_to.sql.in change_master_to.sql.orig fi # Start a server to send backups when requested by peers. 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 # 设置PVC volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi
主从节点的配置和启动都在上面的yaml文件中定义好了,接下来需要逐个创建即可。
创建所需资源
//创建configMap kubectl apply -f configMap.yaml //创建service kubectl apply -f service.yaml //创建statefulSet kubectl apply -f statefulSet.yaml
执行完毕后可以使用以下命令监测创建情况。
kubectl get pods --watch
测试主库
进入pod进行操作
进入到pod mysql-0中,进行测试
kubectl exec -it mysql-0 bash
用mysql-client链接mysql-0
mysql -h mysql-0
创建库、表
//创建数据库test create database test; //使用test库 use test; //创建message表 create table message (message varchar(50)); //查看message表结构 show create table message;
插入数据
//插入 insert into message value("hello aloofjr"); //查看 select * from message;
测试备库
连接mysql-1
mysql -h mysql-1.mysql
查看库、表结构
//查看数据库列表 show databases; //使用test库 use test; //查看表列表 show tables; //查看message表结构 show create table message;
读取数据
//查看 select * from message;
写入数据
insert into message values("hello world");
此时会报错 ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
这是因为mysql-1是一个只读备库,无法进行写操作。
测试mysql-read服务
kubectl run mysql-client-loop --image=mysql:5.7 -i -t --rm --restart=Never --\ bash -ic "while sleep 1; do mysql -h mysql-read -e 'SELECT @@server_id,NOW()'; done"
每秒查询一次数据库,可以观察到,调度到不同的server-id,即pod节点
扩缩容
//扩容至5副本 kubectl scale statefulset mysql --replicas=5 //缩容只2副本 kubectl scale statefulset mysql --replicas=2
清理
kubectl delete statefulset mysql kubectl delete configmap,service,pvc -l app=mysql
总结
上面就是通过k8s部署一个一主多从mysql集群的过程,其中有几个重要知识点:
- 通过configMap可以将配置和镜像解耦
- 通过initContainers在pod启动前,做一些初始化工作
- 通过requests设置pod所需的cpu和memory
- 通过livenessProbe进行pod节点探活
- 通过readnessProbe进行pod可用性检测
下文,我们来学习如何通过k8s部署一个可读写数据库的SpringBoot应用。
本文中用到的yaml文件见我的GitHub仓库AloofJr
更多文章
见我的博客:https://nc2era.com
written by AloofJr,转载请注明出处
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Docker安装ElasticSearch和Elasticsearch-Head以及IK分词器
ElasticSearch 是一个分布式、高扩展、高实时的搜索引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用ElasticSearch的水平伸缩性,能使数据在生产环境变得更有价值。ElasticSearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elastic Search 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户,本文介绍如果通过Docker进行安装Elasticsearch单节点和集群 一、安装单节点Elasticsearch 1、拉取Elasticsearch docker pull elasticsearch:6.8.7 2、创建数据卷 主要用于将容器内的数据和宿主机进行挂载,避免容器重启和挂掉的时候数据丢失 创建目录 # -p是创建多级目录 mkdir -p /data/es 进入刚刚创建的es目录,创建数据存放目录和日志存放目录 # 进入目录 cd /data/es # 创建数据目录和日志目录 mkdir data log # 这两个目...
- 下一篇
Docker虚拟化管理:30分钟教你学会用Docker
Docker虚拟化管理:30分钟教你学会用Docker 关于Docker的官方介绍网上太多了我就不贴了,就实际体验来说Docker可以极大的简化环境搭建及服务部署的操作流程,大大降低部署的时间成本,解放你的双手。 本文不会深入讲解Docker底层架构及运行原理,也不会有一堆架构图贴在这里。该篇旨在让你以最快的速度学会使用Docker,关于Docker的架构及其底层的一些知识,你可以在学会Docker的基本使用之后再去了解。开门见山讲架构聊底层有点容易让人犯迷糊,但在使用Docker之前你至少应该了解他的三大核心组件:仓库、镜像和容器,以及他们之前的关系。本文将通过一个MySQL示例带你了解并使用Docker,待你对Docker有一个基本了解后你再回头去看他的体系架构会容易理解。 三大核心组件仓库:仓库是集中存储镜像的地方,我们本地安装Docker之后,需要从仓库中拉取镜像。可以类比于Maven,有公有仓库和私有仓库之分。 镜像:是一个Linux的文件系统,它里面存放着可以再Linux内核中运行的程序及其数据。 容器:是镜像创建的运行实例,可以把它理解为一个精简版的Linux系统,里面运...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装