生產(chǎn)環(huán)境中使用docker的過程中,往往需要對數(shù)據(jù)進行持久化,或者需要在多個容器之間進行數(shù)據(jù)共享菇篡,這必然涉及容器的數(shù)據(jù)管理操作。
容器中管理數(shù)據(jù)主要有兩種方式:
- 數(shù)據(jù)卷(Data Volumes): 容器內數(shù)據(jù)直接映射到本地主機環(huán)境一喘;
- 數(shù)據(jù)卷容器(Data Volume Containers): 使用特定容器維護數(shù)據(jù)卷驱还。
本篇文章首先介紹如何在容器內創(chuàng)建數(shù)據(jù)卷,并且把本地的目錄或文件掛載到容器內的數(shù)據(jù)卷中凸克。接下來议蟆,會介紹如何使用數(shù)據(jù)卷容器在容器和主機、容器和容器之間共享數(shù)據(jù)萎战,并實現(xiàn)數(shù)據(jù)的備份和恢復咐容。
6.1 數(shù)據(jù)卷
數(shù)據(jù)卷是一個可供容器使用的特殊目錄,它將主機操作系統(tǒng)目錄直接映射進容器撞鹉,類似Linux中的mount操作疟丙。
數(shù)據(jù)卷可以提供很多有用的特性颖侄,如下所示:
- 數(shù)據(jù)卷可以在容器之間共享和重用鸟雏,容器之間傳遞數(shù)據(jù)將變得高效方便享郊;
- 對數(shù)據(jù)卷內數(shù)據(jù)的修改會立馬生效,無論是容器內操作還是本地操作;
- 對數(shù)據(jù)卷的更新不會影響鏡像孝鹊,解耦了應用和數(shù)據(jù)炊琉;
- 卷會一直存在,知道沒有容器使用又活,可以安全的卸載它苔咪。
1.在容器內創(chuàng)建一個數(shù)據(jù)卷
在用docker run
命令的時候,使用-v
標記可以在容器內創(chuàng)建一個數(shù)據(jù)卷柳骄。多次重復-v
標記可以創(chuàng)建多個數(shù)據(jù)卷团赏。
下面 使用webserver
鏡像創(chuàng)建一個web容器,并創(chuàng)建一個數(shù)據(jù)卷掛載到容器的/webapp
目錄耐薯。
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v0.21 e230d26d7671 2 hours ago 967.9 MB
centos6.8 0.21 7e48bfa0489e 30 hours ago 1.052 GB
[root@private_vpn ~]# docker run -itd -p 80:80 --name web -v /tmp/webapp:/webapp webserver:v0.21 /bin/bash
71cf8102d33c8e2a5ddfb69ed28bf8743ee4c1dbc27c9c6fd0a69c1d97b74d58
[root@private_vpn ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
71cf8102d33c webserver:v0.21 "/bin/bash" 4 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp web
[root@private_vpn ~]#
[root@private_vpn ~]# ls -l /tmp/webapp/
total 0
[root@private_vpn ~]# docker exec -ti 71 /bin/bash
[root@71cf8102d33c /]# ls -l /webapp
total 0
[root@71cf8102d33c /]# cat /tmp/test.txt #容器講解那篇文章創(chuàng)建的測試文件
test
命令:docker run -itd -p 80:80 --name web -v /tmp/webapp:/webapp webserver:v0.21 /bin/bash
使用-v
標記指定掛載一個本地的已有目錄到容器中去作為數(shù)據(jù)卷(推薦方式)
上面的命令加載主機的/tmp/webapp目錄到容器的/webapp目錄舔清。
注意:本地路徑必須是絕對路徑且存在,如果目錄不存在docker容器曲初,則會自動創(chuàng)建体谒。
-p: 指定端口映射,本地到docker容器臼婆。
--name: 指定容器名字
在主機/tmp/webapp目錄下創(chuàng)建文件并寫入內容:
[root@private_vpn ~]# cd /tmp/webapp/
[root@private_vpn webapp]# ls
[root@private_vpn webapp]# echo "This is a docker web test page" >> index.html
[root@private_vpn webapp]# cat index.html
This is a docker web test page
docker容器內檢查數(shù)據(jù)是否已共享:
[root@71cf8102d33c webapp]# cat index.html
This is a docker web test page
數(shù)據(jù)已共享抒痒,在主機和容器之間。
然后再訪問試試看(當然我的此容器內已經(jīng)安裝好了nginx服務,根據(jù)需求自己修改配置):
已經(jīng)成功颁褂。
也可以先創(chuàng)建數(shù)據(jù)卷故响,然后在啟動容器的時候掛載數(shù)據(jù)卷
docker volume create my-vol
同樣可以通過inspect
命令查看數(shù)據(jù)卷詳細信息
可以看到在/data/docker/volumes/
目錄下創(chuàng)建一個數(shù)據(jù)卷my-vol(我之前修改了Docker Root Dir的目錄為/data/docker/
)
[root@test ~]# docker volume create my-vol
my-vol
[root@test ~]# docker volume ls
DRIVER VOLUME NAME
local my-vol
[root@test ~]# docker volume inspect my-vol
[
{
"CreatedAt": "2020-01-08T13:39:54+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/data/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
啟動一個掛載數(shù)據(jù)卷的容器:在用docker run
命令的時候,使用--mount
或者-v
標記來將數(shù)據(jù)卷
掛載到容器里颁独。下面創(chuàng)建一個名為本web的容器被去,并加載一個數(shù)據(jù)卷到容器的/usr/share/nginx/html
目錄。
docker run -d -p 8080:80 --name web -v my-vol:/usr/share/nginx/html nginx
[root@test ~]# docker run -d -p 8080:80 --name web -v my-vol:/usr/share/nginx/html nginx
f1ae7c82566a0bdb60931a8403b4ff6f72fd09673d0e586dac3ac11c49dc22ea
[root@test ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1ae7c82566a nginx "nginx -g 'daemon of…" 3 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp web
運行完成后奖唯,可以查看數(shù)據(jù)卷目錄下面已經(jīng)有文件了惨缆。
[root@test ~]# ls -l /data/docker/volumes/my-vol/_data/
total 8
-rw-r--r-- 1 root root 494 Nov 19 20:50 50x.html
-rw-r--r-- 1 root root 612 Nov 19 20:50 index.html
添加文件并測試訪問
[root@test ~]# cd /data/docker/volumes/my-vol/_data/
[root@test _data]# vim 1.html
[root@test _data]# cat 1.html
my-vol haha
[root@test _data]# curl localhost:8080/1.html
my-vol haha
數(shù)據(jù)卷時被設計用來持久化數(shù)據(jù)的,它的生命周期獨立于容器丰捷,Docker不會在容器被刪除后自動刪除數(shù)據(jù)卷坯墨,并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的數(shù)據(jù)卷
。如果需要在刪除容器的同時移除數(shù)據(jù)卷病往,可以在刪除容器的時候使用docker rm -v
這個命令捣染。無主的數(shù)據(jù)卷可能會占據(jù)很多存儲空間,需要清理請使用docker volume prune
命令停巷。
掛載權限
默認掛載的路徑權限為讀寫耍攘。如果指定為只讀可以用:ro榕栏,如:-v /tmp:/usr/tmp:ro。
– 容器目錄不可以為相對路徑
– 宿主機目錄如果不存在蕾各,則會自動生成
– 掛載宿主機已存在目錄后扒磁,在容器內對其進行操作,報“Permission denied”式曲》镣校可通過兩種方式解決:
* 1> 關閉selinux。
臨時關閉:`# setenforce 0`
永久關閉:修改`/etc/sysconfig/selinux`文件吝羞,將 SELINUX 的值設置為disabled兰伤。
* 2> 以特權方式啟動容器
指定`--privileged`參數(shù),如:
`# docker run -it --privileged=true -v /test:/soft centos /bin/bash`