云计算深度实践者。《每天5分钟玩转OpenStack》《每天5分钟玩转Docker容器技术》作者。
sysdig 是一个轻量级的系统监控工具,同时它还原生支持容器。通过 sysdig 我们可以近距离观察 linux 操作系统和容器的行为。 Linux 上有很多常用的监控工具,比如 strace,tcpdump,htop, iftop,lsof ...... 而 sysdig 则是将这些工具的功能集成到一个工具中,并且提供一个友好统一的操作界面。
当 Docker 部署规模逐步变大后,可视化监控容器环境的性能和健康状态将会变得越来越重要。 在本章中,我们将讨论几个目前比较常用的容器监控工具和方案,为大家构建自己的监控系统提供参考。 首先我们会讨论 Docker 自带的几个监控子命令:ps, top 和 stats。
上一节我们在 docker1 上的 MySQL 容器中使用了 Rex-Ray volume mysqldata,更新了数据库。现在容器已经删除,今天将演示在 docker2 中重新使用这个卷。 在 dokcer2 上执行如下命令,启动 MySQL 容器: docker run --name mydb_on_docker2 -v mysqldata:/var/lib/mysql -d mysql 新容器也使用相同的卷 mysqldata,不过这次不需要指定环境变量 MYSQL_ROOT_PASSWORD,因为密码已经保存到 mysqldata 里面了。
前面我们安装部署了 Rex-Ray,并且成功配置 VirtualBox backend,今天演示如何创建和使用 Rex-Ray volume。 在 docker1 或 docker2 上执行如下命令创建 volume: docker volume create --driver rexray --name=mysqldata --opt=size=2 volume mysqldata 创建成功,大小为 2GB。
Rexy-Ray 支持多种 backend,上一节我们已经安装配置了 Rex-Ray,今天演示如何配置 VirtualBox backend。 在 VirtualBox 宿主机,即我的笔记本上启动 vboxwebsrv 服务:vboxwebsrv -H 0.0.0.0 执行如下命令关闭 VirtualBox 的登录认证:VBoxManage setproperty websrvauthlibrary null 在关机状态下修改虚拟机 docker1 和 docker2 的 Storage 配置: 删除 IDE controller。
Rex-Ray 是一个优秀的 Docker volume driver,本节将演示其安装和配置方法。 Rex-Ray 以 standalone 进程的方式运行在 Docker 主机上,安装方法很简单,在需要使用 Rex-Ray driver 的主机 docker1 和 docker2 上运行如下命令: curl -sSL https://dl.
从业务数据的角度看,容器可以分为两类:无状态(stateless)容器和有状态(stateful)容器。 无状态是指容器在运行过程中不需要保存数据,每次访问的结果不依赖上一次访问,比如提供静态页面的 web 服务器。
前面各小节我们先后学习了 Docker Overaly,Macvaln,Flannel,Weave 和 Calico 跨主机网络方案。目前这个领域是百家争鸣,而且还有新的方案不断涌现。 本节将从不同维度比较各种网络方案,大家在选择的时候可以参考。
在前面的小节中,我们没有特别配置,calico 会为自动为网络分配 subnet,当然我们也可以定制。 首先定义一个 IP Pool,比如: cat
Calico 默认的 policy 规则是:容器只能与同一个 calico 网络中的容器通信。本节讨论如何定制 policy。 calico 能够让用户定义灵活的 policy 规则,精细化控制进出容器的流量,下面我们就来实践一个场景: 创建一个新的 calico 网络 cal_web 并部署一个 httpd 容器 web1。
前面我们完成了 Calico 网络的部署并运行了容器,今天将讨论 Calico 的连通性。测试一下 bbox1 与 bbox2 的连通性: ping 成功,数据包流向如下图所示。
上一节我们部署了 Calico 网络,今天将运行容器并分析 Calico 的网络结构。在 host1 中运行容器 bbox1 并连接到 cal_net1: docker container run --net cal_net1 --name bbox1 -tid busybox 查看 bbox1 的网络配置。
Calico 是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来。与 VxLAN 不同的是,Calico 不对数据包做额外封装,不需要 NAT 和端口映射,扩展性和性能都很好。
上一节我们学习了 Weave 网络内部如何通信,今天讨论 Weave 如何与外界通信。 weave 是一个私有的 VxLAN 网络,默认与外部网络隔离。外部网络如何才能访问到 weave 中的容器呢? 答案是: 首先将主机加入到 weave 网络。
上一节我们分析了 Weave 的网络结构,今天讨论 Weave 的连通和隔离特性。 首先在host2 执行如下命令: weave launch 192.168.56.104 这里必须指定 host1 的 IP 192.168.56.104,这样 host1 和 host2 才能加入到同一个 weave 网络。
上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构。在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 -itd busybox 首先执行 eval $(weave env) 很重要,其作用是将后续的 docker 命令发给 weave proxy 处理。
weave 是 Weaveworks 开发的容器网络解决方案。weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来。对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交换机,容器可以直接通信,无需 NAT 和端口映射。
flannel 支持多种 backend,前面我们讨论的是 vxlan,host-gw 是 flannel 的另一个 backend,本节会将前面的 vxlan backend 切换成 host-gw。
上一节我们在 flannel 网络中部署了容器,本节讨论 flannel 的连通和隔离特性。 flannel 网络连通性 测试 bbox1 和 bbxo2 的连通性: bbox1 能够 ping 到位于不同 subnet 的 bbox2,通过 traceroute 分析一下 bbox1 到 bbox2 的路径。
上一节我们安装和配置了 flannel,本节在 Docker 中使用 flannel。 配置 Docker 连接 flannel 编辑 host1 的 Docker 配置文件 /etc/systemd/system/docker.service,设置 --bip 和 --mtu。
上一节我们部署了 etcd,本节安装和配置 flannel。 build flannel flannel 没有现成的执行文件可用,必须自己 build,最可靠的方法是在 Docker 容器中 build。
flannel 是 CoreOS 开发的容器网络解决方案。flannel 为每个 host 分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可以在 host 间路由,容器间无需 NAT 和 port mapping 就可以跨主机通信。
上一节我们创建了两个 macvlan 并部署了容器,网络结构如下: 本节验证 macvlan 之间的连通性。 bbox1 能 ping 通 bbox3,bbox2 能 ping 通 bbox4。
上一节我们创建了 macvlan 并部署了容器,本节详细分析 macvlan 底层网络结构。 macvlan 网络结构分析 macvlan 不依赖 Linux bridge,brctl show 可以确认没有创建新的 bridge。
上一节我们准备好了 macvlan 的实验环境,今天在 host1 和 host2 中创建 macvlan 网络 mac_net1: 注意:在 host2 中也要执行相同的命令。
除了 overlay,docker 还开发了另一个支持跨主机容器网络的 driver:macvlan。 macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。
不同的 overlay 网络是相互隔离的。我们创建第二个 overlay 网络 ov_net2 并运行容器 bbox3。 bbox3 分配到的 IP 是 10.0.1.2,尝试 ping bbox1(10.0.0.2)。
上一节我们在 host1 中运行了容器 bbox1,今天将详细讨论 overlay 网络跨主机通信的原理。 在 host2 中运行容器 bbox2: bbox2 IP 为 10.0.0.3,可以直接 ping bbox1: 可见 overlay 网络中的容器可以直接通信,同时 docker 也实现了 DNS 服务。
上一节我们创建了 overlay 网络 ov_net1,今天将运行一个 busybox 容器并连接到 ov_net1: 查看容器的网络配置: bbox1 有两个网络接口 eth0 和 eth1。
上一节我们搭建好实验环境,配置并运行了consul,今天开始创建 overlay 网络。 在 host1 中创建 overlay 网络 ov_net1: -d overlay 指定 driver 为 overaly。
为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。
前面已经学习了 Docker 的几种网络方案:none、host、bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题。本章的重点则是讨论跨主机容器间通信的方案。
对于 Docker Machine 来说,术语 Machine 就是运行 docker daemon 的主机。“创建 Machine” 指的就是在 host 上安装和部署 docker。先执行 docker-machine ls 查看一下当前的 machine: 如我们所料,当前还没有 machine,接下来我们创建第一个 machine: host1 - 192.168.56.104。
前面我们的实验环境中只有一个 docker host,所有的容器都是运行在这一个 host 上的。但在真正的环境中会有多个 host,容器在这些 host 中启动、运行、停止和销毁,相关容器会通过网络相互通信,无论它们是否位于相同的 host。
Data Volume 中存放的是重要的应用数据,如何管理 volume 对应用至关重要。前面我们主要关注的是 volume 的创建、共享和使用,本节将讨论如何备份、恢复、迁移和销毁 volume。 备份 因为 volume 实际上是 host 文件系统中的目录和文件,所以 volume 的备份实际上是对文件系统的备份。
在上一节的例子中 volume container 的数据归根到底还是在 host 里,有没有办法将数据完全放到 volume container 中,同时又能与其他容器共享呢? 当然可以,通常我们称这种容器为 data-packed volume container。
volume container 是专门为其他容器提供 volume 的容器。它提供的卷可以是 bind mount,也可以是 docker managed volume。下面我们创建一个 volume container: 我们将容器命名为 vc_data(vc 是 volume container 的缩写)。
数据共享是 volume 的关键特性,本节我们详细讨论通过 volume 如何在容器与 host 之间,容器与容器之间共享数据。 容器与 host 共享数据 我们有两种类型的 data volume,它们均可实现在容器与 host 之间共享数据,但方式有所区别。
docker managed volume 与 bind mount 在使用上的最大区别是不需要指定 mount 源,指明 mount point 就行了。还是以 httpd 容器为例: 我们通过 -v 告诉 docker 需要一个 data volume,并将其 mount 到 /usr/local/apache2/htdocs。
storage driver 和 data volume 是容器存放数据的两种方式,上一节我们学习了 storage driver,本节开始讨论 Data Volume。 Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。
我们从本章开始讨论 Docker 存储。 Docker 为容器提供了两种存放数据的资源: 由 storage driver 管理的镜像层和容器层。 Data Volume。 我们会详细讨论它们的原理和特性。
上节我们学习了容器如何访问外部网络,今天讨论另一个方向:外部网络如何访问到容器? 答案是:端口映射。 docker 可将容器对外提供服务的端口映射到 host 的某个端口,外网通过该端口访问容器。
前面我们已经解决了容器间通信的问题,接下来讨论容器如何与外部世界通信。这里涉及两个方向: 容器访问外部世界 外部世界访问容器 容器访问外部世界 在我们当前的实验环境下,docker host 是可以访问外网的。
容器之间可通过 IP,Docker DNS Server 或 joined 容器三种方式通信。 IP 通信 从上一节的例子可以得出这样一个结论:两个容器要能通信,必须要有属于同一个网络的网卡。 满足这个条件后,容器就可以通过 IP 交互了。
通过前面小节的实践,当前 docker host 的网络拓扑结构如下图所示,今天我们将讨论这几个容器之间的连通性。 两个 busybox 容器都挂在 my_net2 上,应该能够互通,我们验证一下: 可见同一网络中的容器、网关之间都是可以通信的。
除了 none, host, bridge 这三个自动创建的网络,用户也可以根据业务需要创建 user-defined 网络。 Docker 提供三种 user-defined 网络驱动:bridge, overlay 和 macvlan。
上一节我们讨论了 none 和 host 类型的容器网络,本节学习应用最广泛也是默认的 bridge 网络。 Docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。
本章开始讨论 Docker 网络。 我们会首先学习 Docker 提供的几种原生网络,以及如何创建自定义网络。然后探讨容器之间如何通信,以及容器与外界如何交互。 Docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络,本章重点讨论前一种。
为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术。cgroup 和 namespace 是最重要的两种技术。cgroup 实现资源限额, namespace 实现资源隔离。 cgroup cgroup 全称 Control Group。
前面学习了如何限制容器对内存和CPU的使用,本节我们来看 Block IO。 Block IO 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽,下面分别讨论。