k8s volumns 持久化
先理解几个概念
在 Kubernetes (k8s) 中,PV (Persistent Volume) 和 PVC (Persistent Volume Claim) 的概念可以用生活中的租房场景来进行类比,这样可以帮助我们更好地理解它们的角色和作用。
PV (Persistent Volume): 房源
想象你是一位房地产经纪人,负责管理城市中的不同房源。每个房源都代表了一块特定的存储空间,比如一个公寓或者一栋房子,这些房源具有固定的大小、位置(比如NFS、Amazon EBS等存储类型)、以及一些特性,如是否允许同时多人入住,出入(读写权限)、是否有花园(附加的访问模式,比如翻窗而入)等。
作为经纪人,你需要事先了解并准备好这些房源,设定好它们的规则,比如租期结束时是否需要恢复原状(回收策略)。
PVC (Persistent Volume Claim): 租房需求
现在,有租户(应用开发者)来到你这里,他们有着不同的租房需求。有的可能只需要一个小单间来存放个人物品(小容量存储需求),有的则需要一个大户型来运行他们的家庭办公室(大量数据存储需求)。
租户提出的需求中会包含他们想要的空间大小、是否需要安静的环境(读写权限要求),以及他们能接受的地理位置(存储类型偏好)等。这个需求声明就是PVC。
配置实战
首先来个房源 k8s-mysql-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wee-book-mysql-pv
spec:
storageClassName: wee-book-mysql-pv
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
此配置创建了一个名为
wee-book-mysql-pv
的持久卷,它提供了1GiB的存储空间,且只能被单个节点以读写权限挂载。卷的物理存储位置位于节点的/mnt/data
目录下。这种类型的持久卷配置适用于开发或测试环境,生产环境中推荐使用更高级的存储解决方案以确保数据的持久性和高可用性。
然后租房者也发出了自己的租房需求 k8s-mysql-pvc.yaml
(当然这里我们是通过storageClassName
直接指定某个pv,毕竟房源和需求都是我们可以定制的,和真实场景还不太一样!)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wee-book-mysql-pvc
spec:
storageClassName: wee-book-mysql-pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
此配置创建了一个名为
wee-book-mysql-pvc
的持久卷声明,它请求1GiB的存储空间,并且要求该存储能够以ReadWriteOnce
模式访问。声明中指定了storageClassName
为wee-book-mysql-pv
,这意味着Kubernetes会尝试寻找一个与之匹配的持久卷(PV),其存储类名称相同且能够满足PVC的存储需求和访问模式。一旦绑定成功,该PVC就可以被用来为Pod提供持久化存储,例如在之前的Deployment配置中通过volumeMounts挂载到容器内部。
然后需要 Deployment 进行 volumn 的设置!
apiVersion: apps/v1
kind: Deployment
metadata:
name: we-book-mysql
labels:
app: we-book-mysql
spec:
replicas: 1
selector:
matchLabels:
app: we-book-mysql
template:
metadata:
name: we-book-mysql
labels:
app: we-book-mysql
spec:
containers:
- name: we-book-mysql
image: mysql:8.0.29
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: root
ports:
- containerPort: 3306
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-storage
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: wee-book-mysql-pvc
这段配置将创建一个Deployment来管理一个单一副本的MySQL数据库Pod。Pod中包含一个容器,使用MySQL 8.0.29镜像,并通过环境变量设置了root用户的密码。容器监听3306端口,并通过PersistentVolumeClaim
wee-book-mysql-pvc
挂载存储卷到/var/lib/mysql
,以确保数据库数据的持久化。
总得来说 we-book-mysql 带着他的行李 /var/lib/mysql 搬到 /mnt/data
补充一下 service
apiVersion: v1
kind: Service
metadata:
name: wee-book-mysql-service
spec:
selector:
app: we-book-mysql
ports:
- protocol: TCP
port: 13306
targetPort: 3306
nodePort: 30001
type: NodePort
此配置创建了一个名为
wee-book-mysql-service
的Service,它的作用是将外部对节点IP和30001
端口的访问透明地路由到集群内匹配标签app: we-book-mysql
的Pod的3306
端口上,从而使得外部客户端可以通过NodePort方式访问到MySQL数据库服务。这在测试和开发环境中非常有用,也适用于需要从集群外部直接访问服务的场景。(13306 集群内部访问此Service时使用的端口)
无 Volumn 对比组参考
首先来个 无 volumn 的对比组!
apiVersion: apps/v1
kind: Deployment
metadata:
name: we-book-mysql
labels:
app: we-book-mysql
spec:
replicas: 1
selector:
matchLabels:
app: we-book-mysql
template:
metadata:
name: we-book-mysql
labels:
app: we-book-mysql
spec:
containers:
- name: we-book-mysql
image: mysql:8.0.29
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: root
上面这个无配置 volumn 当 deployment 删掉的时候,数据会丢失
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
mysql> CREATE DATABASE LD;
Query OK, 1 row affected (0.01 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| LD |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql>
删掉
kubectl delete deployment.apps/we-book-mysql
然后重启
kubectl apply -f k8s-mysql-deployment.yaml
deployment.apps/we-book-mysql created
然后重新进,查询一下,可以看到创建的 LD 库 是没有持久化下来的!
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.02 sec)
有 Volumn 对比组参考
用的就是配置实战中的 Deployment 的配置
按照上面的方式,就可以发现 来回删除 deployment 创建的 Ld 数据库还是一直都在的!
如何找到挂载的data在哪
docker run --pid=host --privileged -it --rm justincormack/nsenter1
是用来运行一个特殊的 Docker 容器,该容器具有以下特点:
--pid=host
:这个标志使得容器使用主机的 PID 命名空间,意味着在容器内部你可以直接查看和操作主机的进程。--privileged
:这个标志给予容器更高的权限,允许它执行一些通常被限制的操作,比如挂载文件系统、管理网络设备等。这对于需要直接访问或修改主机系统资源的场景非常有用,但同时也带来了安全风险。-it
:这表示以交互模式运行容器,并为容器分配一个伪终端(pseudo-TTY),使得容器的标准输入保持打开,适用于需要用户交互的场景。--rm
:这个选项告诉 Docker 在容器退出后立即删除它,有助于保持环境的整洁。justincormack/nsenter1
:这是要运行的镜像名称。justincormack/nsenter1
是一个包含nsenter
工具的 Docker 镜像,nsenter
是一个用于进入现有 namespaces 的工具,常用于在容器或系统中执行需要特定命名空间上下文的操作,比如直接在宿主机的网络或文件系统命名空间内执行命令。
去到以下目录:/containers/services/02-docker/rootfs/mnt/data
02-docker
这一部分可能目录文件名不一定一样
我试了很多次,基本都是 x’x-docker 或者 直接就是一个 docker 目录
/containers/services/02-docker/rootfs/mnt/data # ls
#ib_16384_0.dblwr client-key.pem private_key.pem
#ib_16384_1.dblwr ib_buffer_pool public_key.pem
#innodb_temp ib_logfile0 server-cert.pem
auto.cnf ib_logfile1 server-key.pem
binlog.000001 ibdata1 sys
binlog.000002 ibtmp1 undo_001
binlog.index mysql undo_002
ca-key.pem mysql.ibd webook
ca.pem mysql.sock
client-cert.pem performance_schema
评论区