《Docker Deep Dive》阅读笔记(二)

卷和数据持久化#

  • 非持久化数据,Linux 系统下,存放在 /var/lib/docker/<storage-driver>/,Windows 系统下,则是在 C:\ProgramData\Docker\windowsfilter\
  • 卷挂载到容器中的文件夹示意图:

    《Docker Deep Dive》阅读笔记(二)

  • 创建:docker volume create myvol
    • -d 指定驱动
  • 查看:docker volume ls
  • 详情:docker volume inspect myvol
  • 删除:docker volume rm xxx
  • 删除所有未挂载到容器的:docker volume prune(慎用)
  • 可以在 Dockerfile 文件中通过 VOLUME 指令部署卷
  • 卷和容器 / 服务
    • docker container run -dit --name voltainer --mount source=bizvol,target=/vol alpine:这里将卷 bizvol 挂载到容器中的 /vol 文件夹,如果卷不存在,会自动创建

Docker 网络#

  • Docker 网络由三部分构成:

    • The Container Network Model (CNM) : 设计指导
    • libnetwork : CNM 的具体实现
    • Drivers : 驱动
  • CNM 模型

    《Docker Deep Dive》阅读笔记(二)

    由三部分组成:

    • Sandboxes : Ethernet interfaces, ports,routing tables, and DNS config.
    • Endpoints : 虚拟网络接口,如 veth
    • Networks : 实现桥接的软件
  • 宿主主机、容器与容器之间的网络关系

    《Docker Deep Dive》阅读笔记(二)

    • 容器 A 有一个端点,B 有两个端点
    • A 和 B 可以通讯,因为它们都连接到了网络 A
    • 一个端点只能连接到一个网络,如果一个容器需要连接到多个网络,就需要多个端点
    • 容器 A 和 B 的网络通过沙箱隔离,各自独立
  • Libnetwork

    • CNM 是设计文档,Libnetwork 是它的经典实现(使用 Go 语言)
    • 不仅实现了 CNM 组成的三部分,而且实现了服务发现、ngress-based 容器负载均衡、network control plane 和 management plane
  • Drivers

    • 相对于 Libnetwork 实现了 network control plane 和 management plane,Driver 则是实现了 data plane。三个 plane 的关系示意图:

    《Docker Deep Dive》阅读笔记(二)
    Docker 内置了几种原生 Driver,在 Linux 系统下,包括:bridge, overlay 和 macvlan;在 Windows 系统下,包括:nat, overlay, transparent 和 l2bridge。还有第三方 Driver。

    • Driver 负责创建和管理它所负责的网络资源
    • Libnetwork 允许同时又多个 Driver
  • 单主机桥接网络

    • 存在于一个 Docker 宿主主机
    • 是 802.1d 网桥的实现
    • 在 Linux 下,使用 bridge driver 创建,而 windows 下则是 nat
    • 不同主机之间即使相同的网络名称也不能通讯
    • 查看:docker network ls
    • 详情: docker network inspect xxx
    • Linux 下的 bridge driver 是基于 Linux bridge,所以可以使用 Linux 的命令查看详情,比如:ip link show docker0
    • Docker’s 默认的 “bridge” 网络和 Linux 的 “docker0” bridge 关系示意图:

    《Docker Deep Dive》阅读笔记(二)

    • 创建一个叫 localnet 的网络(Linux):docker network create -d bridge localnet
    • apt install bridge-utils 安装查看工具,brctl show 查看 Driver(结果跟 docker network ls 一一对应
      《Docker Deep Dive》阅读笔记(二)
    • 例子

      • 运行一个容器,并添加到 localnet 网络:docker container run -d --name c1 --network localnet alpine sleep 1d
      • 查看结果:docker network inspect localnet --format '{{json .Containers}}',可以看到容器已经添加到网络
      • brctl show 查看,结果大概是这样的:
        《Docker Deep Dive》阅读笔记(二)
        可以看到 c1 的 interface 添加到了 br-20c2e8ae4bbb bridge。
        示意图:

    《Docker Deep Dive》阅读笔记(二)

    • 如果添加一个新的容器到相同的网络,在这个容器可通过名字 c1ping 同 c1 容器,因为容器内置了 Docker DNS 服务,因而可以解析同个网络下其他所有容器的名称
    • 注意:默然的 bridge network 不只是 DNS 解析,而其他用户自定义的则可以
    • 例子:
      • 启动另一个容器,添加到同一个网络:docker container run -it --name c2 --network localnet alpine sh
      • 在容器 c2 中 ping 容器 c1:ping c1 ,结果可以 ping 通
        • 容器通过容器端口与宿主主机的端口映射连接外部网络
        • 例子
        • 运行一个 web 服务容器,将容器的 80 端口映射到宿主主机的 5000 端口:docker container run -d --name web --network localnet --publish 5000:80 nginx
        • 确认端口映射:docker port web
        • 测试:浏览器访问主机IP:5000,将可以访问到站点(windows 下为 localhost:5000 或 127.0.0.1:5000)
  • 多主机 overlay 网络(Multi-host overlay networks)

    • macvlan driver (在 windows 上是 transparent)

      • 通过给容器 MAC 和 IP 地址,不需要端口映射和网桥
      • 但 host NIC 必需为 promiscuous mode
      • 连接到 VLAN 需要:子网信息、网关、IP 段、使用宿主主机的哪个 interface 或 sub-interface
      • 例子

        • 创建

          docker network create -d macvlan \
          --subnet=10.0.0.0/24 \
          --ip-range=10.0.0.0/25 \ # 指定IP段
          --gateway=10.0.0.1 \
          -o parent=eth0.100 \  # 表示连接到VLAN 100
          macvlan100

          将会创建名称为 macvlan100 的网络、the eth0.100 sub-interface,示意图:

      《Docker Deep Dive》阅读笔记(二)

      • 添加到容器:

            docker container run -d --name mactainer1 \
            --network macvlan100 \
            alpine sleep 1d
        示意图(多个容器):
        
        ![《Docker Deep Dive》阅读笔记(二)](https://cdn.learnku.com/uploads/images/201909/20/27146/cuJ581nJHk.PNG!large)
    • 容器和排除问题的服务日志

      • 守护进程的日志
        • windows:位于∼AppData\Local\Docker
        • Linux:journalctl -u docker.service 查看
        • 修改 daemon.json 配置文件,可配置日志的记录级别等,修改后记得重启 Docker
      • 容器的日志
        • 单机容器:docker container logs <container-name>
        • Swarm 服务:docker service logs <service-name>
        • 宿主主机为容器提供日志驱动,可有:
          • json-file (default)
          • journald (only works on Linux hosts running systemd)
          • syslog
          • splunk
          • gelf
        • 可在 daemon.json 文件中配置驱动:"log-driver": "syslog
        • 单独为容器或服务配置日志驱动:--log-driver 或者 --log-opts
    • 服务发现

      • 服务发现允许容器之间、Swarm 服务之间相互定位(需要在相同的网络)
      • Docker 内置了 DNS 服务,每个容器自带 DNS 解析
      • 以下是 容器 “c1” 通过容器名称 ping 容器 “c2” 的示意图:
        《Docker Deep Dive》阅读笔记(二)
        • 容器或 Swarm 服务启动时添加 --name,DNS 服务就会注册其名称和 IP(需在同一个网络)
        • --dns 指定 DNS 解析服务器地址
        • --dns-search 自定义搜索域名,对于不能解析的名称
        • 例子
          docker container run -it --name c1 \
          --dns=8.8.8.8 \
          --dns-search=dockercerts.com \
          alpine sh
    • Ingress 负载均衡

      • Swarm 支持两种发布模式用于从集群外部访问集群
        • Ingress 模式(默认):Swarm 的任何节点,即使没有 service replica 也可以访问
        • Host 模式: 节点需要有 service replicas 运行才能访问
        • 例子,发布为 host 模式
           docker service create -d --name svc1 \
          --publish published=5000,target=80,mode=host \
          nginx

          Ingress 模式访问路由示意图:(外部的访问可能命中任意一个节点)
          《Docker Deep Dive》阅读笔记(二)
          如果有多个副本,将会平衡访问:
          《Docker Deep Dive》阅读笔记(二)

本作品采用《CC 协议》,转载必须注明作者和本文链接
Was mich nicht umbringt, macht mich stärker