kubernetes使用nfs创建pvc部署mysql stateful的方法

kubernetes创建的pod默认都是无状态的,换句话说删除以后不会保留任何数据。

所以对于mysql这种有状态的应用,必须使用持久化存储作为支撑,才能部署成有状态的stateful.

最简单的方法就是使用nfs作为网络存储,因为nfs存储很容易被所有节点所共享。

首先安装nfs

安装nfs非常简单。一条命令就可以完成

yum install nfs-utils

nfs-utils必须在所有节点都安装,因为除了nfs-server, 其他node节点需要nfs客户端才能访问nfs存储。

然后创建nfs共享的目录,比如/nfs-mysql

mkdir /nfs-mysql

接着配置/etc/exports把上面的目录写进去, vim /etc/exports

/nfs-mysql 192.168.10.0/24(rw,no_root_squash)

备注:

192.168.10.0/24表示nfs存储共享的ip段,

rw表示可读写,

no_root_squash表示允许nfs客户端保留跟它原来客户端主机上一样的身份权限,这么说有点拗口,简单说:就是nfs客户端可以通过chown命令切换/nfs-mysql目录的身份和权限

为什么要这样设置: 因为nfs默认会将nfs客户端的身份映射为匿名用户,这样一来像mysql一旦chown切换身份就会失败。

man exports就可以看到root_squash和no_root_squash的作用

然后启动nfs-server,这样nfs存储就搞好了

systemctl start nfs-server

nfs增加共享资源,使其生效的命令是:

exportfs -fr

nfs客户端通过showmount -e ${nfs服务器ip} 就可以查看到远程nfs服务器共享的资源:

然后下面讲重点,怎么利用nfs创建pvc存储。

首先第一步创建pv存储卷:

创建pv存储卷

apiVersion: v1

kind: PersistentVolume

metadata:

name:nfs-pv-mysql

spec:

capacity:

storage: 1Gi

volumeMode: Filesystem

accessModes:

  • ReadWriteMany

persistentVolumeReclaimPolicy: Retain

storageClassName: "nfs-mysql"

nfs:
path: /nfs-mysql # nfs服务器上定义的挂载地址, 也就是/etc/exports里面定义的
server: 192.168.10.20 # nfs服务器的地址

第二步: 向上面创建的pv存储卷申请存储空间

向pv申请空间

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: nfs-pvc-mysql # 这个pvc的名称就是后面stateful要使用到的,非常重要

spec:

accessModes:

  • ReadWriteMany

storageClassName: "nfs-mysql"

resources:

requests:

storage: 1Gi

注意: 上面两个storageClassName的值必须是一样的。

然后pv和pvc就创建好了。

上面pvc状态显示Bound,表示pvc跟pv已经绑定成功。

你可以理解为pv就是一个存储池, 而pvc就是从里面拿出来的存储资源

mysql就是使用这个创建好的pvc来做持久化存储的。

kind: StatefulSet

apiVersion: apps/v1

metadata:

name: mysql-db-deploy

namespace: default

labels:

k8s-app: mysql-db-app

spec:

replicas: 1

serviceName: mysql-db-app-service #此字段必须有,stateful规定的

selector:

matchLabels:

k8s-app: mysql-db-app

template:

metadata:

labels:

k8s-app: mysql-db-app

name: mysql-db-app

spec:

containers:

name: mysql-db-app

ports:

  • name: admin

containerPort: 3306

env:

  • name: MYSQL_ROOT_PASSWORD

value: "123456"

volumeMounts:

  • name: data-pv
    mountPath: /var/lib/mysql

volumes:

  • name: data-pv
    persistentVolumeClaim:
    claimName: nfs-pvc-mysql # 使用已存在的 PVC 的名称

kind: Service
apiVersion: v1
metadata:
name: mysql-db-svc
namespace: default
spec:
selector:
k8s-app: mysql-db-app
ports:

  • protocol: TCP
    port: 3306
    name: admin
    nodePort: 30306
    type: NodePort

重点在我标红的地方: 主要就是volumeMounts和volumes配置这两个地方

claimName的值就是上面已经创建好的pvc的名字

volumeMounts选项是containers二级子配置

volumes跟containers字段是同级关系

serviceName字段必须有

这样mysql stateful就配好了,你可以测试一下: 就是删除了mysql pod,然后重新自动创建mysql pod, mysql的数据也不会丢失, 这就是stateful的作用

注意点

  1. 创建pv时,nfs下path必须是提前存在的,而且是远程nfs设置的挂载路径

否则会报错:

mounting xxx:/nfs_share failed, reason given by server: No such file or directory

  1. mysql stateful配置中volumes.persistentVolumeClaim.claimName字段的值必须是已创建pvc的名称,不能是pv的名称, 否则会报错: MountVolume.SetUp failed for volume "nfs-pv" : mount failed
  1. nfs exports中的配置必须要有no_root_squash选项,否则创建mysql pod就会报错:

chown: changing ownership of '/var/lib/mysql/': Operation not permitted

  1. mysql所使用的pvc的挂载目录必须是空的,否则mysql pod会报错:

ERROR\] --initialize specified but the data directory has files in it. Aborting. ![](https://file.jishuzhan.net/article/1728573466610765826/e4df88853d12bcf84fd664c0d58a6a23.webp)

相关推荐
东风微鸣25 分钟前
Python 脚本最佳实践2025版
docker·云原生·kubernetes·可观察性
Andy杨30 分钟前
20250710-2-Kubernetes 集群部署、配置和验证-网络组件存在的意义?_笔记
网络·笔记·kubernetes
风雅的远行者2 小时前
mysql互为主从失效,重新同步
数据库·mysql
晨岳2 小时前
CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
java·redis·mysql·nginx·centos·tomcat
鸥梨菌Honevid6 小时前
QT解析文本框数据——概述
数据库·qt·mysql
今天又得骑车了6 小时前
一、MySQL 8.0 之《EXPLAIN ANALYZE 执行计划》
数据库·mysql·database
David爱编程6 小时前
Deployment vs StatefulSet:怎么选?
后端·云原生·kubernetes
icecreamstorm6 小时前
MySQL 事务 最全入门
后端·mysql
weixin_420571876 小时前
Windos服务器升级MySQL版本
运维·服务器·mysql
万能小锦鲤7 小时前
《Java EE与中间件》实验三 基于Spring Boot框架的购物车
java·spring boot·mysql·实验报告·购物车·文档资源·java ee与中间件