七. k8s--volumes之pv pvc學習筆記


k8s存儲卷-volumes

為什么要用volumes?

容器中的磁盤的生命周期是短暫的, 這就帶來了一些列的問題:

  1. 當一個容器損壞之后, kubelet會重啟這個容器, 但是文件會丟失, 這個容器將是一個全新的狀態
  2. 當很多容器運行在同一個pod中時, 很多時候需要數據文件的共享
  3. k8s中,由於pod分布在各個不同的節點之上,並不能實現不同節點之間持久性數據的共享,並且,在節點故障時,可能會導致數據的永久性丟失。

volumes就是用來解決以上問題的

Volume 的生命周期獨立於容器,Pod 中的容器可能被銷毀和重建,但 Volume 會被保留。

volumes類型

emptyDir

一個emptyDir第一次被創建是在一個pod被指定到具體node的時候, 並且會一直存在在pod的生命周期中, 它初始化是一個空的目錄,pod中的容器都可以讀寫這個目錄,這個目錄可以被掛在到各個容器相同或者不相同的的路徑下。當一個pod因為任何原因被移除的時候,這些數據會被永久刪除。注意:一個容器崩潰了不會導致數據的丟失,因為容器的崩潰並不移除pod.
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo   #name必須小寫
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    create-by: tianpei.wang
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /data/web/html/

  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /data/
    command: ["/bin/sh", "-c", "sleep 7200"]
  volumes:
  - name: html
    emptyDir: {}

gitrepo

本質上還是一個emptyDir,創建的那一刻從git上clone下來文件,不會在更新,所以會借助sidecar容器來更新或者推送目錄中的文件代碼

hostPath

一個hostPath類型的磁盤就是掛在了主機的一個文件或者目錄,這個功能可能不是那么常用,但是這個功能提供了一個很強大的突破口對於某些應用來說 例如,如下情況我們舊可能需要用到hostPath!!!!!! 一. 某些應用需要用到docker的內部文件,這個時候只需要掛在本機的/var/lib/docker作為hostPath!!!!!! 二. 在容器中運行cAdvisor,這個時候掛在/dev/cgroups!!!!!!
apiVersion: v1
kind: Pod
metadata:
    name: pod-volume-hostpath
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      hostPath:
        path: /data/pod/volume1
        type: DirectoryOrCreate

nfs

安裝部署nfs

yum install -y nfs-utils rpcbind
systemctl start rpcbind
systemctl start nfs
[root@test share]# cat /etc/exports
/data/share 10.0.0.0/24(rw,no_root_squash)
apiVersion: v1
kind: Pod
metadata:
    name: pod-volume-hostpath
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      nfs:
        path: /data/share
        server: 10.0.0.53

k8s--PV, PVC

PV PVC帶來了哪些好處

Volume 提供了非常好的數據持久化方案,不過在可管理性上還有不足。

如前面nfs-volume舉例, 當我們創建一個掛載到nfs服務器上的pod時, 我們需要知道:

  1. nfs服務的ip
  2. nfs服務的共享目錄

Pod 通常是由應用的開發人員維護,而 Volume 則通常是由存儲系統的管理員維護。開發人員要獲得上面的信息:

  1. 要么詢問管理員。
  2. 要么自己就是管理員。

這樣就帶來一個管理上的問題:應用開發人員和系統管理員的職責耦合在一起了。如果系統規模較小或者對於開發環境這樣的情況還可以接受。但當集群規模變大,特別是對於生成環境,考慮到效率和安全性,這就成了必須要解決的問題。

Kubernetes 給出的解決方案是 PersistentVolume 和 PersistentVolumeClaim。

PersistentVolume (PV) 是外部存儲系統中的一塊存儲空間,由管理員創建和維護。與 Volume 一樣,PV 具有持久性,生命周期獨立於 Pod。

PersistentVolumeClaim (PVC) 是對 PV 的申請 (Claim)。PVC 通常由普通用戶創建和維護。需要為 Pod 分配存儲資源時,用戶可以創建一個 PVC,指明存儲資源的容量大小和訪問模式(比如只讀)等信息,Kubernetes 會查找並提供滿足條件的 PV。

有了 PersistentVolumeClaim,用戶只需要告訴 Kubernetes 需要什么樣的存儲資源,而不必關心真正的空間從哪里分配,如何訪問等底層細節信息。這些 Storage Provider 的底層信息交給管理員來處理,只有管理員才應該關心創建 PersistentVolume 的細節信息。

  • 一個pv只能對應一個pvc,但是一個pvc可以對應多個pod
  • pv屬於集群級別的資源,整個集群都可以用;pvc屬於namespace級別的資源,只屬於所屬namespace
  • pvc資源存儲在etcd中,只要etcd服務正常就不會丟失,和節點沒有關系

基於nfs配置pv和pvc

nfs的配置參考前文

定義pv

apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv001
    labels:
        name: pv001
spec:
    nfs:
        path: /data/volumes/test1
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv002
    labels:
        name: pv002
spec:
    nfs:
        path: /data/volumes/test2
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv003
    labels:
        name: pv003
spec:
    nfs:
        path: /data/volumes/test3
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 7Gi
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   2Gi        RWO,RWX        Retain           Available                                           14m
pv002   2Gi        RWO,RWX        Retain           Available                                           14m
pv003   7Gi        RWO,RWX        Retain           Available                                           14m

accessModes:

  • ReadWriteOnce (RWO) – the volume can be mounted as read-write by a single node
  • ReadOnlyMany (ROX) – the volume can be mounted read-only by many nodes
  • ReadWriteMany (RWX) – the volume can be mounted as read-write by many nodes

定義pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mypvc
    namespace: default
spec:
    accessModes: ["ReadWriteMany"]
    resources:
        requests:
            storage: 6Gi
---
apiVersion: v1
kind: Pod
metadata:
    name: myapp-pvc
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc

此時發現有符合要求的pv被綁定到了pod上

[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   2Gi        RWO,RWX        Retain           Available                                           15m
pv002   2Gi        RWO,RWX        Retain           Available                                           15m
pv003   7Gi        RWO,RWX        Retain           Bound       default/mypvc                           15m

以mysql:5.6鏡像為例

  1. 直接使用上例創建的pv

  2. 創建mysql的pvc和deployment

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
        name: mypvc
        namespace: default
    spec:
        accessModes: ["ReadWriteMany"]
        resources:
            requests:
                storage: 6Gi
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
        name: mysql-deployment
        namespace: default
    spec:
        replicas: 1
        selector:
            matchLabels:
                app: mysql
        template:
            metadata:
              labels:
                app: mysql
            spec:
                containers:
                - name: mysql
                  image: mysql:5.6
                  imagePullPolicy: IfNotPresent
                  args:
                  - "--ignore-db-dir=lost+found"
                  ports:
                  - containerPort: 3306
                  env:
                  - name: MYSQL_ROOT_PASSWORD
                    value: "mysql"
                  volumeMounts:
                  - name: mysql
                    mountPath: /var/lib/mysql
                volumes:
                - name: mysql
                  persistentVolumeClaim:
                      claimName: mypvc
    
  3. 然后在創建的pod中創建數據

    kubectl exec -it pod mysql-deployment-5b9cf7df5c-mh94v -- /bin/sh
    
    #在pod中可以看到掛載好的nfs磁盤
    # df -h
    Filesystem                     Size  Used Avail Use% Mounted on
    overlay                         20G  3.7G   16G  19% /
    tmpfs                           64M     0   64M   0% /dev
    tmpfs                          912M     0  912M   0% /sys/fs/cgroup
    /dev/sda2                       20G  3.7G   16G  19% /etc/hosts
    shm                             64M     0   64M   0% /dev/shm
    10.0.0.53:/data/volumes/test3   20G  4.3G   16G  22% /var/lib/mysql
    
    #進入mysql
    # mysql -uroot -pmysql
    
    #創建新的數據庫
    mysql> create database wtp;
    
    #進入新庫
    mysql> use wtp;
    
    #創建新的表
    mysql> CREATE TABLE `tbl_dept`(
        -> `id` INT(11) NOT NULL AUTO_INCREMENT,
        -> `deptName` VARCHAR(30) DEFAULT NULL,
        -> `locAdd`  VARCHAR(40) DEFAULT NULL,
        -> PRIMARY KEY (`id`)
        -> )ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    Query OK, 0 rows affected (0.12 sec)
    
    #刪除mysql的deployment
    kubectl delete deployments mysql-deployment
    
    #重新創建mysql的deployment
    kubectl apply -f pvc.yaml
    
    #進入新的mysql pod
    kubectl exec -it mysql-deployment-5b9cf7df5c-ztfwx -- /bin/sh
    
    #可以看到依舊掛載的之前的目錄
    # df -h
    Filesystem                     Size  Used Avail Use% Mounted on
    overlay                         20G  3.7G   16G  19% /
    tmpfs                           64M     0   64M   0% /dev
    tmpfs                          912M     0  912M   0% /sys/fs/cgroup
    /dev/sda2                       20G  3.7G   16G  19% /etc/hosts
    shm                             64M     0   64M   0% /dev/shm
    10.0.0.53:/data/volumes/test3   20G  4.3G   16G  22% /var/lib/mysql
    
    #進入mysql查看之前的數據都還在
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | wtp                |
    +--------------------+
    4 rows in set (0.08 sec)
    
    mysql> use wtp
    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_wtp |
    +---------------+
    | tbl_dept      |
    +---------------+
    1 row in set (0.00 sec)
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM