Docker: 数据管理与端口映射、容器互联
一.数据管理
常常需要对数据进行持久化,or多个容器之间进行数据共享。
容器中的管理数据主要有2种方式:
- 数据卷Data Volumes :容器内数据直接映射到本地主机环境
- 数据卷容器Data Volumes Containers: 使用特定容器维护数据卷
我们应该明白如何在容器内创建数据卷,并把本地的目录或文件挂载到容器内的数据卷中。如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复。
1. 数据卷:
数据卷是一个可供容器使用的特殊目录,将主机操作系统目录直接映射进容器。
特性:
- 可以在容器之间共享和重用
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作
- 对数据卷的更新不会影响镜像,解耦开应用和数据
- 卷会一直存在,直到没有容器使用后就可以安全的卸载它
1.1 创建数据卷:(Docker提供了volume子命令来管理数据卷)
快速在本地创建一个数据卷:
查看var/lib/docker/volumes,会发现创建的数据卷位置:
docker volume还支持:
- inspect查看详细信息
- ls列出已有的数据卷
- prune清理无用数据卷
- rm删除数据卷
1.2 绑定数据卷:
在创建容器时将主机本地的任意路径挂载到容器内作为数据卷,这种形式创建的数据卷称为绑定数据卷。
docker [container] run命令时,可以使用-mount来使用数据卷.
-mount支持3种类型的数据卷:
- volume: 普通数据卷,映射到主机/var/lib/docker/volumes路径下
- bind: 绑定数据卷,映射到主机指定路径下
- tmpfs: 临时数据卷,只存于内存中
e.g: 使用training/webapp镜像创建一个web容器,并创建一个数据卷挂载到容器的/opt/webapp目录:
等价写法:
注意:
本地目录路径必须是绝对路径,容器内路径可以为相对路径,如果目录不存在,docker会自动创建
docker挂载数据卷的默认权限是rw,用户可以通过ro指定为只读:
这样,容器内对所挂载数据卷内的数据就无法修改了。
2.数据卷容器:
需要在多个容器之间共享一些持续更新的数据。
最简单的方式:使用数据卷容器。
数据卷容器是一个容器,它的目的是专门提供数据卷给其他容器挂载。
e.g:
(1). 首先创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:
(2). 然后可以在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷。
e.g:
此时容器db1 db2都挂载到了同一个数据卷到相同的/dbdata目录,3个容器任何一方在该目录下的写入,其他容器都可以看到。
可以多次使用--volumes-from来从多个容器挂载多个数据卷,甚至可以从其他已经挂载了容器卷的容器来挂载数据卷。
使用--volumes-from参数所挂载的容器自身并不需要保持在运行状态。
如果删除了挂载的容器,数据卷并不会被自动删除。
想要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式使用docker rm -v 来指定同时删除关联的容器。
3. 利用数据卷容器来迁移数据:
使用数据卷容器可以让用户在容器之间*升级和移动数据卷。
利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。
3.1 备份:
如下命令备份dbdata数据卷容器内的数据卷:
解释:
首先利用ubuntu镜像创建一个容器worker,使用--volumes-from dbdata来让worker容器挂载到dbdata容器的数据卷(dbdata数据卷);使用-v $(pwd):/backup来挂载本地的当前目录到workeer容器的/backup目录。worker容器启动后,使用tar cvf /backup/backup.tar /dbdata将/dbdata下内容备份为容器内的/backup/backup.tar , 即宿主主机当前目录下的backup.tar
3.2 恢复:
首先,创建一个带有数据卷的容器dbdata2:
然后创建另一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器卷中:
二.端口映射和容器互联
经常需要多个服务组件容器共同协作的情况。往往需要多个容器之间能够互相访问到对方的服务。
容器服务的访问是一个关键。Docker支持LInux系统自带的网络服务和功能。
Docker提供了3个方便的功能来满足服务访问的基本需求:
- 通过网络访问(另一篇文章讲解)
- 允许映射容器内应用的服务端口到本地宿主主机
- 互联机制实现多个容器间通过容器名来快速访问
1. 端口映射实现容器访问:
1.1 从外部访问容器应用:
当容器中运行一些网络应用,要让外部访问这些应用时,可以使用-p 或-P参数来指定端口映射。
使用-P的时候,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口。
如果是虚拟机,只需要查看虚拟机的ip地址,然后在宿主机访问就行了。
在一个指定端口上只可以绑定一个容器,支持的格式:
- IP:HostPort:ContainerPort映射到指定地址的指定端口
- IP::ContainerPort 映射到指定地址的任意端口
还可以使用udp标记指定udp端口:
- HostPort:ContainerPort映射所有接口地址
查看映射端口配置/绑定的地址:docker port
容器有自己的内部网络和ip地址,使用docker [container] inspect+容器ID,获取容器的具体信息。
2. 互联机制实现便捷互访:
互联linking是一种让多个容器中的应用 进行快速交互的方式。会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,不用指定具体的ip地址。
2.1 自定义容器命名:
连接系统依据容器的名称来执行。
首先需要自定义一个好记的容器命名。当创建容器的时候,系统会默认分配一个名字。
使用--name标记可以为容器自定义命名。
还可以使用docker [container] inspect来查看容器的名字:
容器名是唯一的。假设已命名一个叫mynginx的容器,当再次使用mynginx这个名称的时候,需要先用docker rm 删除之前创建的同名容器。
在执行docker run 的时候如果添加--rm标记,则容器在终止后会立刻删除。--rm和-d不能同时使用
2.2 容器互联:
使用--link可以让容器之间安全的进行交互。
此时mynginx和mynginx2容器建立了互联关系。
--link参数的格式为--link name:alias
name是要链接的容器的名称,alias是别名
当使用docker ps 查看name列有mynginx2/mynginx表示nginx容器链接到了mynginx2容器,语序访问mynginx2容器的信息。
docker相当于在2个互联的容器间创建了一个虚拟通道。不用映射他们的端口到宿主主机上。没有使用-p标记,避免了暴露服务端口到外部网络上。
docker通过2种方式为容器公开链接信息:
- 更新环境变量
- 更新/etc/hosts文件(docker添加host信息到父容器的/etc/hosts文件)
可以使用ping来测试容器的联通:
先在容器内安装:
然后ping+容器名。
用户可以链接到多个子容器到父容器。