04

理解Docker Volume

一个容器中的进程修改了容器中的文件, 那么会讲底层的文件复制一份,然后在修改, 这样就生成了一个新的层级.
Image 存放路径:
/var/lib/docker/graph : 每层之间的关系
/var/lib/docker/devicemapper/devicemapper/metadata
两个目录都是存放 image 的元信息, 而不是数据文件. 双份的数据
Image 和 Container 的二进制数据文件存放在:
/var/lib/docker/devicemapper/devicemapper/data
data 是一个特殊的叙述文件, ls 看大小是100G, 表示最大是100G, du 是真正的大小.

graphdriver 的几种实现

aufs是 linux 内核的一个补丁集, 由于代码质量不高,一直没有被 linux 内核所接受, 目前只有 Ubuntu 系统在使用.
Device mapper 是 linux2.6内核中提供的一种从逻辑设备到物理设备的映射框架机制, 是 LVM2的核心, 支持块级别的 copy on write 特性.
VFS 虚拟文件系统的最大缺陷是不支持 copy on wirte 特性, 每层都是一个单独的目录, 如果要新增一个 child 层, 则需要讲父级层镜像文件一并复制到新目录.(可用但基本不用)
btrfs 非常快, 采用 btrfs 的文件系统级的快照能力来实现分层功能, 缺点是仍在进化中, 还不够成熟, 特别是在大量写操作的压力下.
目前,除了少数版本如 Ubuntu, Docker 基本运行在 Devicemapper 基础上.

为什么需要 Volume

docker 写操作的两种方式, 一种就是 Ubuntu 下的 aufs, 一种就是常用的 Devicemapper. 这两种方式在高频写文件的时候都需要付出很大代价(都需要复制一份新的副本再修改文件), 所以 docker 官方推荐使用 volume.

volume 是什么

volume 的实质是在宿主机上映射一个文件夹到docker 中, 让 docker 可以对这个文件夹可以进行操作.
-v 不指定宿主机目录
使用 docker run -v 创建一个 container 以后, 使用 docker inspect 可以看到 mounts 中 -v 对应的目录在宿主机中的path:

如果在这个_data 的目录下新建一个文件夹, 那么在 docker 中对应的/leader 下也会看到. 类似于 link 的效果.
-v 指定本机目录
可以将宿主机的目录与 docker 中的目录进行映射, 多个 docker 可以映射同一目录,这样就实现了基于 volume 互联实现跨主机共享的目的.
但在 build 中是无法使用这种方式的, 因为需要指定本机目录, 就会导致无法移植.
基于数据容器的单主机互联
有一个单独的 volume container 来负责提供数据, 其他 container 通过访问它来使用数据.

docker run --rm=true --privileged=true --volumes-from=3d1ada481637 -it java /bin/bash

比如3d1ada481637中存在一个/leder 的目录, 那么通过这样创建的container 也会拥有相同的/leader 目录.

在 volume container 中创建一个 volume, 其他依赖于它的 container 都可以拥有相同的目录, 并且不依赖于宿主机目录.

基于 link 的互联

docker 默认是允许 container 互通的, 通过-icc=false 可以关闭互通. 一旦关闭了互通, 只能通过-link name:alias 命令来连接指定 container.
--link redis:db 的别名, 会在/etc/hosts 中生成对应的 ip 映射. 其中redis为目标容器,db是给这个主机名指定的一个别名
link支持同一台主机上的 container 互联, 跨主机的 link 实现可以使用docker 的远程代理模式 ,原理就是在不同的主机上通过自动生成的代理容器来通信, 转发数据.

socat 工具

socat can forward connections through an HTTP proxy

socat TCP4-LISTEN:6666 TCP4:proxy.company.com:8080

这个命令会将请求6666的数据转发到 proxy.company.com 的8080端口
和 iptable 的转发有什么区别?

基于网络的互联

常用的互联方式: 端口转发
docker run -p 8066:3306 会在宿主机中新增一个 docker-proxy 的进程, 来监听主机的8066端口
--net=host 使用宿主机的网络
--net=container:mysqlServer 多个容器公用一个 IP, 有利于实现一个容器中运行一个进程

2016-09-29 15:252