1. 程式人生 > 其它 >③kubernetes 儲存卷 Volume

③kubernetes 儲存卷 Volume

一 儲存卷的概念和型別

為了保證資料的永續性 必須保證docker容器中的資料儲存在容器外部 為了實現資料的永續性儲存 在宿主機和容器內做對映 可以保證在容器的生命週期結束 資料依舊可以實現永續性儲存 但是在k8s中 由於pod 分佈在各個不同的節點上 並不能實現不同節點之間永續性資料的共享 並且在節點故障時 可能會導致資料的丟失 為此 k8s就引入了外部儲存卷的功能

k8s的儲存卷型別

[root@master service]# kubectl explain pod.spec.volumes  #檢視支援的儲存型別
KIND:     Pod
VERSION:  v1

FIELDS:
   awsElasticBlockStore	<Object>
     AWSElasticBlockStore represents an AWS Disk resource that is attached to a
     kubelet's host machine and then exposed to the pod. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

   cephfs	<Object>
     CephFS represents a Ceph FS mount on the host that shares a pod's lifetime

   cinder	<Object>
     Cinder represents a cinder volume attached and mounted on kubelets host
     machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

   configMap	<Object>
     ConfigMap represents a configMap that should populate this volume

   csi	<Object>
     CSI (Container Storage Interface) represents ephemeral storage that is
     handled by certain external CSI drivers (Beta feature).
常用的分類
  1. emptyDir(臨時目錄):Pod刪除,資料也會被清除,這種儲存成為emptyDir,用於資料的臨時儲存。多容器資料互通
  2. hostPath (宿主機目錄對映):
  3. 本地的SAN (iSCSI,FC)、NAS(nfs,cifs,http)儲存
  4. 分散式儲存(glusterfs,rbd,cephfs)
  5. 雲端儲存 (EBS,Azure Disk)

二、emptyDir儲存卷演示

一個emptyDir 第一次建立是在一個pod被指定到具體node的時候,並且會一直存在在pod的生命週期當中,正如它的名字一樣,它初始化是一個空的目錄,pod中的容器都可以讀寫這個目錄,這個目錄可以被掛在到各個容器相同或者不相同的的路徑下。當一個pod因為任何原因被移除的時候,這些資料會被永久刪除。注意:一個容器崩潰了不會導致資料的丟失,因為容器的崩潰並不移除pod.

emptyDir 磁碟的作用:
(1)普通空間,基於磁碟的資料儲存
(2)作為從崩潰中恢復的備份點
(3)儲存那些那些需要長久儲存的資料,例web服務中的資料
預設的,emptyDir 磁碟會儲存在主機所使用的媒介上,可能是SSD,或者網路硬碟,這主要取決於你的環境。當然,我們也可以將emptyDir.medium的值設定為Memory來告訴Kubernetes 來掛在一個基於記憶體的目錄tmpfs,因為tmpfs速度會比硬碟塊度了,但是,當主機重啟的時候所有的資料都會丟失。

[root@k8s-master ~]# kubectl explain pods.spec.volumes.emptyDir  #檢視emptyDir儲存定義
[root@k8s-master ~]# kubectl explain pods.spec.containers.volumeMounts  #檢視容器掛載方式
[root@k8s-master ~]# mkdir volumes && cd volumes
[root@k8s-master volumes]# vim pod-vol-demo.yaml   #建立emptyDir的清單
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    magedu.com/create-by:"cluster admin"
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:    #在容器內定義掛載儲存名稱和掛載路徑
    - name: html
      mountPath: /usr/share/nginx/html/
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /data/    #在容器內定義掛載儲存名稱和掛載路徑
    command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  volumes:  #定義儲存卷
  - name: html    #定義儲存卷名稱  
    emptyDir: {}  #定義儲存卷型別

[root@master volume]# kubectl apply -f empryDir_pod.yaml 
pod/pod-demo created
[root@master volume]# kubectl get pod -l app=myapp
NAME       READY   STATUS              RESTARTS   AGE
pod-demo   0/2     ContainerCreating   0          13s
[root@master volume]# kubectl get pod -l app=myapp -o wide
NAME       READY   STATUS              RESTARTS   AGE   IP       NODE    NOMINATED NODE   READINESS GATES
pod-demo   0/2     ContainerCreating   0          16s   <none>   node2   <none>           <none>
[root@master volume]# kubectl get pod -l app=myapp -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
pod-demo   2/2     Running   0          86s   172.7.104.28   node2   <none>           <none>
[root@master volume]# curl 172.7.104.28
Wed Aug 11 09:55:47 UTC 2021
Wed Aug 11 09:55:49 UTC 2021
Wed Aug 11 09:55:51 UTC 2021
Wed Aug 11 09:55:53 UTC 2021
Wed Aug 11 09:55:55 UTC 2021
Wed Aug 11 09:55:57 UTC 2021
Wed Aug 11 09:55:59 UTC 2021
Wed Aug 11 09:56:01 UTC 2021
Wed Aug 11 09:56:03 UTC 2021
Wed Aug 11 09:56:05 UTC 2021
Wed Aug 11 09:56:07 UTC 2021
Wed Aug 11 09:56:09 UTC 2021
Wed Aug 11 09:56:11 UTC 2021
Wed Aug 11 09:56:13 UTC 2021

三、hostPath儲存卷

hostPath宿主機路徑,就是把pod所在的宿主機之上的脫離pod中的容器名稱空間的之外的宿主機的檔案系統的某一目錄和pod建立關聯關係,在pod刪除時,儲存資料不會丟失。

(1)檢視hostPath儲存型別定義
[root@k8s-master volumes]# kubectl explain pods.spec.volumes.hostPath  
KIND:     Pod
VERSION:  v1

RESOURCE: hostPath <Object>

DESCRIPTION:
     HostPath represents a pre-existing file or directory on the host machine
     that is directly exposed to the container. This is generally used for
     system agents or other privileged things that are allowed to see the host
     machine. Most containers will NOT need this. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

     Represents a host path mapped into a pod. Host path volumes do not support
     ownership management or SELinux relabeling.

FIELDS:
   path	<string> -required-  #指定宿主機的路徑
     Path of the directory on the host. If the path is a symlink, it will follow
     the link to the real path. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

   type	<string>
     Type for HostPath Volume Defaults to "" More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

type:
DirectoryOrCreate  宿主機上不存在建立此目錄  
Directory 必須存在掛載目錄  
FileOrCreate 宿主機上不存在掛載檔案就建立  
File 必須存在檔案  

(2)清單定義
apiVersion: v1
kind: Pod
metadata:
  name: volumes-hostpath-demo
spec:
  containers:
  - name: filebeat
    image: ikubernetes/filebeat:5.6.7-alpine
    env:
    - name: REDIS_HOST
      value: redis.ilinux.io:6379
    - name: LOG_LEVEL
      value: info
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: socket
      mountPath: /var/run/docker.sock
    - name: varlibdockercontainers
      mountPath: /var/lib/docker/containers
      readOnly: true
  volumes:
  - name: varlog
    hostPath:
      path: /var/log
  - name: varlibdockercontainers
    hostPath:
      path: /var/lib/docker/containers
  - name: socket
    hostPath:
      path: /var/run/docker.sock

[root@master volume]# kubectl get pod 
NAME                        READY   STATUS    RESTARTS   AGE
volumes-hostpath-demo       1/1     Running   0          7m49s
[root@master volume]# kubectl exec -it volumes-hostpath-demo -- bash
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "bash": executable file not found in $PATH: unknown
command terminated with exit code 126
[root@master volume]# kubectl exec -it volumes-hostpath-demo -- sh
/ # ls /var/log/
anaconda                  chrony                    grubby                    ntpstats                  tallylog                  vmware-vmsvc-root.log
audit                     containers                grubby_prune_debug        pods                      tuned                     vmware-vmsvc.log
boot.log                  cron                      lastlog                   rhsm                      vmware-network.1.log      vmware-vmtoolsd-root.log
boot.log-20210804         cron-20210808             maillog                   secure                    vmware-network.2.log      wtmp
boot.log-20210805         dmesg                     maillog-20210808          secure-20210808           vmware-network.3.log      yum.log
btmp                      dmesg.old                 messages                  spooler                   vmware-network.log
calico                    firewalld                 messages-20210808         spooler-20210808          vmware-vgauthsvc.log.0
/ # cat /var/log/yum.log 
Apr 19 12:38:24 Installed: 1:bash-completion-2.1-6.el7.noarch
Apr 19 12:38:40 Installed: 2:vim-filesystem-7.4.160-5.el7.x86_64
Apr 19 12:38:42 Installed: 2:vim-common-7.4.160-5.el7.x86_64
Apr 19 12:38:42 Installed: 14:libpcap-1.5.3-11.el7.x86_64
Apr 19 12:38:42 Installed: gpm-libs-1.20.7-5.el7.x86_64
Apr 19 12:38:42 Installed: 2:vim-enhanced-7.4.160-5.el7.x86_64
Apr 19 12:38:43 Installed: 14:tcpdump-4.9.2-3.el7.x86_64
Apr 19 12:38:43 Installed: lsof-4.87-6.el7.x86_64
Apr 19 12:38:43 Installed: lrzsz-0.12.20-36.el7.x86_64