k8s数据持久化

k8s数据持久化

Docker容器是有生命周期的,因此数据卷可以实现数据持久化

数据卷主要解决的问题:

  • 数据持久性:当我们写入数据时,文件都是暂时性的存在,当容器崩溃后,host就会将这个容器杀死,然后重新从镜像创建容器,数据就会丢失
  • 数据共享:在同一个Pod中运行容器,会存在共享文件的需求

存储类(Storage class)是k8s资源类型的一种,它是有管理员为管理PV更加方便创建的一个逻辑组,可以按照存储系统的性能高低,或者综合服务质量,备份策略等分类。不过k8s本身不知道类别到底是什么,它这是作为一个描述。

存储类的好处之一就是支持PV的动态创建,当用户用到持久性存储时,不必再去提前创建PV,而是直接创建PVC就可以了,非常的方便。

存储类对象的名称很重要,并且出了名称之外,还有3个关键字段

Provisioner(供给方):

及提供了存储资源的存储系统。k8s内建有多重供给方,这些供给方的名字都以“kubernetes.io”为前缀。并且还可以自定义。

Parameters(参数):存储类使用参数描述要关联到的存储卷,注意不同的供给方参数也不同。

reclaimPolicy:PV的回收策略,可用值有Delete(默认)和Retain

Volume:

emptyDir(空目录):使用情况比较少,一般只做临时使用,类似Docker数据 持久化的:docker manager volume,该数据卷初始分配时,是一个空目录,同一个Pod中的容器可以对该目录有执行读写操作,并且共享数据

? 使用场景:在同一个Pod里,不同的容器,共享数据卷

? 如果容器被删除,数据仍然存在,如果Pod被删除,数据也会被删除

使用实例:

[[email protected] ~]# vim emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - image:  busybox
    name: producer
    volumeMounts:
    - mountPath:  /producer_dir  //容器内的路径
      name: shared-volume  //指定本地的目录名
    args:
    - /bin/sh
    - -c
    - echo  "hello k8s" > /producer_dir/hello;  sleep 30000

  - image:  busybox
    name: consumer
    volumeMounts:
    - mountPath:  /consumer_dir
      name: shared-volume
    args:
    - /bin/sh
    - -c
    - cat /consumer_dir/hello;  sleep 30000

  volumes:
  - name: shared-volume  //这里的名字必须与上面的Pod的mountPath的name相对应
    emptyDir: {}   //定义数据持久化类型,即表示空目录
[[email protected] ~]# kubectl  applky   -f  emptyDir.yaml
[[email protected] ~]# kubectl  get  pod
NAME                READY   STATUS    RESTARTS   AGE
producer-consumer   2/2     Running   0          14s
[[email protected] ~]# kubectl  logs  producer-consumer  consumer
hello  k8s

//使用inspect查看挂载的目录在哪(查看Mount字段)

[[email protected] ~]# kubectl  get  pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
producer-consumer   2/2     Running   0          69s   10.244.1.2   node01   <none>           <none>
//可以看到容器运行在node01上,在node01上找到这个容器并查看并查看详细信息
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE
f117beb235cf        busybox
13c7a18109a1        busybox
[[email protected] ~]# docker inspect 13c7a18109a1
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/producer_dir", //容器内的挂载目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
//再查看另一个容器
[[email protected] ~]# docker inspect f117beb235cf
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/consumer_dir",  //容器内的挂载目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
//可以看到两个容器使用的同一个挂载目录
[[email protected] ~]# cd  /var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume
[[email protected] shared-volume]# ls
hello
[[email protected] shared-volume]# cat hello
hello  k8s

//将容器删除,验证目录是否存在

[[email protected] ~]# docker rm  -f  13c7a18109a1
13c7a18109a1
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE
a809717b1aa5        busybox
f117beb235cf        busybox
//它会重新生成一个新的容器,来达到我们用户所期望的状态,所以这个目录还是存在的

//删除Pod

[[email protected] ~]# kubectl  delete  pod producer-consumer
[[email protected] ~]# ls  /var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume
ls: 无法访问/var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume: 没有那个文件或目录
//Pod删除后数据也会被删除

hostPath Volume(使用场景也比较少):类似Docker数据持久化的:bind mount

将Pod所在节点的文件系统上某一个文件或目录挂载进容器内

? 如果Pod被删除,数据会保留,相比较emptyDir会好一点,不过,一旦host崩溃,hostPath也无法访问

docker或者k8s集群本身的存储会采用hostPath这种方式

k8s集群中会有很多pod,如果都是用hostPath Volume的话管理起来很不方便,所以就用到了PV

Persistent Volume | PV(持久卷)提前做好的,数据持久化的数据存放目录

是集群中的一块存储空间,由集群管理员管理或者由Storage class(存储类)自动管理,PV和pod、deployment、Service一样,都是一个资源对象

PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统

Psesistent Volume Claim | PVC(持久卷使用声明|申请)

PVC代表用户使用存储的请求,应用申请PV持久化空间的一个申请、声明。K8s集群可能会有多个PV,你需要不停的为不同的应用创建多个PV

它类似于pod。Pod消耗节点资源,PVC消耗存储资源。 pod可以请求特定级别的资源(CPU和内存)。 权限要求可以请求特定的大小和访问模式

官方文档有更详细的说明:https://www.kubernetes.org.cn/pvpvcstorageclass

基于NFS服务来做的PV

[[email protected] ~]# yum  -y  install  nfs-utils (需要节点全部下载,会报挂载类型错误)
[[email protected] ~]# yum  -y  install  rpcbind
[[email protected] ~]# mkdir  /nfsdata
[[email protected] ~]# vim  /etc/exports
/nfsdata  *(rw,sync,no_root_squash)
[[email protected] ~]# systemctl  start  rpcbind
[[email protected] ~]# systemctl  start  nfs-server
[[email protected] ~]# showmount  -e
Export list for master:
/nfsdata *

1.创建PV(实际的存储目录) 2.创建PVC 3.创建pod

创建PV资源对象:

[[email protected] ~]# vim nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-pv
spec:
  capacity: //PV容量的大小
    storage:  1Gi
  accessModes: //PV支持的访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy:  Recycle //PV的存储空间的回收策略是什么
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 192.168.1.70
[[email protected] ~]# kubectl  apply  -f  nfs-pv.yaml
[[email protected] ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Available           nfs                     9m30s

accessModes: (PV支持的访问模式)

? - ReadWriteOnce:能以读-写的方式mount到单个节点

? - ReadWariteMany:能以读-写的方式mount到多个节点

? - ReadOnlyOnce:能以只读的方式mount到单个节点

persistentVolumeReclaimPolicy:(PV的存储空间的回收策略是什么)

? Recycle:自动清除数据

? Retain:需要管理员手动回收

? Delete:云存储专用。直接删除数据

PV和PVC相互的关联:通过的是storageClassName && accessModes

创建PVC

[[email protected] ~]# vim  nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:    //访问模式
    - ReadWriteOnce
  resources:
    requests:
      storage:  1Gi   //申请的容量大小
  storageClassName:  nfs    //向哪个PV申请
[[email protected] ~]# kubectl apply -f nfs-pvc.yaml
[[email protected] ~]# kubectl get pvc
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    test-pv   1Gi        RWO            nfs            14s

PV的应用:

创建一个Pod资源:

[[email protected] ~]# vim  pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: pod1
    image:  busybox
    args:
    - /bin/sh
    - -c
    - sleep 30000
    volumeMounts:
    - mountPath:  "/mydata"
      name: mydata
  volumes:
    - name:  mydata
      persistentVolumeClaim:
        claimName:  test-pvc
[[email protected] ~]# kubectl  apply  -f  pod.yaml

之前创建PV的时候指定的挂载目录是/nfsdata/pv1,我们并没有创建pv1这个目录,所以这个pod是运行不成功的。

以下是排错方法:

  1. kubectl describe
  2. kubectl logs
  3. /var/log/messages
  4. 查看该节点的kubelet的日志
//使用kubectl describe
[[email protected] ~]# kubectl  describe  pod  test-pod
mount.nfs: mounting 192.168.1.70:/nfsdata/pv1 failed, reason given by server: No such file or directory  //提示没有文件或目录

创建目录,再查看pod状态:

[[email protected] ~]# mkdir  /nfsdata/pv1
NAME       READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
test-pod   1/1     Running   0          12m   10.244.1.3   node01   <none>           <none>

验证是否应用成功:

[[email protected] ~]# kubectl  exec  test-pod  touch /mydata/hello
[[email protected] ~]# ls  /nfsdata/pv1/
hello
[[email protected] ~]# echo  123  >  /nfsdata/pv1/hello
[[email protected] ~]# kubectl  exec  test-pod  cat /mydata/hello
123

删除Pod,验证回收策略(Recycle):

[[email protected] ~]# kubectl  delete  pod  test-pod
[[email protected] ~]# kubectl  delete  pvc test-pvc
[[email protected] ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Available           nfs                     42h
[[email protected] ~]# ls  /nfsdata/pv1/
[[email protected] ~]#
//验证成功,数据已经回收

通常情况下不会设置为自动删除,不然就和emptyDir就差不多了

删除pv,修改回收策略:

之前是先创建PV--->PVC--->Pod,现在调整一下,先创建PV--->---Pod--->PVC

[[email protected] ~]# vim  nfs-pv.yaml
  persistentVolumeReclaimPolicy:  Retain
[[email protected] ~]# kubectl  apply  -f  nfs-pv.yaml
[[email protected] ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Retain           Available           nfs                     7s
[[email protected] ~]# kubectl  apply  -f  pod.yaml
[[email protected] ~]# kubectl  get pod
NAME       READY   STATUS    RESTARTS   AGE
test-pod   0/1     Pending   0          5s  //Pending正在被调度
[[email protected] ~]# kubectl  describe  pod test-pod
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  41s (x2 over 41s)  default-scheduler  persistentvolumeclaim "test-pvc" not found
//没有发现对应的pvc

创建pvc
[[email protected] ~]# kubectl  apply  -f  nfs-pvc.yaml
[[email protected] ~]# kubectl  get pod
NAME       READY   STATUS    RESTARTS   AGE
test-pod   1/1     Running   0          114s

验证Retain(管理员手动删除)回收策略:

[[email protected] ~]# kubectl  exec test-pod  touch  /mydata/k8s
[[email protected] ~]# ls  /nfsdata/pv1/
k8s
[[email protected] ~]# kubectl  delete  pod test-pod
[[email protected] ~]# kubectl  delete  pvc test-pvc
[[email protected] ~]# ls  /nfsdata/pv1/
k8s
//可以看到并没有回收
[[email protected] ~]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Retain           Available           nfs                     6s

mysql对数据持久化的应用:

//这里就不再创建PV,PVC了,用之前的就行

[[email protected] ~]# kubectl  apply  -f  nfs-pvc.yaml
[[email protected] ~]# kubectl  get pvc
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    test-pv   1Gi        RWO            nfs            7s

创建Deploment资源对象,mysql容器

[[email protected] ~]# vim mysql.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: test-mysql
spec:
  selector:
    matchLabels:  //基于等值的标签
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: 123.com
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: test-pvc
[[email protected] ~]# kubectl  get deployments.
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
test-mysql   1/1     1            1           61s

进入容器创建数据,验证是否应用PV:

[[email protected] ~]# kubectl  get pod -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
test-mysql-569f8df4db-fnnxc   1/1     Running   0          32m   10.244.1.5   node01   <none>           <none>
[[email protected] ~]# kubectl  exec  -it  test-mysql-569f8df4db-fnnxc  --  mysql -u root -p123.com
mysql> create database yun33;  //创建数据库
mysql> use yun33;  //选择使用数据路
Database changed
mysql> create table my_id( id int(4));  创建表
mysql> insert my_id values(9527);  //在表中插入数据
mysql> select * from my_id;  //查看表中所有数据
+------+
| id   |
+------+
| 9527 |
+------+
1 row in set (0.00 sec)
[[email protected] ~]# ls /nfsdata/pv1/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  k8s  mysql  performance_schema  yun33

关闭node01节点,模拟节点宕机:

[[email protected] ~]# kubectl get pod -o wide -w
NAME                          READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
test-mysql-569f8df4db-fnnxc   1/1     Running   0          36m   10.244.1.5   node01   <none>           <none>
test-mysql-569f8df4db-fnnxc   1/1     Terminating   0          38m   10.244.1.5   node01   <none>           <none>
test-mysql-569f8df4db-2m5rd   0/1     Pending       0          0s    <none>       <none>   <none>           <none>
test-mysql-569f8df4db-2m5rd   0/1     Pending       0          0s    <none>       node02   <none>           <none>
test-mysql-569f8df4db-2m5rd   0/1     ContainerCreating   0          0s    <none>       node02   <none>           <none>
test-mysql-569f8df4db-2m5rd   1/1     Running             0          2s    10.244.2.4   node02   <none>           <none>
[[email protected] ~]# kubectl get pod -o wide
NAME                          READY   STATUS        RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
test-mysql-569f8df4db-2m5rd   1/1     Running       0          20s   10.244.2.4   node02   <none>           <none>
test-mysql-569f8df4db-fnnxc   1/1     Terminating   0          38m   10.244.1.5   node01   <none>           <none>

验证:在node02上新生成的pod,它内部是否有我们创建的数据

[[email protected] ~]# kubectl  exec -it test-mysql-569f8df4db-2m5rd  -- mysql -u root -p123.com
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| yun33              |
+--------------------+
4 rows in set (0.01 sec)

mysql> use yun33;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------+
| Tables_in_yun33 |
+-----------------+
| my_id           |
+-----------------+
1 row in set (0.01 sec)

mysql> select *  from my_id;
+------+
| id   |
+------+
| 9527 |
+------+
1 row in set (0.01 sec)
[[email protected] ~]# ls  /nfsdata/pv1/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  k8s  mysql  performance_schema  yun33

原文地址:https://blog.51cto.com/13997536/2469764

时间: 2024-10-02 20:31:05

k8s数据持久化的相关文章

k8s数据持久化之statefulset的数据持久化,并自动创建PV与PVC

一:Statefulset StatefulSet是为了解决有状态服务的问题,对应的Deployment和ReplicaSet是为了无状态服务而设计,其应用场景包括:1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现2.稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现3.有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依

k8s数据持久化之Secret

一.Secret资源对象:解决了密码.token.密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中.Secret可以以Volume或者环境变量的方式使用.用来保存一些敏感信息,比如数据库的用户名密码或者密钥.Secret有三种类型:1.Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中.2.Opaque

K8s数据持久化之自动创建PV

在前两篇实现k8s的数据持久化的流程为:搭建nfs底层存储===>创建PV====>创建PVC===>创建pod.最终pod中的container实现数据的持久化. 上述流程中,看似没什么问题,但细想一下,PVC在向PV申请存储空间的时候,是根据指定的pv名称.访问模式.容量大小来决定具体向哪个PV来申请空间的,如果PV的容量为20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间为10G,那么一旦这个PVC是向上面的PV申请的空间,也就是说,那个PV

k8s实践(七):存储卷和数据持久化(Volumes and Persistent Storage)

环境说明: 主机名 操作系统版本 ip docker version kubelet version 配置 备注 master Centos 7.6.1810 172.27.9.131 Docker 18.09.6 V1.14.2 2C2G master主机 node01 Centos 7.6.1810 172.27.9.135 Docker 18.09.6 V1.14.2 2C2G node节点 node02 Centos 7.6.1810 172.27.9.136 Docker 18.09.

K8s之MySQL实现数据持久化

这个是一个只写配置及验证的博文...... 博文大纲:1.搭建nfs存储2.创建PV3.创建PVC4.确认pv及pvc的状态5.创建pod+svc(service)6.进入MySQL数据库,添加测试数据7.手动删除节点上的容器,验证数据库内的数据是否还存在8.模拟MySQL容器所在的节点宕机,验证数据是否会丢失9.client端访问MySQL数据库 k8s集群环境如下: master节点IP:192.168.20.6 node01节点IP:192.168.20.7 node02节点IP:192.

K8s实现数据持久化

前言 在一切虚拟化解决方案中,数据的持久化都是需要我们非常关心的问题,docker如此,K8s也不例外.在k8s中,有一个数据卷的概念. k8s数据卷主要解决了以下两方面问题: 数据持久性:通常情况下,容器运行起来后,写入到其文件系统的文件时暂时性的.当容器崩溃后,kebelet将这个容器kill掉,然后生成一个新的容器,此时,新运行的容器将没有原来容器内的文件,因为容器是重新从镜像创建的. 数据共享:同一个pod中运行的容器之间,经常会存在共享文件/文件夹的需求. 在k8s中,Volume(数

k8s存储数据持久化,emptyDir,hostPath,基于Nfs服务的PV,PVC

在docker和K8S中都存在容器是有生命周期的,因此数据卷可以实现数据持久化. 数据卷解决的主要问题: 1.数据持久性:当我们写入数据时,文件都是暂时性的存在,当容器崩溃后,host就会将这个容器杀死,然后重新从镜像创建容器,数据就会丢失. 2.数据共享:在同一个Pod中运行容器,会存在共享文件的需求. 数据卷的类型: 1.emptyDiremptyDir数据卷类似于docker数据持久化的docker manager volume,该数据卷初分配时,是一个空目录,同一个Pod中的容器可以对该

Kubernetes数据持久化方案

在开始介绍k8s持久化存储前,我们有必要了解一下k8s的emptydir和hostpath.configmap以及secret的机制和用途. 1.EmptydirEmptyDir是一个空目录,他的生命周期和所属的 Pod 是完全一致的,EmptyDir主要作用可以在同一 Pod 内的不同容器之间共享工作过程中产生的文件.如果Pod配置了emptyDir类型Volume, Pod 被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致

Kubernetes数据持久化之Storage Class(存储类)自动创PV

通过博文Kubernetes的存储之Volume可以了解到Kubernets实现数据持久化的流程为:搭建NFS底层存储-->创建PV-->创建PVC-->创建pod最终将pod中的container实现数据的持久化! 从上述流程中,看似没有什么问题,但是仔细研究就会发现:PVC在向PV申请存储空间时,是根据指定PV的名称.访问模式.容量大小来决定具体向哪个PV申请空间的. 打比方说:如果PV的容量是20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间