Kubernets volume

原文: https://kubernetes.io/docs/concepts/storage/volumes/

容器中的文件是短暫存在的,這會導(dǎo)致一定的問題。首先,當(dāng)容器掛掉之后,kubelete會重啟他,但是文件會丟失掉;其次,在一個pod中運行的各個容器經(jīng)常需要共享文件。kubernetes的volume就是用來解決這些問題的。

背景


docker也有volume的概念,但是有點松散和缺乏管理。在Docker里,一個volume簡單來說就是磁盤上或者另外一個容器中的目錄,沒有生命周期管理,而且直到最近也只支持本地磁盤的volume。Docker能支持volume driver,但是實用性很受限(docker 1.7 每個容器只支持一種volume driver,而且不能給volume傳遞參數(shù))。

一個kubernetes的volume,有非常明確的跟Pod一樣的生命周期。因此,一個volume比同一個pod中的所有容器都活得長,而且數(shù)據(jù)是不受容器重啟影響的。當(dāng)然,pod沒了,volume也就沒了??赡鼙冗@更重要的是,kubernetes支持多種類型的volumes,而且一個pod可以同時使用多種voluems。

本質(zhì)上來說,一個vlomue就是一個目錄,可能在里面放了一些數(shù)據(jù),這個目錄可以被pod里的容器訪問。致于這個目錄哪兒來的,他背后是什么設(shè)備,他的內(nèi)容是啥,這就要看具體是哪種類型的volume了。
要使用一個volume,需要pod聲明提供什么volume(使用spec.volumes字段) 和掛載到哪些容器中 (使用spec.containers.volumeMounts字段).
容器里的進程看到的文件系統(tǒng),是由docker鏡像和volumes組合起來的。Docker鏡像是文件系統(tǒng)的root,而其他volumes都是掛載在某個具體的目錄上。volumes不能掛載到其他volumes中,也不能有指向其他volume的hard link. Pod中的每個容器必須單獨制定掛載那個volume。

TL;DR:

k8s的volume就是好就是好就是好.

Volume類型


kubernets支持這些volume類型:

  • emptyDir
  • hostPath
  • gcePresistentDisk
  • awsElasticBlockStore
  • nfs
  • iscsi
  • flocker
  • glusterfs
  • rbd
  • cephfs
  • gitRepo
  • secret
  • persistentVolumeClaim
  • downwardAPI
  • azureFileVolume
  • azureDisk
  • vsphereVolume
  • Quobyte
  • PortworxVolume
  • ScaleIO
    歡迎你們貢獻其他的類型。

emptyDir

emptyDir volume是在Pod被分配到一個Node上之后,最先創(chuàng)建出來的,而且一只存在到Pod不在這個node上了為止。 看名字就看得出來,他是一個空目錄。該pod中的容器都可以在emptyDir volume中讀寫到相同的文件,盡管這個volume可能被掛載在不同容器的不同目錄。 當(dāng)一個Pod不管什么原因被從所在的Node上移除了,emptyDir里的數(shù)據(jù)也就被永久刪除了。 NOTE: 如果僅僅是容器掛掉了,不會導(dǎo)致pod被從node上移除,所以enmptyDir中的數(shù)據(jù)還是安全的。

一些常見的用途:

  • scratch space, such as for a disk-based merge sort
  • 長時間計算的檢查點用來從crash中恢復(fù)
  • holding files that a content-manager container fetches while a webserver container serves the data

默認(rèn)來說,emptyDir volume存儲在哪兒是看你的機器的,可能是普通磁盤,可能是SSD,也可能是網(wǎng)絡(luò)存儲,主要看你的環(huán)境。但是,你也可以通過把 emptryDir.medium 的值改成 “Memory”, 這樣kubernets就會給你掛個tmpfs (基于RAM的文件系統(tǒng))。雖然tmpfs很快,但是不像磁盤,當(dāng)機器重啟之后,就沒了,而且你消耗的空間還要算在容器的內(nèi)存限制里。

Example Pod

apiVersion: v1 
kind: Pod 
metadata:   
  name: test-pd 
spec:   
  containers:   
  - image: gcr.io/google_containers/test-webserver     
    name: test-container     
    volumeMounts:     
    - mountPath: /cache      
      name: cache-volume   
  volumes:   
  - name: cache-volume
    emptyDir: {}

hostPath

hostPath volume 掛載一個宿主機上的目錄到你的Pod里。 這可能不是大多是Pod需要用到的,但是他為某些應(yīng)用提供了一個途徑。
舉個例子,可以這么用:

  • 運行一個容器可能要訪問docker內(nèi)部的什么東西,可以把/var/lib/docker掛進去
  • 在一個容器里運行cAdvisor, 把/dev/cgroups掛進去

注意點:
相同配置的pod(必須用podTemplate創(chuàng)建出來的)可能在不同node上的行為不一樣,因為不同node上的同一目錄上中文件內(nèi)容不一樣。當(dāng)kubernetes在做調(diào)度的時候,如果需要考慮資源情況的話,是管不到hostPath里使用的資源的宿主機上的root用戶創(chuàng)建的目錄只能被root用戶操作。你可能需要在容器里也用root用戶運行,或者在宿主機上修改對應(yīng)目錄的權(quán)限。

ExamplePod

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
    -image: [gcr.io/google_containers/test-webserver](http://gcr.io/google_containers/test-webserver)
     name: test-container
     volumeMounts:
        -mountPath: /test-pd
         name: test-volume
   volumes:
      -name: test-volume
       hostPath: # directory location on host
       path: /data

gcePersistentDisk

gcePersistentDisk volume掛載一個Goole Compute Engine(GCE)的 PersistentDisk 到你的pod中。
反正用不到,先不管了。

awsElasticBlockStore

反正也用不到,先不管了

nfs

nfs volume允許一個NFS掛載到你的pods里。不像emptyDir一樣會在Pod移除時被擦除掉,nfs volume的內(nèi)容是受保護的,不會被干掉,只是被unmount掉而已。這就是說,一個NFS volume可以預(yù)填充數(shù)據(jù),而且這些數(shù)據(jù)可以在不同pod之間使用。NFS可以同時被多個writer掛載。
有點意思,看個例子:
https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/nfs

iscsi, flocker,glusterfs,rbd,cephfs都用不到,先不管了

gitRepo

gitRepo volume是一個用來展示volume插件能力的例子.他會掛載一個空目錄,并且clone一個git庫進來供pod使用。在不遠的將來,這樣的volume們可能會改成更解耦的模型,而不是擴展kubernets的API。

來看個例子:

apiVersion: v1
kind: Pod
metadata:
  name: server
spec:
    containers:
      -image: nginxname:nginx
        volumeMounts:
          -mountPath: /mypath
          name: git-volume
    volumes:
        -name: git-volume
         gitRepo:
            repository: "git@somewhere:me/my-git-repository.git"
            revision: "22f1d8406d464b0c0874075539c1f2e96c253775"

secret

secret volume是用來給pod傳遞敏感信息的,比如密碼。你可以用kubernets API存儲秘密信息,然后他們當(dāng)成文件掛載到需要使用他們的Pod中,這樣就可以避免直接跟kubernets發(fā)生聯(lián)系。secret volumes是基于tmpfs的,所以它們永遠不會被寫到持久化存儲上。

提示: 你需要在使用之前先通過kubernets API創(chuàng)建一個secret

persistentVolumeClaim

persistentVolumeClaim volume是用來掛載一個PersitentVolume到pod中的。PersistentVolume是一種讓用戶在不需要關(guān)心具體細(xì)節(jié)的情況下申請耐用存儲(比如GCE PersistentDisk, 或者 ISCSI volume)的方式。

downwardAPi, FlexVolume, AzureFileVolume, AzureDiskVolum, vsphereVolume, Quobyte, PortworxVolume, ScaleIO 先不管了

使用子路徑


有些時候,在一個pod中的一個volume可能有多種用途。volumeMounts.subPath 屬性可以用來指定一個volume的子路徑而不是他的根目錄。
來看個例子, 這個例子是一個運行LAMP的pod,使用了一個共享的volume. html內(nèi)容映射到他的html目錄,數(shù)據(jù)庫映射到mysql目錄。請看:

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容