1. 程式人生 > >從零開始學習docker(九)持久化儲存和資料共享

從零開始學習docker(九)持久化儲存和資料共享

有些時候容器會產生一些資料,而我們不希望這些資料隨著容器的刪除而刪除。想保證資料的安全,一般用在資料庫。

首先看一下container和image的區別:

container容器是在image之上建立的,container layer可以讀寫資料,而image是隻讀的,而我們在container中謝的資料僅限於在當前container中讀寫,如果把container停止和刪除,那麼之前寫的檔案和資料都刪除了,所以container是臨時儲存和儲存資料的。

如果有這樣的需求:如果我們建立一個mysql資料庫的container,資料都是以檔案的形式儲存在本地的,如果把mysql容器刪除,那麼資料就被刪除了,這是不可取的。

docker引入了一個持久化的機制。

 

預設情況下會將資料寫入到Container Layer,但是我們可以通過持久化將資料儲存到Volume。即使容器被刪除了,那麼只要Volume還在,我們資料就還在,被儲存了下來。

Docker持久化資料方案:

  • 基於本地檔案系統的Volume。可以在執行Docker create 或Docker run時,通過-v引數將主機的目錄作為容器的資料卷。這部分功能便是基於本地檔案系統的volume管理。
  • 基於plugin的volume。支援第三方的存出方案,比如NAS,aws

 Volume的型別:

  • 受管理的data volume,由docker後臺自動建立。
  • 繫結掛在的Volume,具體掛在位置可以由使用者指定。

準備環境

建立一個mysql的container,

iie4bu@hostdocker:~$ docker run -d --name mysql-1 -e MYSQL_ALLOW_EMPTY_PASSWORD mysql 
886583d9191dd8df6deed609f31e9e15ed854f83a85b4b47c335b04a441b55b3
iie4bu@hostdocker:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

-e MYSQL_ALLOW_EMPTY_PASSWORD表示使用空密碼

查詢映象發現沒有執行

檢視日誌:docker logs mysql-1

iie4bu@hostdocker:~$ docker logs mysql-1
error: database is uninitialized and password option is not specified 
  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

把這個映象刪除,重新建立。

先看一下我們本地是否有volume?

iie4bu@hostdocker:~$ docker volume ls
DRIVER              VOLUME NAME
local               01d091f0bc6a045d10d56b5892dc55ccb2c6cda6b19cbcc8ca3c7adc9b3c477b
local               0e4b3a8c4be019d86c855a773865e5472dbc0629a7b542d44fe5d132be07ee87

發現有很多,都是之前建立的。可以先刪除掉:

docker volume rm 01d091f0bc6a045d10d56b5892dc55ccb2c6cda6b19cbcc8ca3c7adc9b3c477b

小技巧:

    可以刪除所有的volume:

docker volume rm $(docker volume ls -q)

重新建立mysql映象:

 iie4bu@hostdocker:~$ docker run -d --name mysql-1 -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql 
48ea258e299a6c74f0762e2bd5ff580422160d02ab600d26aec716ca983fc90e
iie4bu@hostdocker:~$
iie4bu@hostdocker:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
48ea258e299a        mysql               "docker-entrypoint.s…"   37 seconds ago      Up 36 seconds       3306/tcp, 33060/tcp   mysql-1
iie4bu@hostdocker:~$ 

現在可以看到mysql已經運行了,檢視volume:

iie4bu@hostdocker:~$ docker volume ls
DRIVER              VOLUME NAME
local               575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d
iie4bu@hostdocker:~$

這個就是mysql的volume

檢視volume詳細資訊:

iie4bu@hostdocker:~$ docker volume inspect 575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d
[
    {
        "CreatedAt": "2019-07-01T14:33:51+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d/_data",
        "Name": "575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d",
        "Options": {},
        "Scope": "local"
    }
]

發現volume的資料是在/var/lib/docker/volumes/575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d/_data路徑下。

我們再建立一個mysql:

iie4bu@hostdocker:~$ docker run -d --name mysql-2 -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql 
200afb2c335e45bd76ad9b3b8d97f29a23972702ae2c4f82be9ebde1d619b644
iie4bu@hostdocker:~$ docker volume ls
DRIVER              VOLUME NAME
local               54bbb749bc0b45dfa1de4eff8b94620e3184ade9633ffdeaeef230dbcd20c0cc
local               575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d

檢視這個新的volume:

iie4bu@hostdocker:~$ docker volume inspect 54bbb749bc0b45dfa1de4eff8b94620e3184ade9633ffdeaeef230dbcd20c0cc
[
    {
        "CreatedAt": "2019-07-01T14:50:46+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/54bbb749bc0b45dfa1de4eff8b94620e3184ade9633ffdeaeef230dbcd20c0cc/_data",
        "Name": "54bbb749bc0b45dfa1de4eff8b94620e3184ade9633ffdeaeef230dbcd20c0cc",
        "Options": {},
        "Scope": "local"
    }
]

實驗:如果將容器停止,是否volume是否還在:

先將mysql-1和mysql-2停止:

iie4bu@hostdocker:~$ docker container stop mysql-1 mysql-2
mysql-1
mysql-2

然後將mysql-1和mysql-2刪除:

iie4bu@hostdocker:~$ docker container rm mysql-1 mysql-2
mysql-1
mysql-2

確認我們本地沒有容器在執行:

iie4bu@hostdocker:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
iie4bu@hostdocker:~$

但是volume還在:

iie4bu@hostdocker:~$ docker volume ls
DRIVER              VOLUME NAME
local               54bbb749bc0b45dfa1de4eff8b94620e3184ade9633ffdeaeef230dbcd20c0cc
local               575c4038694e1abf8e883fc029813a745de6e5f412412eebec7c1a5b9c46e35d
iie4bu@hostdocker:~$ 

給volume起別名

先將上面的兩個volume刪除