《Docker 技术入门与实践》-读书笔记二

《Docker 技术入门与实践》-读书笔记一

《Docker 技术入门与实践》-读书笔记二

一、数据管理

用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据,或者把容器内的数据进行备份,甚至在多个容器之间进行数据的共享,这必然涉及容器的数据管理操作。

容器中管理数据的方式有两种:

数据卷:数据卷是一个可供容器使用的特殊目录,它绕过文件系统,并提供多个特性。

  • 数据卷可以在容器之间共享和重用。
  • 对数据卷的修改会立马生效。
  • 对数据卷的更新不会影响镜像。
  • 卷会一直存在,直到没有容器使用。

数据卷容器:如果用户需要在容器之间共享一些持续更新的数据,最简单的方式就是使用数据卷容器。专门用它提供数据卷供其他容器挂载使用。


(一)在容器内创建一个数据卷

1、只要在 docker run 命令后面跟上 -v 参数即可创建一个数据卷,当然也可以跟多个 -v 参数来创建多个数据卷,当创建好带有数据卷的容器后,就可以在其他容器中通过 --volumes-froms 参数来挂载该数据卷了,而不管该容器是否运行。

2、不能使用 docker export、save、cp 等命令来备份数据卷的内容,因为数据卷是存在于镜像之外的。备份的方法可以是创建一个新容器,挂载数据卷容器,同时挂载一个本地目录,然后把远程数据卷容器的数据卷通过备份命令备份到映射的本地目录里面。

3、也可以把一个本地主机的目录当做数据卷挂载在容器上,同样是在docker run后面跟-v参数,不过-v后面跟的不再是单独的目录了,它是[host-dir]:[container-dir]:[rw|ro]这样格式的,host-dir是一个绝对路径的地址,如果host-dir不存在,则docker会创建一个新的数据卷,如果host-dir存在,但是指向的是一个不存在的目录,则docker也会创建该目录,然后使用该目录做数据源。

为容器添加一个数据卷,这个数据卷在容器里的目录是/opt/data:

[root@localhost bin]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               14.04               316b57509753        6 days ago          215 MB
test                 latest              3af2730c06cf        6 days ago          86.7 MB
docker.io/registry   latest              33fbbf4a24e5        12 days ago         24.2 MB
docker.io/ubuntu     latest              1d9c17228a9e        2 weeks ago         86.7 MB
[root@localhost bin]# docker run -v /opt/data -t -i ubuntu /bin/bash
root@ec225a892f3f:/# cd /opt/data/
root@ec225a892f3f:/opt/data# ll
total 0
drwxr-xr-x. 2 root root  6 Jan 16 09:33 ./
drwxr-xr-x. 1 root root 18 Jan 16 09:33 ../
root@ec225a892f3f:/opt/data# echo "123" >123
root@ec225a892f3f:/opt/data# echo "456" >456
root@ec225a892f3f:/opt/data# ll
total 8
drwxr-xr-x. 2 root root 28 Jan 16 09:33 ./
drwxr-xr-x. 1 root root 18 Jan 16 09:33 ../
-rw-r--r--. 1 root root  4 Jan 16 09:33 123
-rw-r--r--. 1 root root  4 Jan 16 09:33 456
[root@localhost bin]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
ec225a892f3f        ubuntu              "/bin/bash"              About a minute ago   Up 4 seconds                                 dreamy_montalcini
30da4c14bf41        registry            "/entrypoint.sh /e..."   31 hours ago         Up 31 hours         0.0.0.0:5000->5000/tcp   keen_murdock

在宿主机上,查看对应上面的那个数据卷的目录路径:

示例:在 “Mounts” 里面存在 source 参数,查看 source 参数可以看到目录里创建的文件。

[root@localhost ~]# docker inspect ec22
[
        ......            

        "Mounts": [
            {
                "Type": "volume",
                "Name": "40d01d2437d53f7ce47a21c957a7cb394f614f90b35fa575b54a73099923b275",
                "Source": "/var/lib/docker/volumes/40d01d2437d53f7ce47a21c957a7cb394f614f90b35fa575b54a73099923b275/_data",
                "Destination": "/opt/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "ec225a892f3f",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "ubuntu",
            "Volumes": {
                "/opt/data": {}
            },
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4f7bf29146b3e72a2a31729947f487097702cc80209debff933669f2972f5912",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4f7bf29146b3",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "d67206d5ba47d81df70a8fb994cee079f17997734b20de378c157a5937c7162c",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "4d39ec836b91611392702d03d11354e823345cf59c2bd4f86411ab4802236196",
                    "EndpointID": "d67206d5ba47d81df70a8fb994cee079f17997734b20de378c157a5937c7162c",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03"
                }
            }
        }
    }
]
[root@localhost ~]# ll /var/lib/docker/volumes/40d01d2437d53f7ce47a21c957a7cb394f614f90b35fa575b54a73099923b275/_data
总用量 8
-rw-r--r--. 1 root root 4 1月  16 17:33 123
-rw-r--r--. 1 root root 4 1月  16 17:33 456

(二)挂载宿主机文件或目录到数据卷

可以直接挂载宿主机文件或目录到容器里,可以理解为目录映射,这样就可以让所有的容器共享宿主机数据,从而只需要改变宿主机的数据源就能够影响到所有的容器数据。

注意:
-v后面的映射关系是 "宿主机文件/目录 : 容器里对应的文件/目录",其中,宿主机上的文件/目录是要提前存在的,容器里对应的文件/目录会自动创建。

数据卷权限:
挂载的数据默认为可读写权限。
但也可以根据自己的需求,将容器里挂载共享的数据设置为只读,这样数据修改就只能在宿主机上操作。如下实例:

1、挂载宿主机文件到容器上 示例:

挂载宿主机文件到容器上

# 在 /usr/local 目录下创建一个文件,填写数据
[root@localhost local]# cat mount.list 
apple
banana
orange
#将目录文件挂载到容器
[root@localhost local]# docker run -t -i -v /usr/local/mount.list:/usr/local/mount.list:ro ubuntu /bin/bash
#查看挂载文件的信息
root@0d45c8e9ff4d:/# cat /usr/local/mount.list 
apple
banana
orange
# 向文件中添加信息,提示没有权限
root@0d45c8e9ff4d:/# echo "watermelon" >> /usr/local/mount.list 
bash: /usr/local/mount.list: Permission denied

在宿主机上修改共享数据

[root@localhost local]# echo "watermelon" >> /usr/local/mount.list 
[root@localhost local]# cat mount.list 
apple
banana
orange
watermelon

在容器中查看共享数据,共享数据已经更新

root@0d45c8e9ff4d:~# cat /usr/local/mount.list 
apple
banana
orange
watermelon

2、挂载宿主机目录到容器 示例:

[root@localhost local]# mkdir mountdir
[root@localhost local]# echo "data1" >> mountdir/data1
[root@localhost local]# echo "data2" >> mountdir/data2
#将目录挂载到容器
[root@localhost local]# docker run -ti -v /usr/local/mountdir/:/opt/mountdir ubuntu /bin/bash
root@2797491c3d19:/# cd /opt/mountdir/
root@2797491c3d19:/opt/mountdir# ll
total 8
drwxr-xr-x. 2 root root 32 Jan 17 02:37 ./
drwxr-xr-x. 1 root root 22 Jan 17 02:38 ../
-rw-r--r--. 1 root root  6 Jan 17 02:37 data1
-rw-r--r--. 1 root root  6 Jan 17 02:37 data2

在宿主机上修改目录文件

[root@localhost local]# cd mountdir/
[root@localhost mountdir]# ll
总用量 8
-rw-r--r--. 1 root root 6 1月  17 10:37 data1
-rw-r--r--. 1 root root 6 1月  17 10:37 data2
[root@localhost mountdir]# echo "data11" >> data1

在容器中查看共享目录

root@2797491c3d19:/opt/mountdir# cat data1
data1
data11

(三)创建数据卷容器

启动一个名为First_Container容器,此容器包含两个数据卷/var/volume1和/var/volume2(这两个数据卷目录是在容器里的,容器创建的时候会自动生成这两目录)

[root@localhost ~]# docker run -ti -v /var/volume1 -v /var/volume2 --name First_Container ubuntu /bin/bash

查看宿主机上与数据卷对应的目录路径:

[root@localhost ~]# docker inspect First_Container | grep /var/lib/docker/volumes
                "Source": "/var/lib/docker/volumes/e90b988156a2763b2e564fcfcf6f8163f5836e1094cd6c4bd61fd13aec93a521/_data",
                "Source": "/var/lib/docker/volumes/e26833eb7ad21a5fbdfbbe2a3ceec85a349fef491630ef47777bf6af039cfd69/_data",

由上面命令结果可以查到,两个数据卷/var/volume1和/var/volume2下的数据在/var/lib/docker/volumes/下对于的两个目录的_data下面

创建Second_Container容器,挂载First_Container容器中的数据卷:

[root@localhost ~]# docker run -t -i --rm --volumes-from First_Container --name Second_Container ubuntu /bin/bash
root@91fa9e2d37d8:/#

查询容器中的数据卷

root@91fa9e2d37d8:/# cd /var/
root@91fa9e2d37d8:/var# ll
total 0
drwxr-xr-x. 1 root root   36 Jan 17 03:08 ./
drwxr-xr-x. 1 root root   28 Jan 17 03:08 ../
drwxr-xr-x. 2 root root    6 Apr 24  2018 backups/
drwxr-xr-x. 5 root root   48 Dec  4 17:12 cache/
drwxr-xr-x. 1 root root   17 Dec  4 17:11 lib/
drwxrwsr-x. 2 root staff   6 Apr 24  2018 local/
lrwxrwxrwx. 1 root root    9 Dec  4 17:11 lock -> /run/lock/
drwxr-xr-x. 3 root root  148 Dec  4 17:11 log/
drwxrwsr-x. 2 root mail    6 Dec  4 17:11 mail/
drwxr-xr-x. 2 root root    6 Dec  4 17:11 opt/
lrwxrwxrwx. 1 root root    4 Dec  4 17:11 run -> /run/
drwxr-xr-x. 2 root root   18 Dec  4 17:11 spool/
drwxrwxrwt. 2 root root    6 Dec  4 17:12 tmp/
drwxr-xr-x. 2 root root    6 Jan 17 03:00 volume1/
drwxr-xr-x. 2 root root    6 Jan 17 03:00 volume2/

即便是删除了初始的数据卷容器xqsj_Container,或是删除了其它容器,但只要是有容器在使用该数据卷,那么它里面的数据就不会丢失!(除非是没有容器在使用它们)。

(四)删除数据卷

如果删除了挂载的容器,数据卷不会被自动删除。Volume 只有在下列情况才能被删除:

  • docker rm -v 删除容器时添加 -v 选项
  • docker run --rm 运行容器时添加 --rm 选项

否则会在 /var/lib/docker/volumes 目录中留下很多不明目录。可以使用下面的方式找出,然后删除数据文件。

[root@localhost ~]# docker inspect First_Container | grep /var/lib/docker/volumes
                "Source": "/var/lib/docker/volumes/e90b988156a2763b2e564fcfcf6f8163f5836e1094cd6c4bd61fd13aec93a521/_data",
                "Source": "/var/lib/docker/volumes/e26833eb7ad21a5fbdfbbe2a3ceec85a349fef491630ef47777bf6af039cfd69/_data",
[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               40d01d2437d53f7ce47a21c957a7cb394f614f90b35fa575b54a73099923b275
local               d171b6e64c660358f3b9ce84e059f44dd2f6c05a2bd3604a4d4efcb36d2dd81d
local               e26833eb7ad21a5fbdfbbe2a3ceec85a349fef491630ef47777bf6af039cfd69
local               e90b988156a2763b2e564fcfcf6f8163f5836e1094cd6c4bd61fd13aec93a521
local               fe0ec142d8d37b79668ca154ebba1a2a40c6db802184e50194cb4e5bc04e3720
[root@localhost ~]# docker rm -vf First_Container
First_Container
[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               40d01d2437d53f7ce47a21c957a7cb394f614f90b35fa575b54a73099923b275
local               d171b6e64c660358f3b9ce84e059f44dd2f6c05a2bd3604a4d4efcb36d2dd81d
local               fe0ec142d8d37b79668ca154ebba1a2a40c6db802184e50194cb4e5bc04e3720
[root@localhost ~]# 

(五)备份

使用下面的命令来备份数据卷容器的数据卷:

[root@localhost ~]# docker run --volumes-form dbdata -v ${pwd}:/backup --name worker ubuntu
tar cvf /backup/backup.tar  /dbdata

解释:首先利用 Ubuntu 镜像创建一个容器 worker . 使用 --volumes-form dbdata 参数来让 worker 容器挂载 dbdata 容器的数据卷;使用 -v ${pwd}:/backup 参数来挂载本地的当前目录到 worker 容器的 /backup 目录。

worker 容器启动后,使用了 tar cvf /backup/backup.tar  /dbdata 命令来将 /dbdata 下内容备份为容器内的  /backup/backup.tar 即宿主机当前目录下的 backup.tar 。

(六)恢复

恢复数据到一个容器,可以按照下面的操作,先创建一个带有数据卷的容器 dbdata2 :

[root@localhost ~]# docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后创建另一个新的容器,挂载 dbdata2 的容器,并解压备份文件到所挂载的容器卷中即可:

[root@localhost ~]# docker run --volumes-form dbdata2 -v ${pwd}:/backup ubuntu tar xvf /backup/backup.tar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值