成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Kubernetes Storage 101: 淺談 Kubernetes 存儲(chǔ)概念,解鎖數(shù)據(jù)驅(qū)動(dòng)的力量

云計(jì)算 云原生
Container 它本質(zhì)上是無狀態(tài)的,且內(nèi)容存在的時(shí)間極為短暫。一旦容器關(guān)閉,它就會(huì)回到最初的狀態(tài)。這就意味著在容器處于活動(dòng)狀態(tài)時(shí),由應(yīng)用產(chǎn)生的數(shù)據(jù)也就丟掉了。

Kubernetes 可以說是已經(jīng)成為云原生分布式操作系統(tǒng)的事實(shí)標(biāo)準(zhǔn)了,它最大的優(yōu)勢(shì)在于可擴(kuò)展性,不論是計(jì)算、存儲(chǔ)還是網(wǎng)絡(luò),它都可以根據(jù)使用者的需求來進(jìn)行靈活擴(kuò)展。

我曾在團(tuán)隊(duì)內(nèi)部就 Kubernetes Storage 主題做過分享,內(nèi)容較為基礎(chǔ),旨在激發(fā)大家的思考。今天我將通過文稿的形式將這些分享整理出來,重新閱讀時(shí),我發(fā)現(xiàn)自己從中收獲了很多,希望對(duì)其他朋友也能有所幫助。

由于篇幅較長,我們將從 Kubernetes 存儲(chǔ)的基本概念和術(shù)語開始。

為什么說 Kubernetes 存儲(chǔ)很重要?

對(duì)于開發(fā)工程師來說,Container 想必大家都已經(jīng)不陌生了。

Container 它本質(zhì)上是無狀態(tài)的,且內(nèi)容存在的時(shí)間極為短暫。一旦容器關(guān)閉,它就會(huì)回到最初的狀態(tài)。這就意味著在容器處于活動(dòng)狀態(tài)時(shí),由應(yīng)用產(chǎn)生的數(shù)據(jù)也就丟掉了。

存儲(chǔ)可以說是支撐應(yīng)用的一個(gè)基石,數(shù)據(jù)若沒了,應(yīng)用必定無法正常工作,所以這種情況對(duì)于應(yīng)用來說肯定是不能夠被接受的。

隨著應(yīng)用逐漸往云原生轉(zhuǎn)型,讓我們來看下應(yīng)用在上 Kubernetes 平臺(tái)都會(huì)碰到哪些存儲(chǔ)問題。

1. 應(yīng)用的配置

每個(gè)應(yīng)用程序都有它自己的配置,通常的做法是將配置和代碼解耦,保持其靈活性。應(yīng)用代碼走鏡像,那么配置在 Kubernetes 里又是如何處理的呢?

2. 容器間數(shù)據(jù)通信

Pod 作為 Kubernetes 里的最小部署單元,Pod 里多個(gè)容器內(nèi)的數(shù)據(jù)共享怎么做?又或者說微服務(wù)架構(gòu)下不同節(jié)點(diǎn)上的 Pod 數(shù)據(jù)又是如何做通信的?

3. 容器內(nèi)數(shù)據(jù)持久化

Pod 是非常脆弱的,如果 Pod 掛了,做了重新調(diào)度,應(yīng)用在舊 Pod 里寫的數(shù)據(jù)還能找回嗎?

4. 集成第三方存儲(chǔ)服務(wù)

比方說我們有自己的存儲(chǔ)服務(wù),又或者說有客戶要求必須使用國產(chǎn)的某個(gè)存儲(chǔ)系統(tǒng),這個(gè)時(shí)候我們有沒有辦法可以將它們集成到 Kubernetes 的存儲(chǔ)體系里?

解決方案

為了解決以上這些問題,Kubernetes 引入了 Volume 這個(gè)抽象的概念。用戶只需通過資源和聲明式 API 來描述自己的意圖,Kubernetes 自會(huì)根據(jù)用戶的需求來完成具體的操作。

Volume 一詞它最初來源于操作系統(tǒng)的術(shù)語,在 Docker 中也有類似的概念。在 Kubernetes 世界中,Volume 是指一種可插拔的抽象層,用于在 Pod 和容器之間共享和持久化數(shù)據(jù)。

本篇文章我們將一起探討 Kubernetes 中 Volume 的概念與應(yīng)用。

Kubernetes 存儲(chǔ)體系

我們知道存儲(chǔ)技術(shù)的種類非常多,Kubernetes 為了盡可能多地兼容各種存儲(chǔ),因此它預(yù)置了很多插件,它將選擇權(quán)交到了用戶手里,讓用戶根據(jù)自己的業(yè)務(wù)需求來選擇。

kubectl explain pod.spec.volumes

這個(gè)命令將返回一個(gè)關(guān)于 Kubernetes Pod 中 Volume 定義的詳細(xì)說明,包括其字段和用法,它可以幫助用戶了解如何在 Pod 中定義一個(gè) Volume。

使用上述命令,我們可以發(fā)現(xiàn) Kubernetes 默認(rèn)支持了至少 20 多種存儲(chǔ)卷類型,這些存儲(chǔ)卷類型可以滿足各種不同的存儲(chǔ)需求。這個(gè)特性使得 Kubernetes 在存儲(chǔ)方面非常靈活,并且可以適應(yīng)各種應(yīng)用程序的存儲(chǔ)要求。

下面這張表格是根據(jù)存儲(chǔ)插件的種類,做的 2 個(gè)大類,表格里只列出了比較常用的卷類型,但還有其他類型可以在官方文檔的 Types of Persistent Volumes[1] 中找到。如果有對(duì) In-Tree Volume[2] 的實(shí)現(xiàn)感興趣的同學(xué),可以查看源代碼。

圖片圖片

那么 In-Tree 和 Out-Of-Tree 兩者有什么區(qū)別呢?我們可以從字面上先大致理解一下它們的區(qū)別,后續(xù)我會(huì)詳細(xì)介紹它們的不同之處。

可以將 In-Tree 理解為將實(shí)現(xiàn)代碼放在 Kubernetes 代碼倉庫中;而 Out-Of-Tree 則表示代碼實(shí)現(xiàn)與 Kubernetes 本身解耦,存放在 Kubernetes 代碼倉庫之外。

小結(jié)

乍一看,Kubernetes 支持的存儲(chǔ)卷類型太多了,對(duì)于不熟悉的同學(xué)可能感到無從下手。然而,總結(jié)起來其實(shí)主要有兩種類型:

  1. 非持久化的 Volume(Non-Persistent Volume or also called ephemeral storage)
  2. 持久化的 PersistentVolume

Non-Persistent Volume vs Persistent Volume

在介紹這兩種 Volume 的主要區(qū)別之前,我覺得有必要聲明一下它們的共同點(diǎn):

1. 使用方式

  • 首先都是通過在 .spec.volumes[] 里定義使用哪一種 Volume 類型
  • 然后將其掛載到容器的指定位置 .spec.containers[].volumeMounts[]

2. 宿主機(jī)目錄

不論是哪種 Volume 類型,Kubelet 都會(huì)為調(diào)度到當(dāng)前 HOST 上的 Pod, 創(chuàng)建它的 Volume 目錄,格式如下

/var/lib/kubelet/pods/<Pod-UID>/volumes/kubernetes.io~<Volume-Type>/<Volume-Name>

#1. Non-Persistent Volume

設(shè)計(jì) Non-Persistent Volume 的目的并非為了持久的保存數(shù)據(jù),它是為同一個(gè) Pod 中多個(gè) Container 之間提供可共享的存儲(chǔ)資源。

VolumeVolume

從上面的架構(gòu)圖可以看出,Volume 是包在 Pod 內(nèi)的,因此其生命周期與掛載它的 Pod 是一致的。當(dāng) Pod 因某種原因被銷毀時(shí),Volume 也會(huì)隨之刪除,但至少它的生命周期要比 Pod 中運(yùn)行的任何一個(gè)容器的存活時(shí)間長。

思考

以下是 Kubernetes 官方文檔對(duì) Pod 生命周期的描述

Pods are only scheduled once in their lifetime. Once a Pod is scheduled (assigned) to a Node, the Pod runs on that Node until it stops or is terminated.

對(duì)于配置了 restartPolicy != Never 的 Pod,即使發(fā)生異常導(dǎo)致 Pod 重啟,Pod 本身不會(huì)重新調(diào)度,因此這些 Volume 的數(shù)據(jù)其實(shí)都還在,因?yàn)?Pod 的 UID 并未發(fā)生變化,它并沒有被刪除。

?? 另外這里有必要說明一下,重啟后 Pod 背后的 Container 雖然是全新的,但是舊的 Container 仍然存在于當(dāng)前的 HOST 上,它只是處于 Exited 狀態(tài)而已,想必大家也明白我的意思了吧?這就意味著在舊 Container 處于活動(dòng)狀態(tài)時(shí),用戶在普通目錄下寫入的數(shù)據(jù),我們?nèi)匀挥袡C(jī)會(huì)可以通過容器讀寫層將數(shù)據(jù)找回。

除非被 Kubelet GC 回收機(jī)制清理掉了。

2. Persistent Volume

設(shè)計(jì) Persistent Volume 的目的是為了持久的保存數(shù)據(jù),且它能為不同節(jié)點(diǎn)上的 Pod 中多個(gè) Container 提供可共享的存儲(chǔ)資源。

Persistent VolumePersistent Volume

很明顯,從上面的架構(gòu)中看到 Persistent Volume 是獨(dú)立于 Pod 存在的,所以它的生命周期與 Pod 是無關(guān)的。

ConfigMap/Secret & EmtpyDir & HostPath

下面簡單過一下 Kubernetes 平臺(tái)經(jīng)常用到的都有哪些存儲(chǔ)卷,我們先站在使用者的角度去看這些存儲(chǔ)卷都是怎么使用的?

這三種類型我在前面的文章里也都分享過,只是沒有特意強(qiáng)調(diào)存儲(chǔ)這個(gè)概念。現(xiàn)在我將它們放在一起,或許可以讓大家更深刻理解到它們的適用場(chǎng)景。

ConfigMap/Secret 適用場(chǎng)景

ConfigMap 和 Secret 這兩個(gè)資源通常用來存儲(chǔ)應(yīng)用程序的配置,是 Kubernetes 平臺(tái)作為解耦配置和代碼的一種常用手段。

最佳實(shí)踐

圖片圖片

一份基準(zhǔn)代碼(Codebase),多份部署(deploy)

我們可以將它們當(dāng)做一個(gè)存儲(chǔ)卷來使用,下面是一個(gè)比較常見的用法,詳細(xì)內(nèi)容可以點(diǎn)擊圖片直接跳轉(zhuǎn)查看。

ConfigMap 常見用法ConfigMap 常見用法

EmtpyDir 適用場(chǎng)景

EmtpyDir 可以說是一種很常用的 Volume 了,顧名思義,它剛被創(chuàng)建出來的時(shí)候是一個(gè)空目錄,通常被用于 Pod 內(nèi)多個(gè)容器之間的數(shù)據(jù)共享。它屬于 Non-Persistent Volume,Pod 被刪除時(shí),在 EmtpyDir 內(nèi)生成的數(shù)據(jù)也一并會(huì)被清除。

最佳實(shí)踐

我們以下面這個(gè)架構(gòu)舉例,其中 Init Container 用來作數(shù)據(jù)的準(zhǔn)備容器,負(fù)責(zé)寫內(nèi)容;Application Container 作為主應(yīng)用的容器,負(fù)責(zé)數(shù)據(jù)的讀取。

該例子不僅詮釋了 Kubernetes 容器編排的魅力,同時(shí)它也是富容器的一種解決方案,具體可以點(diǎn)擊圖片查看詳細(xì)內(nèi)容 Scenario 03

容器間利用 EmtpyDir Volume 實(shí)現(xiàn)數(shù)據(jù)的通信

我們?cè)賮砜戳硗庖粋€(gè)比較常見的例子,sidecar 容器通過 EmtpyDir 來讀取另外一個(gè)容器的日志文件。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: lqshow/busybox-curl:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        i=$((i+1));
        sleep 1;
      done
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-sidecar
    image: lqshow/busybox-curl:1.28
    args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}
EOF

正如大家所見,Pod 里 count 容器的日志并未以 stdout 的方式輸出,我們?nèi)粝胗靡韵旅钇鋵?shí)是抓不到日志的。

kubectl logs -f counter -c count

但是我們可以通過一個(gè) sidecar 容器,將日志文件讀出來重新以 stdout 的方式輸出來。

當(dāng)然這種處理日志的方式肯定不是最佳的,因?yàn)樗鼤?huì)導(dǎo)致宿主機(jī)上會(huì)形成 2 份一樣的日志,其實(shí)完全沒有必要的。但是這里舉這么一個(gè)例子用來幫助理解 emptyDir 的適用場(chǎng)景,我是覺得還蠻合適的。

kubectl logs -f counter -c count-log-sidecar

HostPath 適用場(chǎng)景

HostPath 它是將宿主機(jī)節(jié)點(diǎn)上的文件系統(tǒng)上的文件或目錄,直接掛載到 Pod 中的,另外需要注意的是卷數(shù)據(jù)是持久化在宿主機(jī)節(jié)點(diǎn)的文件系統(tǒng)內(nèi)的。這種 Volume 類型其實(shí)不適合大部分的應(yīng)用,因?yàn)?Volume 里的內(nèi)容它只保留在某個(gè)特定的節(jié)點(diǎn)上,一旦 Pod 做了重新分配,調(diào)度到了其他節(jié)點(diǎn),原數(shù)據(jù)是不會(huì)被帶過來的。

所以一般情況下不建議使用 hostpath,除非你有一個(gè)非常具體的需求,并且了解你在做什么,是否 make sense?

最佳實(shí)踐

HostPath 通常和 DaemonSet 搭配使用,我們繼續(xù)以上面提到的日志收集為例,每個(gè)節(jié)點(diǎn)上會(huì)跑一個(gè) Logging agent(Fluentd),它會(huì)掛載宿主機(jī)上的容器日志目錄,來達(dá)到收集當(dāng)前主機(jī)日志的目的。

還有我們本次分享的主題之一,各種存儲(chǔ)插件的 Agent 組件(CSI),它也必須運(yùn)行在每一個(gè)節(jié)點(diǎn)上,用來在這個(gè)節(jié)點(diǎn)上掛載遠(yuǎn)程存儲(chǔ)目錄,操作容器的 Volume 目錄。

當(dāng)然它還有很多其他用法,大家自己去發(fā)現(xiàn)啦,我就不在多做介紹了。

思考

HostPath + NodeAffinity 雖然能做到偽持久化,看似有了 PV 的能力,但是我們不建議這么使用,因?yàn)檫@種方式很容易會(huì)將宿主機(jī)上的磁盤寫滿,最終會(huì)導(dǎo)致當(dāng)前節(jié)點(diǎn) NotReady。

另外出于對(duì)集群安全的考慮,我們通常都會(huì)限制 HostPath 掛載,畢竟 HostPath Volume 存在許多安全風(fēng)險(xiǎn),如果不加以限制,用戶真的有可能對(duì) Node 做任何事情。

PV,PVC & Storage Class

PV 和 PVC 是 Kubernetes 存儲(chǔ)體系里非常重要的兩個(gè)資源,它們的引入主要是為了實(shí)現(xiàn)職責(zé)分離和解耦。

這么說吧,對(duì)于應(yīng)用開發(fā)者來說,他們無需關(guān)心存儲(chǔ)設(shè)施的細(xì)節(jié),只需關(guān)注應(yīng)用對(duì)存儲(chǔ)資源的需求。

其實(shí)還有一個(gè)原因,作為開發(fā)者的我們并不知道集群里有哪些 volume 類型可用,而且存儲(chǔ)相關(guān)的配置也確實(shí)非常的復(fù)雜。存儲(chǔ)涉及的知識(shí)領(lǐng)域很專業(yè),俗話說讓專業(yè)人做專業(yè)事,可以更好的提高做事效率。

我們先來看下官方對(duì)這兩個(gè)資源的解讀吧。

名詞解釋

1. Persistent Volume (PV)

Cluster 級(jí)別的資源,它由集群管理員或者是External Provisioner組件創(chuàng)建。

它描述的是持久化存儲(chǔ)數(shù)據(jù)卷。

2. Persistent Volume Claim (PVC)

Namespace 級(jí)別的資源,它由開發(fā)者或者是StatefulSet控制器(根據(jù) VolumeClaimTemplate) 創(chuàng)建,另外通用臨時(shí)卷(Generic ephemeral volume)也會(huì)創(chuàng)建其生命周期與 Pod 一致的臨時(shí)存儲(chǔ)卷。

它描述的是 Pod 對(duì)持久化存儲(chǔ)的需求屬性,如 Volume 的容量、訪問模式等,提供了對(duì)底層存儲(chǔ)資源的抽象表述。

通過使用 PVC,可以使 Pod 跨集群移植成為可能。

3. Storage Class

Cluster 級(jí)別的資源,它由集群管理員創(chuàng)建,它定義了動(dòng)態(tài)供應(yīng)和配置 PV 的能力。Storage Class 提供了一種動(dòng)態(tài)分配 PV 的機(jī)制,根據(jù) PVC 的請(qǐng)求自動(dòng)創(chuàng)建 PV,并實(shí)現(xiàn)了存儲(chǔ)的動(dòng)態(tài)供應(yīng)和管理。

這里有必要提一下 StorageClass 中的 parameters 字段,它雖然是一個(gè)可選的字段,用于指定與存儲(chǔ)類相關(guān)的參數(shù),但是在開發(fā) CSI Driver 的時(shí)候,這個(gè)參數(shù)非常的有用,具體參見:Secrets and Credentials[3]。這些參數(shù)的具體含義取決于所使用的存儲(chǔ)插件和存儲(chǔ)供應(yīng)商。

source: docker.com

怎么理解呢?

對(duì)于剛接觸 Kubernetes 不久的同學(xué)來說,僅從名詞解釋上可能不大好理解。

一開始我也感到困惑,不知道這些資源是什么,如何使用,以及它們適用的場(chǎng)景。

沒關(guān)系,接下來我們將從不同角度對(duì)這些資源進(jìn)行解讀,希望能幫助大家建立概念。最后,我會(huì)介紹它們的具體用法。

#1. 從資源維度

以下是一個(gè)恰當(dāng)?shù)谋扔鳎m然出處未知,但我覺得很適合,所以直接引用了

PV 資源的 .Spec 中保存了存儲(chǔ)設(shè)備的詳細(xì)信息,我們可以把 PVC 想象成 Pod。

  1. Pod 消耗 Node 資源,而 PVC 消耗的是 PV 資源
  2. Pod 可以請(qǐng)求特定級(jí)別的資源(比如 CPU 和內(nèi)存),而 PVC 可以請(qǐng)求特定存儲(chǔ)卷的大小及訪問模式
  3. PVC 將應(yīng)用程序與它背后特定的存儲(chǔ)做解耦

2. 從關(guān)注點(diǎn)分離維度

應(yīng)用開發(fā)者

首先需要明確的是,對(duì)應(yīng)用開發(fā)者來說,我們只會(huì)跟 PVC 這個(gè)資源打交道,因?yàn)橹挥形覀冮_發(fā)者才知道自己的應(yīng)用大概需要多少存儲(chǔ)空間。

在 Kubernetes 中,PVC 可以被視為持久化存儲(chǔ)的抽象接口。它描述了對(duì)特定持久化存儲(chǔ)的需求和屬性,但并不負(fù)責(zé)實(shí)際的存儲(chǔ)實(shí)現(xiàn)。PV 負(fù)責(zé)實(shí)現(xiàn)具體的存儲(chǔ),并與 PVC 進(jìn)行綁定。

我們只需要明確自己的需求,即存儲(chǔ)需要的大小以及訪問模式就夠了,而不必關(guān)心存儲(chǔ)背后具體是 NFS 還是 Ceph 等實(shí)現(xiàn)方式,這并不是我們需要關(guān)心的事情。

這種分離的設(shè)計(jì)讓我們能夠?qū)W⒂趹?yīng)用開發(fā),無需關(guān)心底層存儲(chǔ)技術(shù)的選擇和實(shí)現(xiàn),從而提高我們的效率和靈活性。

運(yùn)維人員

PV 資源通常是由運(yùn)維人員來創(chuàng)建的,因?yàn)榧簝?nèi)會(huì)提供哪些存儲(chǔ),也只有集群運(yùn)維人員才知道,這個(gè)應(yīng)該比較好理解。

Provisioning

集群內(nèi)提供 PV 一般有兩種方式,下面我們來分別看下這兩種方式的優(yōu)缺點(diǎn)

1. Static Provisioning

Static Provisioning

使用流程
  1. 首先由集群管理員基于一些底層網(wǎng)絡(luò)存儲(chǔ)資源創(chuàng)建一個(gè)靜態(tài)持久化卷
  2. 然后用戶創(chuàng)建一個(gè) PVC 聲明,用來申請(qǐng)第一步的特定持久化卷
  3. 最后創(chuàng)建一個(gè) Pod 并同時(shí)使用這個(gè) PVC
思考

這種方式好處是非常明顯的,可以說集群內(nèi)所有的存儲(chǔ)資源都在運(yùn)維的掌控中。

但是,供給靜態(tài) PV 這種流程,PV 資源必須是由運(yùn)維人員參與創(chuàng)建的,它也帶來一些問題:

  1. 小規(guī)模的集群還好,如果在大規(guī)模的生產(chǎn)環(huán)境下,用戶應(yīng)用的實(shí)例是不可控的,可能需要成千上萬個(gè) PV,無法預(yù)測(cè)。這種手動(dòng)且重復(fù)的工作,效率不僅低下,且這種操作對(duì)管理員也是一種痛苦。
  2. 另外這種方式也很容易導(dǎo)致存儲(chǔ)使用效率低下
  • 要么配置少了,限制程序的運(yùn)行
  • 要么過度配置了,導(dǎo)致存儲(chǔ)的浪費(fèi)

那么如何實(shí)現(xiàn)自動(dòng)化呢?這就得依賴 Storage Class 這個(gè)概念了,它引入了動(dòng)態(tài)存儲(chǔ)配置的流程。

2. Dynamic Provisioning

Dynamic Provisioning

使用流程

從上面的流程圖來看,很明顯整個(gè)流程少了管理員的介入。

  1. 用戶創(chuàng)建一個(gè) PVC 的時(shí)候,由對(duì)應(yīng)的 Provision 自動(dòng)創(chuàng)建一個(gè) PV 與它進(jìn)行一一綁定。怎么對(duì)應(yīng)呢?就是通過 storageClassName 來尋找。
  2. 創(chuàng)建一個(gè) Pod 并同時(shí)使用這個(gè) PVC,這個(gè)流程兩者都是一致的。
思考

自動(dòng)創(chuàng)建 PV 這種模式,它可以說是完全改變了部署的工作方式。

它其實(shí)不僅僅是解放了運(yùn)維人員這么簡單,對(duì) DevOps 的推進(jìn)也提供了很大的幫助。

PV 和 PVC 綁定條件

?? StorageClass: PV 和 PVC 必須屬于相同的 StorageClass。?? 訪問模式(Access Modes): PV 和 PVC 的訪問模式必須兼容,訪問模式定義了 Pod 如何訪問存儲(chǔ)卷。?? 容量(Capacity):PVC 的請(qǐng)求容量不能超過 PV 的容量。PVC 可以請(qǐng)求一個(gè)特定大小的存儲(chǔ)卷,而 PV 必須具備足夠的容量來滿足 PVC 的請(qǐng)求。?? Selector(選擇器): PV 可以定義一個(gè)或多個(gè) Label Selector,而 PVC 可以通過 Label Selector 來選擇匹配的 PV。PVC 的 Selector 必須匹配 PV 的 Label Selector 才能進(jìn)行綁定。

當(dāng)滿足這些綁定條件時(shí),Kubernetes 將會(huì)自動(dòng)將 PVC 綁定到相應(yīng)的 PV 上,從而實(shí)現(xiàn)持久化存儲(chǔ)的分配和使用。

思考

在 Kubernetes 中,PV 與 PVC 是一對(duì)一的關(guān)系,一個(gè) PV 只能綁定一個(gè) PVC。然而,多個(gè) Pod 可以共享同一個(gè) PVC,從而使用該 PVC 提供的持久化存儲(chǔ)。事實(shí)上,我們?cè)谏a(chǎn)環(huán)境并不會(huì)直接使用 Pod,因?yàn)樗鼤?huì)因?yàn)楦鞣N原因被關(guān)閉而不再提供服務(wù),比如被節(jié)點(diǎn)驅(qū)逐。

一般情況下我們使用 Deployment, 它可以管理多個(gè)副本(replicas)的 Pod,在以下場(chǎng)景中,我們有 3 個(gè) Pod 副本,它們掛載同一個(gè) PVC,如果該 PVC 只有只讀權(quán)限的話,那么不會(huì)出現(xiàn)任何問題。

DeploymentDeployment

但是,如果該 PVC 具有讀寫權(quán)限,然后又被 3 個(gè) Pod 副本共享,這可能會(huì)導(dǎo)致數(shù)據(jù)不一致的問題。好比說會(huì)碰到 Race Condition:如果兩個(gè)或更多的 Pod 同時(shí)寫入相同的文件,可能會(huì)發(fā)生數(shù)據(jù)覆蓋或者數(shù)據(jù)不一致的情況。

那么有什么辦法可以解決這個(gè)問題呢?那就是 StatefulSet 工作負(fù)載,它也有多副本的概念。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  ...
  replicas: 3
  template:
    ...
  volumeClaimTemplates: # 定義創(chuàng)建與該 StatefulSet 相關(guān)的 PVC 的模板
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

不同之處我們可以通過定義 volumeClaimTemplates,以便自動(dòng)為每個(gè)副本創(chuàng)建一個(gè)新的 PVC,如下圖所示

StatefulSetStatefulSet

當(dāng)然,實(shí)際場(chǎng)景往往會(huì)更加的復(fù)雜,尤其是分布式應(yīng)用,如主從關(guān)系需要考慮 StatefulSet 提供的 Pod 標(biāo)識(shí)與順序等特性。

我們?cè)賮砜匆幌?PVC 最后一種創(chuàng)建方式:它就是通用臨時(shí)卷(Generic ephemeral volume)。

需要注意的是,Generic Ephemeral Volume 中的數(shù)據(jù)只會(huì)在容器的生命周期內(nèi)保留,當(dāng) Pod 被刪除或重啟時(shí),一并生產(chǎn)的 PVC 同時(shí)也被刪除。因此,Generic Ephemeral Volume 適用于需要在容器生命周期內(nèi)保留一些臨時(shí)數(shù)據(jù)的場(chǎng)景,例如緩存文件或臨時(shí)配置文件。

kind: Pod
apiVersion: v1
metadata:
  name: my-app
spec:
  containers:
    - name: my-frontend
      volumeMounts:
      - mountPath: "/scratch"
        name: scratch-volume
      ...
  volumes:
    - name: scratch-volume
      ephemeral:
        volumeClaimTemplate:
          metadata:
            labels:
              type: my-frontend-volume
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "scratch-storage-class"
            resources:
              requests:
                storage: 1Gi

Default Storage Class

管理員可以將集群內(nèi)的某個(gè)存儲(chǔ)類打上 annotation,作為 Default Storage Class,它是預(yù)定義的一種特殊存儲(chǔ)類,用于指定在未顯式指定存儲(chǔ)類的情況下所使用的默認(rèn)存儲(chǔ)類。

kubectl patch storageclass <STORAGE-CLASS-NAME> -p \
'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

Container Storage Interface

盡管 Kubernetes 平臺(tái)本身支持多種存儲(chǔ)插件,但由于用戶需求不斷增長,這些插件往往無法滿足所有要求。比方說,當(dāng)客戶要求我們的 PaaS 平臺(tái)必須與國產(chǎn)某個(gè)存儲(chǔ)集成時(shí),我們?cè)撊绾螒?yīng)對(duì)?

此外,這些存儲(chǔ)插件基本上是 In-tree的,如果插件需要做 patch,當(dāng)前的模式會(huì)給測(cè)試和維護(hù)帶來不便。

這時(shí)就不得不提到容器存儲(chǔ)接口(CSI),它本質(zhì)上只是定義了一套協(xié)議標(biāo)準(zhǔn),第三方存儲(chǔ)插件只要實(shí)現(xiàn)這些統(tǒng)一的接口,就能對(duì)接 Kubernetes,用戶無需接觸核心的 Kubernetes 代碼。

適配工作由容器編排系統(tǒng)(如 Kubernetes)和存儲(chǔ)提供商(SP)共同完成,CO 通過 gRPC 與 CSI 插件進(jìn)行通信。

圖片圖片

CSI 其實(shí)蠻復(fù)雜的,涉及到的組件相當(dāng)多,后面我會(huì)專門寫一篇文章介紹 CSI 的工作原理以及遇到的挑戰(zhàn)。

寫在最后

通過對(duì)這些基本概念的理解,我們能夠在 Kubernetes 中正確配置和管理存儲(chǔ)資源,滿足應(yīng)用程序?qū)Τ志没鎯?chǔ)的需求。

參考資料

[1]Types of Persistent Volumes: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

[2]In-Tree Volume: https://github.com/kubernetes/kubernetes/tree/master/pkg/volume

[3]Secrets and Credentials: https://kubernetes-csi.github.io/docs/secrets-and-credentials.html

責(zé)任編輯:武曉燕 來源: Cloud Native 101
相關(guān)推薦

2022-11-29 08:05:48

KubernetesPVCSI

2018-11-21 10:36:29

Kubernetes存儲(chǔ)Docker

2023-12-18 08:23:12

CSI插件Kubernetes

2024-09-29 13:53:58

數(shù)據(jù)飛輪數(shù)據(jù)中臺(tái)數(shù)字化轉(zhuǎn)型

2021-04-14 09:33:58

Kubernetes通信網(wǎng)絡(luò)模型

2023-04-28 08:11:46

Kubernetes容器

2021-02-19 08:38:36

Kubernetes容器化分布式

2024-09-29 18:49:39

2021-01-12 14:46:34

Kubernetes開發(fā)存儲(chǔ)

2021-04-13 05:38:35

Kubernetes存儲(chǔ)數(shù)據(jù)庫

2024-02-22 15:35:05

2019-01-15 17:50:18

存儲(chǔ)技術(shù)容器

2021-11-22 14:54:36

Kubernetes存儲(chǔ)

2018-06-21 15:14:51

Kubernetes存儲(chǔ)容器

2018-07-19 10:56:16

Kubernetes存儲(chǔ)架構(gòu)

2023-11-20 20:45:38

2022-01-27 13:47:10

Kubernete命令Linux

2024-09-29 18:31:16

解鎖數(shù)據(jù)在線教育飛輪效應(yīng)

2025-04-29 10:00:00

Kubernete云原生Helm

2019-05-14 14:27:36

KubernetesDocker存儲(chǔ)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产亚洲精品精品国产亚洲综合 | 亚洲视频一区在线 | 在线观看 亚洲 | 精品自拍视频在线观看 | 成人福利视频 | 天天夜夜人人 | 成人av一区 | 国产中文字幕在线 | 日韩一区二区福利视频 | 91免费在线视频 | 国产成人99久久亚洲综合精品 | 欧美精品一区在线 | 日韩欧美三区 | 成人精品在线观看 | 日韩久久精品电影 | 国产精品一区二区久久 | 国内精品视频一区二区三区 | 久久久久国产精品一区 | 成人欧美一区二区三区黑人孕妇 | 久久免费精品 | 国产特级毛片aaaaaa喷潮 | a级在线 | 成人精品福利 | 天堂久久av | 怡红院免费的全部视频 | 国产成人高清 | 欧美午夜在线 | 国产清纯白嫩初高生在线播放视频 | 激情综合五月 | 无码日韩精品一区二区免费 | 激情一区二区三区 | 久久久久久久久久一区 | 日韩一 | 免费国产一区二区 | 亚洲午夜av久久乱码 | 精品一区av | 男人的天堂久久 | 99re99| 成人精品免费视频 | 91精品国产乱码久久久久久久久 | 亚洲在线视频 |