Docker 數據持久化的三種方案,你總能用到

容器中的數據能夠存儲在容器層。可是將數據存放在容器層存在如下問題:linux

  • 數據不是持久化。意思是若是容器刪除了,這些數據也就沒了
  • 主機上的其它進程不方便訪問這些數據
  • 對這些數據的I/O會通過存儲驅動,而後到達主機,引入了一層間接層,所以性能會有所降低

Docker 提供了3種持久化數據的方式:docker

  1. volumes:存於主機文件系統中的某個區域,由Docker管理(/var/lib/docker/volumes/ on linux)。非Docker進程不該該修改這些數據。卷是Docker中持久化數據的最好方式
  2. bind mount:存於主機文件系統中的任意位置。非Docker進程能夠修改這些數據
  3. tmpfs mount(Linux中):存於內存中(注意,並非持久化到磁盤)。在容器的生命週期中,它能被容器用來存放非持久化的狀態或敏感信息

Docker 數據持久化的三種方案,你總能用到

volumes安全

若是沒有顯式建立,一個卷會在最開始掛載時被建立。當容器中止時,卷仍然存在。多個容器能夠經過read-write或read-only的方式使用同一個卷。架構

只有在顯式刪除時,卷纔會被刪除。若是將一個空卷掛載到容器中一個存有文件或目錄的目錄中,這些文件或目錄會被拷貝到空卷中;若是將一個非空卷掛載到容器中一個存有文件或目錄的目錄中,這些文件或目錄會被隱藏。app

使用

  • 建立:docker volume create
  • 刪除某個卷:docker volume rm 卷名
  • 刪除全部未使用的卷:docker volume prune
  • 列出全部卷:docker volume ls
  • 查看某個卷的信息:docker volume inspect 卷名
  • 掛載到容器:-v或--volume。若是是Docker17.06或更高:推薦使用--mount。(同 bind mount)
  • 掛載類型:key爲type,value爲bind、volume或tmpfs
  • 掛載源:key爲source或src,對於命名卷,value爲卷名,對於匿名卷,則忽略
  • 容器中的掛載點:key爲destination、dst或target,value爲容器中的路徑
  • 讀寫類型:value爲readonly,沒有key
  • volume-opt選項,能夠出現屢次。好比volume-driver=local,volume-opt=type=nfs,…
  • 第一個域:對於命名卷,爲卷名;匿名卷,則忽略,此時會建立匿名卷
  • 第二個域:容器中的掛載點
  • 第三個域:可選參數,由','隔開,如ro
  • -v或—volume:由3個域組成,’:’分隔
  • —mount:由多個’,’隔開的鍵值對
  • =組成:
當使用docker service create 啓動Docker服務時,只支持--mount,不支持-v和--volume。而且每一個服務容器使用它們各自的本地卷,所以若是使用本地(local)卷驅動,容器沒法經過卷共享數據,可是一些卷驅動支持共享存儲。Docker for AWS和Doocker for Azure都使用Cloundstor plugin支持持久存儲

場景

  • 多個運行容器間共享數據
  • 當Docker主機不確保具備給定的目錄或文件時。卷能夠將容器運行時與Docker主機的配置解耦合
  • 備份、恢復、或將數據從一個Docker主機遷移到另外一個Docker主機時

bind mountssh

主機中的文件或目錄經過全路徑被引用。在使用綁定掛載時,這些目錄或文件不必定要已經存在。性能

若是使用這種方式將一個目錄掛載到容器中一個存有文件或目錄的目錄中,這些文件或目錄會被隱藏;若是主機中的文件或目錄不存在,當使用--mount掛載時,Docker會報錯,當使用-v或--volume時,會在主機上建立目錄ui

使用

掛載到容器:-v或—volume。若是是Docker17.06或更高:推薦使用—mount。(同 volumes)spa

  • -v或--volume:由3個域組成,':'分隔
  • 第一個域:對於命名卷,爲卷名;匿名卷,則忽略,此時會建立匿名卷
  • 第二個域:容器中的掛載點
  • 第三個域:可選參數,由','隔開,如ro
  • --mount:由多個','隔開的鍵值對<key>=<value>組成:
  • 掛載類型:key爲type,value爲bind、volume或tmpfs
  • 掛載源:key爲source或src,value爲主機中文件或目錄的路徑
  • 容器中的掛載點:key爲destination、dst或target,value爲容器中的路徑
  • 讀寫類型:value爲readonly,沒有key
  • bind-propagation選項:key爲bind-propagation,value爲rprivate、private、rshared、shared、rslave或slave
  • 一致性選項:value爲consistent、delegated、cached。這個選項僅僅適用於Docker for Mac
  • --mount不支持z和Z(這個不一樣於-v和—volume)

場景

大致上來講,只要可能,最好使用volumes
  • 主機與容器共享配置文件(Docker默認狀況下經過這種方式爲容器提供DNS解析,經過將/etc/resolv.conf掛載到容器中)
  • 共享源代碼或build artifacts(好比將Maven的target/目錄掛載到容器中,每次在Docker主機中build Maven工程時,容器可以訪問到那些rebuilt artifacts)
  • 當 docker主機中的文件或目錄結構和容器須要的一致時

bind propagation插件

對於bind mount和volumes,默認都是rprivate。只有在使用bind mount時可配置,且必須在linux下。bind propagation是個超前主題,對於大多數用戶來講,並不須要配置

對於一個掛載點/mnt,假設它同時也被掛載到/tmp。bind propagation控制 whether a mount on /tmp/a would also be available on /mnt/a

Docker 數據持久化的三種方案,你總能用到

在設置bind propagation以前,主機文件系統須要支持bind propagation

下面的例子將主機中的target/掛載到容器中2次:

Docker 數據持久化的三種方案,你總能用到

此時若是建立/app/foo/,/app2/foo也會存在

selinux label

你能添加z或Z選項來修改掛載到容器中的主機文件或目錄的selinux label:

  • z選項指明bind mount的內容在多個容器間是共享的
  • Z選項指明bind mount的內容是私有不共享的

要特別當心的使用這兩個選項。」Bind-mounting a system directory such as /home or /usr with the Z option renders your host machine inoperable and you may need to relabel the host machine files by hand」

tmpfs mount

只在linux中支持

相對於volumes和bind mount,tmpfs mount是臨時的,只在主機內存中持久化。當容器中止,tmpfs mount會被移除。對於臨時存放敏感文件頗有用

不一樣於volumes和bind mount,多個容器沒法共享tmpfs mount

使用

  • 掛載到容器:—tmpfs。若是是Docker17.06或更高:推薦使用—mount
  • 掛載類型:key爲type,value爲bind、volume或tmpfs
  • 容器中的掛載點:key爲destination、dst或target,value爲容器中的路徑
  • tmpfs-size和tmpfs-mode選項
  • —tmpfs:直接指定容器中的掛載點。不容許指定任何配置選項
  • —mount:由多個’,’隔開的鍵值對
  • =組成:

Docker 數據持久化的三種方案,你總能用到

場景

  • 最好的使用場景是你既不想將數據存於主機,又不想存於容器中時。這能夠是出於安全的考慮,或當應用須要寫大量非持久性的狀態數據時爲了保護容器的性能

volume drivers

機器間共享數據

當構建錯誤容忍應用時,可能須要配置同一個服務的多個副原本訪問相同的文件:

Docker 數據持久化的三種方案,你總能用到

有多種方法來實現這個目的:

  • 爲應用添加邏輯,將文件存儲到一個雲對象存儲系統(如Amazon S3)中
  • 使用一個支持將文件寫入外部存儲系統(如NFS或Amazon S3)的driver來建立卷

volume drivers能夠將底層存儲系統從應用邏輯中抽象出來。好比,若是你的服務使用一個具備NFS driver的卷,你能更新你的服務使用不一樣的driver,做爲在雲中存儲數據的示例,而不更改應用程序邏輯

使用

在使用docker volume create或驅動容器建立匿名卷時,能夠指定一個volume drivers。下面的例子使用vieux/sshfs做爲volume drivers

假設有2個節點,第一個節點是Docker主機,它能SSH到第二個節點

一、在Docker主機中,安裝vieux/sshfs插件

Docker 數據持久化的三種方案,你總能用到

二、使用卷驅動建立卷

1)建立命名卷

Docker 數據持久化的三種方案,你總能用到

2)啓動容器時使用卷驅動建立匿名卷

Docker 數據持久化的三種方案,你總能用到

三、備份、恢復、遷移數據卷

1)備份一個容器

Docker 數據持久化的三種方案,你總能用到

  • 啓動一個新容器,掛載dbstore容器中的卷
  • 掛載一個本地主機目錄到容器/backup
  • 使用tar將dbdata卷中的數據打包成backup.tar

2)用備份恢復容器

使用剛剛建立的備份來恢復容器:

Docker 數據持久化的三種方案,你總能用到

而後,在新建立的容器的卷中使用tar解包備份的數據:

Docker 數據持久化的三種方案,你總能用到喜歡就點個贊吧,主頁有Java架構交流圈!

相關文章
相關標籤/搜索