[关闭]
@ranger-01 2018-05-14T19:30:07.000000Z 字数 4599 阅读 1087

精通Docker --- 镜像,容器,网络,存储

docker


1. 镜像

1.1 Docker为什么轻量级

image_1cdf6jdf92e41pl4esk15rp10mfp.png-257.7kB

对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

1.2 镜像的分层结构

可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
image_1cdeug31ab30qj71rjm7j7uus9.png-140.6kB

Docker 镜像采用分层结构最大的好处就是:共享资源。而且镜像的每一层都可以被共享。

1.3 可写的容器层

当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”

image_1cdeugmru1ve8a4j1pnrcrhg0pm.png-371.7kB

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。

  1. 添加文件
    在容器中创建文件时,新文件被添加到容器层中。

  2. 读取文件
    在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。

  3. 修改文件
    在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。

  4. 删除文件
    在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

1.4 构建镜像

Docker 提供了两种方法构建镜像:

  1. docker commit 命令

    • 这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱
    • 更重要的:使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审计,存在安全隐患。
  2. Dockerfile 构建文件

  3. 运行命令格式

    • Shell 格式: <instruction> <command> . 当指令执行时,shell 格式底层会调用 /bin/sh -c <command>
    1. ENV name Cloud Man
    2. ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
    • Exec 格式 <instruction> ["executable", "param1", "param2", ...]
  4. RUN vs CMD vs ENTRYPOINT

    • RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。

    • CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。

      • Exec 格式:CMD ["executable","param1","param2"]
        这是 CMD 的推荐格式。
      • CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
      • Shell 格式:CMD command param1 param2
    • ENTRYPOINT 配置容器启动时运行的命令。一定会被执行,即使运行 docker run 时指定了其他命令。

  5. 镜像名字组成

    [registry-host]:[port]/[username]/xxx:tag

2. 容器

cgroup 和 namespace 是最重要的两种技术。cgroup 实现资源限额, namespace 实现资源隔离。

2.1 Control Group。

Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。

image_1cdeuu797drv17flcno1og412hb13.png-67.8kB

2.2 namespace

在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。
Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。

3. 网络

Docker 安装时会自动在 host 上创建三个网络,我们可用 docker network ls 命令查看:

image_1cdeuv3u41ejr4bp1iqb9rms511g.png-58.1kB

3. bridge 网络

Docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上

image_1cdev1gt01rnl1snl19831v1012cj2t.png-118.9kB
image_1cd4k3kl31jg556m1c52dqm1gfp2d.png-96.8kB

3.1 创建bridge

docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2

3.2 容器间通信

3.3 容器与外界的连接

  1. 容器访问外网

    image_1cdev7tv0j5c7sv9ba61v1bqt51.png-91.8kB

    • -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
      其含义是:如果网桥 docker0 收到来自 172.17.0.0/16 网段的外出包,把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换(NAT)。
      image_1cdev94rr14v344fo1217p91ujt5e.png-171.3kB

    • docker0 的网络包:
      image_1cdev9sup14m71pld1mp411qr13ei5r.png-117kB

    • host机器网卡网络包:
      image_1cdevac8e1rocjbe16o71olshes68.png-110.3kB

  2. 外网访问容器

    • 每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量:
      image_1cdevgt0v1hr61nk61fms1bhd18259i.png-26.1kB

    • docker-proxy 监听 host 的 32773 端口。

    • 当 curl 访问 10.0.2.15:32773 时,docker-proxy 转发给容器 172.17.0.2:80。
    • httpd 容器响应请求并返回结果
      image_1cdevg8ojvs31oig11v1rau7hk95.png-120.7kB

4.存储

Docker 为容器提供了两种存放数据的资源:

4.1 两种类型的volume

4.2 数据共享

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注