溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

kubernetes數(shù)據(jù)持久化

發(fā)布時(shí)間:2020-06-01 14:37:44 來(lái)源:億速云 閱讀:283 作者:鴿子 欄目:云計(jì)算

數(shù)據(jù)持久化就是將內(nèi)存中的數(shù)據(jù)模型轉(zhuǎn)換為存儲(chǔ)模型,以及將存儲(chǔ)模型轉(zhuǎn)換為內(nèi)存中的數(shù)據(jù)模型的統(tǒng)稱(chēng). 數(shù)據(jù)模型可以是任何數(shù)據(jù)結(jié)構(gòu)或?qū)ο竽P?存儲(chǔ)模型可以是關(guān)系模型、XML、二進(jìn)制流等。

Docker容器是有生命周期的,因此數(shù)據(jù)卷可以實(shí)現(xiàn)數(shù)據(jù)持久化

數(shù)據(jù)卷主要解決的問(wèn)題:

  • 數(shù)據(jù)持久性:當(dāng)我們寫(xiě)入數(shù)據(jù)時(shí),文件都是暫時(shí)性的存在,當(dāng)容器崩潰后,host就會(huì)將這個(gè)容器殺死,然后重新從鏡像創(chuàng)建容器,數(shù)據(jù)就會(huì)丟失
  • 數(shù)據(jù)共享:在同一個(gè)Pod中運(yùn)行容器,會(huì)存在共享文件的需求

存儲(chǔ)類(lèi)(Storage class)是k8s資源類(lèi)型的一種,它是有管理員為管理PV更加方便創(chuàng)建的一個(gè)邏輯組,可以按照存儲(chǔ)系統(tǒng)的性能高低,或者綜合服務(wù)質(zhì)量,備份策略等分類(lèi)。不過(guò)k8s本身不知道類(lèi)別到底是什么,它這是作為一個(gè)描述。

存儲(chǔ)類(lèi)的好處之一就是支持PV的動(dòng)態(tài)創(chuàng)建,當(dāng)用戶(hù)用到持久性存儲(chǔ)時(shí),不必再去提前創(chuàng)建PV,而是直接創(chuàng)建PVC就可以了,非常的方便。

存儲(chǔ)類(lèi)對(duì)象的名稱(chēng)很重要,并且出了名稱(chēng)之外,還有3個(gè)關(guān)鍵字段

Provisioner(供給方):

及提供了存儲(chǔ)資源的存儲(chǔ)系統(tǒng)。k8s內(nèi)建有多重供給方,這些供給方的名字都以“kubernetes.io”為前綴。并且還可以自定義。

Parameters(參數(shù)):存儲(chǔ)類(lèi)使用參數(shù)描述要關(guān)聯(lián)到的存儲(chǔ)卷,注意不同的供給方參數(shù)也不同。

reclaimPolicy:PV的回收策略,可用值有Delete(默認(rèn))和Retain

Volume:

emptyDir(空目錄):使用情況比較少,一般只做臨時(shí)使用,類(lèi)似Docker數(shù)據(jù) 持久化的:docker manager volume,該數(shù)據(jù)卷初始分配時(shí),是一個(gè)空目錄,同一個(gè)Pod中的容器可以對(duì)該目錄有執(zhí)行讀寫(xiě)操作,并且共享數(shù)據(jù)

使用場(chǎng)景:在同一個(gè)Pod里,不同的容器,共享數(shù)據(jù)卷

如果容器被刪除,數(shù)據(jù)仍然存在,如果Pod被刪除,數(shù)據(jù)也會(huì)被刪除

使用實(shí)例:

[root@master ~]# vim emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - image:  busybox
    name: producer
    volumeMounts:
    - mountPath:  /producer_dir  //容器內(nèi)的路徑
      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相對(duì)應(yīng)
    emptyDir: {}   //定義數(shù)據(jù)持久化類(lèi)型,即表示空目錄
[root@master ~]# kubectl  applky   -f  emptyDir.yaml
[root@master ~]# kubectl  get  pod
NAME                READY   STATUS    RESTARTS   AGE  
producer-consumer   2/2     Running   0          14s
[root@master ~]# kubectl  logs  producer-consumer  consumer 
hello  k8s

//使用inspect查看掛載的目錄在哪(查看Mount字段)

[root@master ~]# 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>
//可以看到容器運(yùn)行在node01上,在node01上找到這個(gè)容器并查看并查看詳細(xì)信息
[root@node01 ~]# docker ps
CONTAINER ID        IMAGE
f117beb235cf        busybox
13c7a18109a1        busybox
[root@node01 ~]# 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", //容器內(nèi)的掛載目錄
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
//再查看另一個(gè)容器
[root@node01 ~]# 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",  //容器內(nèi)的掛載目錄
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
//可以看到兩個(gè)容器使用的同一個(gè)掛載目錄
[root@node01 ~]# cd  /var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume
[root@node01 shared-volume]# ls
hello
[root@node01 shared-volume]# cat hello 
hello  k8s

//將容器刪除,驗(yàn)證目錄是否存在

[root@node01 ~]# docker rm  -f  13c7a18109a1 
13c7a18109a1
[root@node01 ~]# docker ps
CONTAINER ID        IMAGE
a809717b1aa5        busybox
f117beb235cf        busybox
//它會(huì)重新生成一個(gè)新的容器,來(lái)達(dá)到我們用戶(hù)所期望的狀態(tài),所以這個(gè)目錄還是存在的

//刪除Pod

[root@master ~]# kubectl  delete  pod producer-consumer
[root@master ~]# ls  /var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume
ls: 無(wú)法訪問(wèn)/var/lib/kubelet/pods/5225f542-0859-4a6a-8d99-1f23b9781807/volumes/kubernetes.io~empty-dir/shared-volume: 沒(méi)有那個(gè)文件或目錄
//Pod刪除后數(shù)據(jù)也會(huì)被刪除

hostPath Volume(使用場(chǎng)景也比較少):類(lèi)似Docker數(shù)據(jù)持久化的:bind mount

將Pod所在節(jié)點(diǎn)的文件系統(tǒng)上某一個(gè)文件或目錄掛載進(jìn)容器內(nèi)

如果Pod被刪除,數(shù)據(jù)會(huì)保留,相比較emptyDir會(huì)好一點(diǎn),不過(guò),一旦host崩潰,hostPath也無(wú)法訪問(wèn)

docker或者k8s集群本身的存儲(chǔ)會(huì)采用hostPath這種方式

k8s集群中會(huì)有很多pod,如果都是用hostPath Volume的話管理起來(lái)很不方便,所以就用到了PV

Persistent Volume | PV(持久卷)提前做好的,數(shù)據(jù)持久化的數(shù)據(jù)存放目錄

是集群中的一塊存儲(chǔ)空間,由集群管理員管理或者由Storage class(存儲(chǔ)類(lèi))自動(dòng)管理,PV和pod、deployment、Service一樣,都是一個(gè)資源對(duì)象

PersistentVolume(PV)是集群中已由管理員配置的一段網(wǎng)絡(luò)存儲(chǔ)。 集群中的資源就像一個(gè)節(jié)點(diǎn)是一個(gè)集群資源。 PV是諸如卷之類(lèi)的卷插件,但是具有獨(dú)立于使用PV的任何單個(gè)pod的生命周期。 該API對(duì)象捕獲存儲(chǔ)的實(shí)現(xiàn)細(xì)節(jié),即NFS,iSCSI或云提供商特定的存儲(chǔ)系統(tǒng)

Psesistent Volume Claim | PVC(持久卷使用聲明|申請(qǐng))

PVC代表用戶(hù)使用存儲(chǔ)的請(qǐng)求,應(yīng)用申請(qǐng)PV持久化空間的一個(gè)申請(qǐng)、聲明。K8s集群可能會(huì)有多個(gè)PV,你需要不停的為不同的應(yīng)用創(chuàng)建多個(gè)PV

它類(lèi)似于pod。Pod消耗節(jié)點(diǎn)資源,PVC消耗存儲(chǔ)資源。 pod可以請(qǐng)求特定級(jí)別的資源(CPU和內(nèi)存)。 權(quán)限要求可以請(qǐng)求特定的大小和訪問(wèn)模式

官方文檔有更詳細(xì)的說(shuō)明:https://www.kubernetes.org.cn/pvpvcstorageclass

基于NFS服務(wù)來(lái)做的PV

[root@master ~]# yum  -y  install  nfs-utils (需要節(jié)點(diǎn)全部下載,會(huì)報(bào)掛載類(lèi)型錯(cuò)誤)
[root@master ~]# yum  -y  install  rpcbind
[root@master ~]# mkdir  /nfsdata
[root@master ~]# vim  /etc/exports
/nfsdata  *(rw,sync,no_root_squash)
[root@master ~]# systemctl  start  rpcbind
[root@master ~]# systemctl  start  nfs-server
[root@master ~]# showmount  -e
Export list for master:
/nfsdata *

1.創(chuàng)建PV(實(shí)際的存儲(chǔ)目錄)  2.創(chuàng)建PVC  3.創(chuàng)建pod

創(chuàng)建PV資源對(duì)象:

[root@master ~]# vim nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-pv
spec:
  capacity: //PV容量的大小
    storage:  1Gi
  accessModes: //PV支持的訪問(wèn)模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy:  Recycle //PV的存儲(chǔ)空間的回收策略是什么
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 192.168.1.70
[root@master ~]# kubectl  apply  -f  nfs-pv.yaml
[root@master ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Available           nfs                     9m30s

accessModes: (PV支持的訪問(wèn)模式)

-  ReadWriteOnce:能以讀-寫(xiě)的方式mount到單個(gè)節(jié)點(diǎn)

-  ReadWariteMany:能以讀-寫(xiě)的方式mount到多個(gè)節(jié)點(diǎn)

-  ReadOnlyOnce:能以只讀的方式mount到單個(gè)節(jié)點(diǎn)

persistentVolumeReclaimPolicy:(PV的存儲(chǔ)空間的回收策略是什么)

Recycle:自動(dòng)清除數(shù)據(jù)

Retain:需要管理員手動(dòng)回收

Delete:云存儲(chǔ)專(zhuān)用。直接刪除數(shù)據(jù)

PV和PVC相互的關(guān)聯(lián):通過(guò)的是storageClassName && accessModes

創(chuàng)建PVC

[root@master ~]# vim  nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:    //訪問(wèn)模式
    - ReadWriteOnce  
  resources:
    requests:
      storage:  1Gi   //申請(qǐng)的容量大小
  storageClassName:  nfs    //向哪個(gè)PV申請(qǐng)
[root@master ~]# kubectl apply -f nfs-pvc.yaml
[root@master ~]# kubectl get pvc
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    test-pv   1Gi        RWO            nfs            14s
PV的應(yīng)用:

創(chuàng)建一個(gè)Pod資源:

[root@master ~]# 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
[root@master ~]# kubectl  apply  -f  pod.yaml

之前創(chuàng)建PV的時(shí)候指定的掛載目錄是/nfsdata/pv1,我們并沒(méi)有創(chuàng)建pv1這個(gè)目錄,所以這個(gè)pod是運(yùn)行不成功的。

以下是排錯(cuò)方法:

  1. kubectl  describe
  2. kubectl  logs
  3. /var/log/messages
  4. 查看該節(jié)點(diǎn)的kubelet的日志
//使用kubectl describe
[root@master ~]# kubectl  describe  pod  test-pod
mount.nfs: mounting 192.168.1.70:/nfsdata/pv1 failed, reason given by server: No such file or directory  //提示沒(méi)有文件或目錄

創(chuàng)建目錄,再查看pod狀態(tài):

[root@master ~]# 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>

驗(yàn)證是否應(yīng)用成功:

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

刪除Pod,驗(yàn)證回收策略(Recycle):

[root@master ~]# kubectl  delete  pod  test-pod
[root@master ~]# kubectl  delete  pvc test-pvc
[root@master ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Available           nfs                     42h
[root@master ~]# ls  /nfsdata/pv1/
[root@master ~]#
//驗(yàn)證成功,數(shù)據(jù)已經(jīng)回收

通常情況下不會(huì)設(shè)置為自動(dòng)刪除,不然就和emptyDir就差不多了

刪除pv,修改回收策略:

之前是先創(chuàng)建PV--->PVC--->Pod,現(xiàn)在調(diào)整一下,先創(chuàng)建PV--->---Pod--->PVC

[root@master ~]# vim  nfs-pv.yaml 
  persistentVolumeReclaimPolicy:  Retain
[root@master ~]# kubectl  apply  -f  nfs-pv.yaml 
[root@master ~]# kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Retain           Available           nfs                     7s
[root@master ~]# kubectl  apply  -f  pod.yaml 
[root@master ~]# kubectl  get pod
NAME       READY   STATUS    RESTARTS   AGE
test-pod   0/1     Pending   0          5s  //Pending正在被調(diào)度
[root@master ~]# kubectl  describe  pod test-pod
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  41s (x2 over 41s)  default-scheduler  persistentvolumeclaim "test-pvc" not found
//沒(méi)有發(fā)現(xiàn)對(duì)應(yīng)的pvc

創(chuàng)建pvc
[root@master ~]# kubectl  apply  -f  nfs-pvc.yaml
[root@master ~]# kubectl  get pod
NAME       READY   STATUS    RESTARTS   AGE
test-pod   1/1     Running   0          114s

驗(yàn)證Retain(管理員手動(dòng)刪除)回收策略:

[root@master ~]# kubectl  exec test-pod  touch  /mydata/k8s
[root@master ~]# ls  /nfsdata/pv1/
k8s
[root@master ~]# kubectl  delete  pod test-pod 
[root@master ~]# kubectl  delete  pvc test-pvc
[root@master ~]# ls  /nfsdata/pv1/
k8s
//可以看到并沒(méi)有回收
[root@master ~]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Retain           Available           nfs                     6s

mysql對(duì)數(shù)據(jù)持久化的應(yīng)用:

//這里就不再創(chuàng)建PV,PVC了,用之前的就行

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

創(chuàng)建Deploment資源對(duì)象,mysql容器

[root@master ~]# vim mysql.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: test-mysql
spec:
  selector:
    matchLabels:  //基于等值的標(biāo)簽
      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
[root@master ~]# kubectl  get deployments.
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
test-mysql   1/1     1            1           61s

進(jìn)入容器創(chuàng)建數(shù)據(jù),驗(yàn)證是否應(yīng)用PV:

[root@master ~]# 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>
[root@master ~]# kubectl  exec  -it  test-mysql-569f8df4db-fnnxc  --  mysql -u root -p123.com
mysql> create database yun33;  //創(chuàng)建數(shù)據(jù)庫(kù)
mysql> use yun33;  //選擇使用數(shù)據(jù)路
Database changed
mysql> create table my_id( id int(4));  創(chuàng)建表
mysql> insert my_id values(9527);  //在表中插入數(shù)據(jù)
mysql> select * from my_id;  //查看表中所有數(shù)據(jù)
+------+
| id   |
+------+
| 9527 |
+------+
1 row in set (0.00 sec)
[root@master ~]# ls /nfsdata/pv1/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  k8s  mysql  performance_schema  yun33

關(guān)閉node01節(jié)點(diǎn),模擬節(jié)點(diǎn)宕機(jī):

[root@master ~]# 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>
[root@master ~]# 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>

驗(yàn)證:在node02上新生成的pod,它內(nèi)部是否有我們創(chuàng)建的數(shù)據(jù)

[root@master ~]# 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)
[root@master ~]# ls  /nfsdata/pv1/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  k8s  mysql  performance_schema  yun33
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI