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)

相关推荐
摇滚侠2 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
Frank_refuel3 小时前
终端环境下:Ubuntu 22.04.1 安装 MySQL 数据库
数据库·mysql·ubuntu
木雷坞8 小时前
K8s GPU 推理服务 ImagePullBackOff 排查与预热
云原生·容器·kubernetes·gpu算力
吴爃9 小时前
Spring Boot 项目在 K8S 中的打包、部署与运维发布实践
运维·spring boot·kubernetes
存在的五月雨9 小时前
Mysql 索引的一些
数据库·mysql
黄俊懿10 小时前
MySQL主从复制:从“异步“到“GTID“,数据同步的进化之路
数据库·sql·mysql·oracle·架构·dba·db
zhou周大哥11 小时前
银河麒麟安装mysql
数据库·mysql
The Straggling Crow11 小时前
Monitoring 2026-04-30
kubernetes
AOwhisky11 小时前
Kubernetes调度与服务暴露:从“定时任务”到“服务发现”的完全指南
linux·运维·云原生·容器·kubernetes·服务发现
Sherry Wangs11 小时前
MySQL 与向量数据库的核心区别:从结构化数据到语义搜索
数据库·mysql