K8s中Volume


容器磁盤上的文件的生命周期是短暫的,這就使得在容器中運行重要應用時會出現一些問題。首先,當容器崩潰
時,kubelet 會重啟它,但是容器中的文件將丟失——容器以干凈的狀態(鏡像最初的狀態)重新啟動。其次,在
Pod 中同時運行多個容器時,這些容器之間通常需要共享文件。Kubernetes 中的 Volume 抽象就很好的解決了這些問題
背景
Kubernetes 中的卷有明確的壽命 —— 與封裝它的 Pod 相同。所f以,卷的生命比 Pod 中的所有容器都長,當這
個容器重啟時數據仍然得以保存。當然,當 Pod 不再存在時,卷也將不復存在。也許更重要的是,Kubernetes
支持多種類型的卷,Pod 可以同時使用任意數量的卷卷的類型。

emptyDir

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

emptyDir 磁盤的作用:

scratch space, such as for a disk-based mergesortcw

checkpointing a long computation for recovery from crashes

holding files that a content-manager container fetches while a webserver container serves the data

  • 普通空間,基於磁盤的數據存儲
  • 作為從崩潰中恢復的備份點
  • 存儲那些那些需要長久保存的數據,例web服務中的數據

默認的,emptyDir 磁盤會存儲在主機所使用的媒介上,可能是SSD,或者網絡硬盤,這主要取決於你的環境。當然,我們也可以將emptyDir.medium的值設置為Memory來告訴Kubernetes 來掛在一個基於內存的目錄tmpfs,因為

tmpfs速度會比硬盤塊度了,但是,當主機重啟的時候所有的數據都會丟失

[root@k8s-master mnt]# cat volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: wangyanglinux/myapp:v2
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - name: liveness-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","sleep 6000s"]
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
    - name: cache-volume
      emptyDir: {}
[root@k8s-master mnt]#

執行:

[root@k8s-master mnt]# vim volume.yaml
[root@k8s-master mnt]# kubectl create -f volume.yaml
pod/test-pd created
[root@k8s-master mnt]# kubectl describe pod test-pd
Name:         test-pd
Namespace:    default
Priority:     0
Node:         k8s-node02/192.168.180.136
Start Time:   Fri, 27 Dec 2019 13:44:38 +0800
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.1.49
IPs:
  IP:  10.244.1.49
Containers:
  test-container:
    Container ID:   docker://236b2b8c29ed6d42b74aaef24bc1d43d21863598c7c5a5cd19b9fc953993c7c0
    Image:          wangyanglinux/myapp:v2
    Image ID:       docker-pullable://wangyanglinux/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 27 Dec 2019 13:44:40 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /cache from cache-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
  liveness-exec-container:
    Container ID:  docker://304943afd2171d58d2b36d93f3833405f7e2651ffb67ad807adaf80c8a6fd330
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      sleep 6000s
    State:          Running
      Started:      Fri, 27 Dec 2019 13:44:40 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /cache from cache-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  cache-volume:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  default-token-6wcrh:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-6wcrh
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From                 Message
  ----    ------     ----       ----                 -------
  Normal  Scheduled  <unknown>  default-scheduler    Successfully assigned default/test-pd to k8s-node02
  Normal  Pulled     8s         kubelet, k8s-node02  Container image "wangyanglinux/myapp:v2" already present on machine
  Normal  Created    8s         kubelet, k8s-node02  Created container test-container
  Normal  Started    7s         kubelet, k8s-node02  Started container test-container
  Normal  Pulled     7s         kubelet, k8s-node02  Container image "busybox" already present on machine
  Normal  Created    7s         kubelet, k8s-node02  Created container liveness-exec-container
  Normal  Started    7s         kubelet, k8s-node02  Started container liveness-exec-container
[root@k8s-master mnt]# kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
test-pd   2/2     Running   0          107s
[root@k8s-master mnt]# !711
kubectl exec test-pd -it -- /bin/sh
Defaulting container name to test-container.
Use 'kubectl describe pod/test-pd -n default' to see all of the containers in this pod.
/ # ls
bin    cache  dev    etc    home   lib    media  mnt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # exit

看來里面有這個文件夾

hostPath
hostPath 卷將主機節點的文件系統中的文件或目錄掛載到集群中
hostPath 的用途如下:
運行需要訪問 Docker 內部的容器;使用 /var/lib/docker 的 hostPath
在容器中運行 cAdvisor;使用 /dev/cgroups 的 hostPath
允許 pod 指定給定的 hostPath 是否應該在 pod 運行之前存在,是否應該創建,以及它應該以什么形式存在
除了所需的 path 屬性之外,用戶還可以為 hostPath 卷指定 type

使用這種卷類型是請注意,因為:
由於每個節點上的文件都不同,具有相同配置(例如從 podTemplate 創建的)的 pod 在不同節點上的行為可能會有所不同。
當 Kubernetes 按照計划添加資源感知調度時,將無法考慮 hostPath 使用的資源
在底層主機上創建的文件或目錄只能由 root 寫入。您需要在特權容器中以 root 身份運行進程,或修改主機上的文件權限以便寫入 hostPath 卷。

[root@k8s-master mnt]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd1
spec:
  containers:
  - image: wangyanglinux/myapp:v2
    name: test-container
    volumeMounts:
    - mountPath: /test-pd1
      name: test-volume1
  volumes:
  - name: test-volume1
    hostPath:
      path: /data
      type: Directory
[root@k8s-master mnt]#
[root@k8s-master mnt]# vim pod1.yaml
[root@k8s-master mnt]# kubectl create -f pod1.yaml
pod/test-pd1 created
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          101m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          9s     <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          102m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          23s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          102m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          25s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          102m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          48s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          102m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          50s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          103m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          79s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          103m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          81s    <none>        k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS              RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running             1          104m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   0/1     ContainerCreating   0          3m2s   <none>        k8s-node01   <none>           <none>

假如子節點沒有data文件夾

[root@k8s-master mnt]# kubectl describe pod test-pd1
Name:         test-pd1
Namespace:    default
Priority:     0
Node:         k8s-node01/192.168.180.135
Start Time:   Fri, 27 Dec 2019 15:31:19 +0800
Labels:       <none>
Annotations:  <none>
Status:       Pending
IP:
IPs:          <none>
Containers:
  test-container:
    Container ID:
    Image:          wangyanglinux/myapp:v2
    Image ID:
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /test-pd1 from test-volume1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  test-volume1:
    Type:          HostPath (bare host directory volume)
    Path:          /data
    HostPathType:  Directory
  default-token-6wcrh:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-6wcrh
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason       Age                From                 Message
  ----     ------       ----               ----                 -------
  Normal   Scheduled    <unknown>          default-scheduler    Successfully assigned default/test-pd1 to k8s-node01
  Warning  FailedMount  21s (x6 over 36s)  kubelet, k8s-node01  MountVolume.SetUp failed for volume "test-volume1" : hostPath type check failed: /data is not a directory
[root@k8s-master mnt]# kubectl describe pod test-pd1
Name:         test-pd1
Namespace:    default
Priority:     0
Node:         k8s-node01/192.168.180.135
Start Time:   Fri, 27 Dec 2019 15:31:19 +0800
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.2.55
IPs:
  IP:  10.244.2.55
Containers:
  test-container:
    Container ID:   docker://5a8696561897043c9c141acae2f66eea2ca6d4b834a15c143c953a269113e25b
    Image:          wangyanglinux/myapp:v2
    Image ID:       docker-pullable://wangyanglinux/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 27 Dec 2019 15:32:04 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /test-pd1 from test-volume1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  test-volume1:
    Type:          HostPath (bare host directory volume)
    Path:          /data
    HostPathType:  Directory
  default-token-6wcrh:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-6wcrh
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason       Age                  From                 Message
  ----     ------       ----                 ----                 -------
  Normal   Scheduled    <unknown>            default-scheduler    Successfully assigned default/test-pd1 to k8s-node01
  Warning  FailedMount  106s (x6 over 2m1s)  kubelet, k8s-node01  MountVolume.SetUp failed for volume "test-volume1" : hostPath type check failed: /data is not a directory
  Normal   Pulled       77s                  kubelet, k8s-node01  Container image "wangyanglinux/myapp:v2" already present on machine
  Normal   Created      77s                  kubelet, k8s-node01  Created container test-container
  Normal   Started      77s                  kubelet, k8s-node01  Started container test-container
[root@k8s-master mnt]# kubectl get pod -o wide
NAME       READY   STATUS    RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-pd    2/2     Running   1          109m   10.244.1.49   k8s-node02   <none>           <none>
test-pd1   1/1     Running   0          3m9s   10.244.2.55   k8s-node01   <none>           <none>
[root@k8s-master mnt]# kubectl exec test-pd1 -it -- /bin/sh
/ # ls
bin       etc       lib       mnt       root      sbin      sys       tmp       var
dev       home      media     proc      run       srv       test-pd1  usr
/ # cd test-pd1
/test-pd1 # date > index.html
/test-pd1 # ls -l
total 4
-rw-r--r--    1 root     root            29 Dec 27 07:35 index.html
/test-pd1 #

在子節點查看

[root@k8s-node01 /]# mkdir /data
[root@k8s-node01 /]# cd /data
[root@k8s-node01 data]# ll
總用量 4
-rw-r--r-- 1 root root 29 12月 27 15:35 index.html
[root@k8s-node01 data]# cat index.html
Fri Dec 27 07:35:52 UTC 2019
[root@k8s-node01 data]#


免責聲明!

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



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