k8s数据持久化-pv和pbc NFS实现
1、Volume在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是P
目录
1、Volume
在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是Pod级别的,可以用来实现Pod中容器的文件共享。目前,Kubernetes支持的数据卷类型如下:
1) EmptyDir
2) HostPath
3) GCE Persistent Disk
4) AWS Elastic Block Store
5) NFS
6) iSCSI
7) Flocker
8) GlusterFS
9) RBD
10) Git Repo
11) Secret
12) Persistent Volume Claim
13) Downward API
1.1本地数据卷
EmptyDir、HostPath这两种类型的数据卷,只能最用于本地文件系统。本地数据卷中的数据只会存在于一台机器上,所以当Pod发生迁移的时候,数据便会丢失。该类型Volume的用途是:Pod中容器间的文件共享、共享宿主机的文件系统。
1.1.1 EmptyDir
如果Pod配置了EmpyDir数据卷,在Pod的生命周期内都会存在,当Pod被分配到 Node上的时候,会在Node上创建EmptyDir数据卷,并挂载到Pod的容器中。只要Pod 存在,EmpyDir数据卷都会存在(容器删除不会导致EmpyDir数据卷丟失数据),但是如果Pod的生命周期终结(Pod被删除),EmpyDir数据卷也会被删除,并且永久丢失。
EmpyDir数据卷非常适合实现Pod中容器的文件共享。Pod的设计提供了一个很好的容器组合的模型,容器之间各司其职,通过共享文件目录来完成交互,比如可以通过一个专职日志收集容器,在每个Pod中和业务容器中进行组合,来完成日志的收集和汇总。
1.1.2 HostPath
HostPath数据卷允许将容器宿主机上的文件系统挂载到Pod中。如果Pod需要使用宿主机上的某些文件,可以使用HostPath。
1.2网络数据卷
Kubernetes提供了很多类型的数据卷以集成第三方的存储系统,包括一些非常流行的分布式文件系统,也有在IaaS平台上提供的存储支持,这些存储系统都是分布式的,通过网络共享文件系统,因此我们称这一类数据卷为网络数据卷。
网络数据卷能够满足数据的持久化需求,Pod通过配置使用网络数据卷,每次Pod创建的时候都会将存储系统的远端文件目录挂载到容器中,数据卷中的数据将被水久保存,即使Pod被删除,只是除去挂载数据卷,数据卷中的数据仍然保存在存储系统中,且当新的Pod被创建的时候,仍是挂载同样的数据卷。网络数据卷包含以下几种:NFS、iSCISI、GlusterFS、RBD(Ceph Block Device)、Flocker、AWS Elastic Block Store、GCE Persistent Disk
1.3 Persistent Volume和Persistent Volume Claim
理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,有时候并不需要关心各种存储实现,只希望能够安全可靠地存储数据。Kubernetes中提供了Persistent Volume和Persistent Volume Claim机制,这是存储消费模式。Persistent Volume是由系统管理员配置创建的一个数据卷(目前支持HostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、iSCSI、GlusterFS、RBD),它代表了某一类存储插件实现;而对于普通用户来说,通过Persistent Volume Claim可请求并获得合适的Persistent Volume,而无须感知后端的存储实现。Persistent Volume和Persistent Volume Claim的关系其实类似于Pod和Node,Pod消费Node资源,Persistent Volume Claim则消费Persistent Volume资源。Persistent Volume和Persistent Volume Claim相互关联,有着完整的生命周期管理:
-
准备:系统管理员规划或创建一批Persistent Volume;
-
绑定:用户通过创建Persistent Volume Claim来声明存储请求,Kubernetes发现有存储请求的时候,就去查找符合条件的Persistent Volume(最小满足策略)。找到合适的就绑定上,找不到就一直处于等待状态;
-
使用:创建Pod的时候使用Persistent Volume Claim;
-
释放:当用户删除绑定在Persistent Volume上的Persistent Volume Claim时,Persistent Volume进入释放状态,此时Persistent Volume中还残留着上一个Persistent Volume Claim的数据,状态还不可用;
-
回收:是否的Persistent Volume需要回收才能再次使用。回收策略可以是人工的也可以是Kubernetes自动进行清理(仅支持NFS和HostPath)
1.4信息数据卷
Kubernetes中有一些数据卷,主要用来给容器传递配置信息,我们称之为信息数据卷,比如Secret(处理敏感配置信息,密码、Token等)、Downward API(通过环境变量的方式告诉容器Pod的信息)、Git Repo(将Git仓库下载到Pod中),都是将Pod的信息以文件形式保存,然后以数据卷方式挂载到容器中,容器通过读取文件获取相应的信息。
网络设计
一台NFS服务器: 192.168.174.133
一台minikube服务器: 192.168.174.147
2.通过NFS实现持久化存储
2.1 NFS服务器端
安装nfs
[root@nfs ~]# yum install -y nfs-utils
新建共享文件夹
mkdir /nfsdata
chmod 666 /nfsdata/
编辑/etc/exports配置文件
[root@nfs ~]# systemctl start nfs-server
[root@nfs ~]# cat /etc/exports
/nfsdata 192.168.174.0/24(rw,no_root_squash,no_all_squash,sync)
刷新配置
[root@nfs ~]# exportfs -rv
exporting 192.168.174.0/24:/nfsdata
2.2 minikube服务器端
安装nfs服务
yum install -y nfs-utils
创建PV
apiVersion: v1
kind: PersistentVolume #资源类型
metadata:
name: mysql-nginx
labels:
type: mysql-nginx-nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany #访问模式,多个客户端读写
persistentVolumeReclaimPolicy: Recycle #回收策略-可以回收
storageClassName: nfs
nfs:
path: "/nfsdata"
server: 192.168.174.138 #nfs 服务器
readOnly: false #只读
[root@lb-nginx ~]# kubectl apply -f pv-nginx.yaml
persistentvolume/mysql-nginx created
创建PVC
$ cat pvc_nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: nfs
[root@kube ~]# kubectl apply -f pvc-nfs.yaml
[root@kube myYaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mysql-nginx 10Gi RWX Recycle Bound default/mysql-nginx-pvc nfs 7s
[root@kube myYaml]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-nginx-pvc Bound mysql-nginx 10Gi RWX nfs 36s
加载一个mysql-deployment.yaml
$ cat mysql-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment #副本控制器Deployment
metadata:
name: mysql57 #Deployment的名称,全局唯一
spec:
replicas: 1 #Pod副本的期待数量
template: #根据此模版创建Pod的副本(实例)
metadata:
labels:
app: mysql57 #Pod副本拥有的标签,对应Deployment的selector
spec:
containers: #Pod内,定义容器
- name: mysql57 #容器名称
image: mysql:5.7 #Docker image
ports:
- containerPort: 3306 #容器应用监听的端口
volumeMounts:
- name: mysql-data-pvc #和下面一致
mountPath: /var/lib/mysql
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD #这里设置root初始密码
value: "123456"
volumes:
- name: mysql-data-pvc
persistentVolumeClaim:
claimName: mysql-nginx-pvc
使用NodePort发布mysql服务
[root@kube myYaml]# cat mysqlService.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql57service
spec:
type: NodePort
selector:
app: mysql57 #pod 的名字
ports:
- name: http
nodePort: 30006
protocol: TCP
port: 3303
targetPort: 3306
[root@kube myYaml]# cat kustomization.yaml
resources:
- pv-nfs.yaml
- pvc-nfs.yaml
- mysql-deploy.yaml
- mysqlService.yaml
[root@kube myYaml]# kubectl apply -k .
[root@kube myYaml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql57-78f5b86655-wm7p6 1/1 Running 0 7m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8h
mysql57service NodePort 10.109.195.199 <none> 3303:30006/TCP 8m6s
[root@nfsnfsdata]# mysql -uroot -h 192.168.174.147 -P 30006 -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.33 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> create database hunannd;
Query OK, 1 row affected (0.01 sec)
[root@nfs nfsdata]# ls
auto.cnf client-cert.pem ib_buffer_pool ib_logfile1 ouzhe public_key.pem sys
ca-key.pem client-key.pem ibdata1 ibtmp1 performance_schema server-cert.pem
ca.pem hunannd ib_logfile0 mysql private_key.pem server-key.pem
中间遇到的一些坑和问题:
- NFS 不要对用户进行压缩,不然mysql容器起不来:(rw,no_root_squash,no_all_squash,sync)
- 确定PVC绑定大对应的PV上
- 如果是Nginx服务,的先将目标网页存放到NFS服务器上,否则nginx访问权限会有误
- 当机器重启了,要重新关闭一下防火墙
如何将PVC绑定到特定的PV上?
简单来讲,就是给PV打上一个label,然后让PVC去匹配这个label即可。
如:https://blog.csdn.net/qianggezhishen/article/details/80764378
参考:
https://www.cnblogs.com/benjamin77/p/9944268.html#auto_id_1
更多推荐
所有评论(0)