在預設的Docker daemon下,我們常會遇到幾種情況:
為了解決這些問題就誕生了docker volume。
如前面章節描述,每個container都是獨立且封閉的,但有時候我們會想要不透過進入container就能改變內部的程式碼,或者是想要進行database升級並保留原本資料,這時就需要docker volume了。
下面是docker volume的structure,那我們接下來講解Docker實現Volume的原理
-v or —mount
首先創建一個volume
$ docker volume create ironman-vol
啟動Container並掛載volume到指定路徑
docker run --name ironman -d -v ironman-vol:/usr/src/app/app -p 8100:8100 ghjjhg567/ironman:latest
若想查看volume
$ docker volume ls
DRIVER VOLUME NAME
local cbd2c6d11ebe4f0f112798bf0b7989d56611ba6eb02a07e95517c0147dd0b354
local ccaf125b25a2e1afe100d7147977ae5535e74e32c7c02246845ba6ae3a069c36
local iron-volume
若想查看volume詳細資訊
$ docker volume inspect iron-volume
[
{
"CreatedAt": "2020-09-12T15:35:54Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/iron-volume/_data",
"Name": "iron-volume",
"Options": {},
"Scope": "local"
}
]
若想移除volume
$ docker volume rm iron-volume
iron-volume
以下為啟動Container並Binding指定路徑的做法
$ docker run --name ironman -d -v $(pwd)/app:/usr/src/app/app -p 8100:8100 ghjjhg567/ironman:latest
1536433a700ada79a5498e081daf26058b317ea6dd8c2f2be28eb54b8c7fd8ae
Tips: 如果是windows環境,請將$(pwd)改為%cd%
再將container外部的app資料夾與內部的app資料夾進行掛載後,我們來測試修改外部程式,內部會不會同步改變。
$ vim ./app/
import json
from flask import Blueprint
from flask_headers import headers
bp = Blueprint('sync', __name__)
@bp.route('/hc', methods=['GET'])
@headers({'Content-Type': 'text/json'})
@headers({'Cache-Control': 's-maxage=0, max-age=0'})
def hc():
return_obj = {
"message": 'This endpoint for web service health check with docker volume'
}
return json.dumps(return_obj, ensure_ascii=False)
我們將return_obj中的message進行修改,接下來我們進入container內部查看
$ docker exec -it ironman bash
$ cat ./app/api/v1/health.py
import json
from flask import Blueprint
from flask_headers import headers
bp = Blueprint('sync', __name__)
@bp.route('/hc', methods=['GET'])
@headers({'Content-Type': 'text/json'})
@headers({'Cache-Control': 's-maxage=0, max-age=0'})
def hc():
return_obj = {
"message": 'This endpoint for web service health check with docker volume'
}
return json.dumps(return_obj, ensure_ascii=False)
那到這邊也就證實volume是有運作的。那接下來就來講解volume & mount
$ docker run --name ironman -d --mount type=bind,source=$(pwd)/app,target=/usr/src/app/app -p 8100:8100 ghjjhg567/ironman:latest
當使用-v在掛載路徑時,若該路徑不存在於本機,則會建立該路徑,如果將綁定到容器上的目錄不為空,那目錄現有的內容會被綁定的目錄給遮蓋
不同於volume and bind mound,tmpfs mount不需要實體路徑將資料儲存,他是暫時性地儲存在主機的記憶體當中,當Container停止時,就會移除資料,通常用來儲存暫存性資料以及敏感資料。
$ docker run --name ironman -d --mount type=tmpfs,destination=/usr/src/app/app -p 8100:8100 ghjjhg567/ironman:latest
$ docker run --name ironman -d --tmpfs /usr/src/app/app -p 8100:8100 ghjjhg567/ironman:latest
在本章節我們練習了各種使用Docker storage的方式,讀者未來能夠因應不同需求而使用不同方式去儲存資訊。
https://docs.docker.com/storage/volumes/