@ranger-01
2018-05-14T19:30:07.000000Z
字数 4599
阅读 1087
docker
对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。
可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
Docker 镜像采用分层结构最大的好处就是:共享资源。而且镜像的每一层都可以被共享。
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。
添加文件
在容器中创建文件时,新文件被添加到容器层中。
读取文件
在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
修改文件
在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
删除文件
在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。
容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
Docker 提供了两种方法构建镜像:
docker commit 命令
Dockerfile 构建文件
运行命令格式
<instruction> <command>
. 当指令执行时,shell 格式底层会调用 /bin/sh -c <command>
ENV name Cloud Man
ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
<instruction> ["executable", "param1", "param2", ...]
RUN vs CMD vs ENTRYPOINT
RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。
ENTRYPOINT 配置容器启动时运行的命令。一定会被执行,即使运行 docker run 时指定了其他命令。
镜像名字组成
[registry-host]:[port]/[username]/xxx:tag
cgroup 和 namespace 是最重要的两种技术。cgroup 实现资源限额, namespace 实现资源隔离。
Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。
在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。
Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。
Docker 安装时会自动在 host 上创建三个网络,我们可用 docker network ls 命令查看:
none: 网络就是什么都没有的网络.
host: 容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。
Docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
创建容器,并指定bridge
到目前为止,容器的 IP 都是 docker 自动从 subnet 中分配,我们能否指定一个静态 IP 呢?只有使用 --subnet 创建的网络才能指定静态 IP。
不同bridge间是不能通信的
给docker0上的某个容器加上一张网卡,使之能与my_net2中容器通信
docker network connect my_net2 h1
ip 通信
两个容器要能通信,必须要属于同一个网络的网卡。具体做法是
Docker DNS server通信
通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署应用之前可能无法确定 IP,部署之后再指定要访问的 IP 会比较麻烦。
joined容器
它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信。
docker run -d -it --name=web1 httpd
docker run -it --network=container:web1 busybox
容器访问外网
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
其含义是:如果网桥 docker0 收到来自 172.17.0.0/16 网段的外出包,把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换(NAT)。
docker0 的网络包:
host机器网卡网络包:
外网访问容器
每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量:
docker-proxy 监听 host 的 32773 端口。
Docker 为容器提供了两种存放数据的资源:
bind mount
bind mount 是将 host 上已存在的目录或文件 mount 到容器。
docker managed volume
docker run -d - p 80:80 -v /usr/local/apache2/htdocs httpd