天天看點

Kubernetes(9)資料管理Kubernetes(9)資料管理

文章目錄

  • Kubernetes(9)資料管理
    • Volume
      • emptyDir

Kubernetes(9)資料管理

volume

首先我們會學習Volume,以及Kubernetes如何通過Volume為叢集中的容器提供存儲;然後我們會實踐幾種常用的Volume類型并了解它們各自的應用場景;最後,我們會讨論Kubernetes如何通過Persistent Volume和Persistent Volume Claim分離叢集管理者與叢集使用者的職責,并實踐Volume的靜态供給和動态供給
Kubernetes(9)資料管理Kubernetes(9)資料管理

Volume

Kubernetes 卷具有明确的生命周期——與包裹它的 Pod 相同。 是以,卷比 Pod 中運作的任何容器的存活期都長,在容器重新啟動時資料也會得到保留。 當然,當一個 Pod 不再存在時,卷也将不再存在。也許更重要的是,Kubernetes 可以支援許多類型的卷,Pod 也能同時使用任意數量的卷。

卷的核心是包含一些資料的目錄,Pod 中的容器可以通路該目錄。 特定的卷類型可以決定這個目錄如何形成的,并能決定它支援何種媒體,以及目錄中存放什麼内容。

使用卷時, Pod 聲明中需要提供卷的類型 (.spec.volumes 字段)和卷挂載的位置 (.spec.containers.volumeMounts 字段).

容器中的程序能看到由它們的 Docker 鏡像和卷組成的檔案系統視圖。 Docker 鏡像 位于檔案系統層次結構的根部,并且任何 Volume 都挂載在鏡像内的指定路徑上。 卷不能挂載到其他卷,也不能與其他卷有硬連結。 Pod 中的每個容器必須獨立地指定每個卷的挂載位置。

Kubernetes的存儲模型Volume,學習如何将各種持久化存儲映射到容器。

我們經常會說:容器和Pod是短暫的。其含義是它們的生命周期可能很短,會被頻繁地銷毀和建立。容器銷毀時,儲存在容器内部檔案系統中的資料都會被清除。

為了持久化儲存容器的資料,可以使用Kubernetes Volume.

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

本質上,Kubernetes Volume是一個目錄,這一點與Docker Volume類似。當Volume被mount到Pod,Pod中的所有容器都可以通路這個Volume.

Volume也支援多種backend類型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph等

Volume提供了對各種backend的抽象,容器在使用Volume讀寫資料的時候不需要關心資料到底是存放在本地節點的檔案系統中還是雲硬碟上。對它來說,所有類型的Volume都隻是一個目錄。
Pod中的所有容器都可以共享Volume,它們可以指定各自的mount路徑。

emptyDir

我們将從最簡單的emptyDir開始學習Kubernetes Volume

emptyDir是最基礎的Volume類型。正如其名字所示,一個emptyDir Volume是Host上的一個空目錄

Volume對于容器來說是持久的,對于Pod則不是。當Pod從節點删除時,Volume的内容也會被删除。但如果隻是容器被銷

毀而Pod還在,則Volume不受影響。

也就是說:emptyDir Volume的生命周期與Pod一緻

emptyDir 的一些用途:

緩存空間,例如基于磁盤的歸并排序。

為耗時較長的計算任務提供檢查點,以便 任務能方便 地從崩潰前狀态恢複執行。

在 Web 伺服器容器服務資料時,儲存内容管理器容器擷取的檔案。

預設情況下, emptyDir 卷存儲在支援該節點所使用的媒體上;這里的媒體可以是磁盤或 SSD 或網絡存儲,這取決于您的環境。 但是,您可以将 emptyDir.medium 字段設定為 “Memory”,以告訴 Kubernetes 為您安裝 tmpfs(基于 RAM 的檔案系統)。 雖然 tmpfs 速度非常快,但是要注意它與磁盤不同。 tmpfs 在節點重新開機時會被清除,并且您所寫入的所有檔案都會計入容器的記憶體消耗,受容器記憶體限制限制。
下面通過例子來實踐emptyDir
[[email protected] ~]$ cat emptyDir.yml 
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 world" > /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
    emptyDir: {}


這裡我們模拟了一個producer-consumer場景。Pod有兩個容器
producer和consumer,它們共享一個Volume。producer負責往Volume中寫資料,consumer則是從Volume讀取資料

1.檔案最底部volumes定義了一個emptyDir類型的Volume shared-volume
2.producer容器将shared-volume mount到/producer_dir目錄
3.producer通過echo将資料寫到檔案hello裡
4.consumer容器将shared-volume mount到/consumer_dir目錄
5.consumer通過cat從檔案hello讀資料

[[email protected] ~]$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
producer-consumer   2/2     Running   0          76s
[[email protected] ~]$ kubectl logs producer-consumer consumer 
hello world

[[email protected] shared-volume]# docker ps -a
1a7d3-b35f-452c-90c1-52adf2e5f532_3
f293c268929e        busybox                "/bin/sh -c 'cat /co…"    8 minutes ago       Up 8 minutes                                       k8s_consumer_producer-consumer_default_f42e8fc1-59d8-4359-9b6a-65b95b06c762_0
8de1260fdd5a        busybox                "/bin/sh -c 'echo \"h…"   8 minutes ago       Up 8 minutes                                       k8s_producer_producer-consumer_default_f42e8fc1-59

[[email protected] shared-volume]# docker inspect 8de1260fdd5a | grep Source
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~empty-dir/shared-volume",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~secret/default-token-jvzv6",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/etc-hosts",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/containers/producer/6376847f",
[[email protected] shared-volume]# docker inspect f293c268929e | grep Source
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~empty-dir/shared-volume",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~secret/default-token-jvzv6",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/etc-hosts",
                "Source": "/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/containers/consumer/76141b24",

因為emptyDir是Docker Host檔案系統裡的目錄,其效果相當于執
行了docker run -v/producer_dir和docker run -v /consumer_dir。通過docker inspect檢視容器的詳細配置資訊,我們發現兩個容器都mount了同一個目錄

#這裡/var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~empty-dir/shared-volume 就是emptyDir在Host上的真正路徑
[[email protected] default-token-jvzv6]# cd /var/lib/kubelet/pods/f42e8fc1-59d8-4359-9b6a-65b95b06c762/volumes/kubernetes.io~empty-dir/shared-volume
[[email protected] shared-volume]# ls
hello
[[email protected] shared-volume]# cat hello 
hello world

"""
emptyDir是Host上建立的臨時目錄,其優點是能夠友善地為Pod
中的容器提供共享存儲,不需要額外的配置。它不具備持久性,如果
Pod不存在了,emptyDir也就沒有了。根據這個特性,emptyDir特别
适合Pod中的容器需要臨時共享存儲空間的場景
"""

           

繼續閱讀