Docker 是基于 容器技术 实现的,容器技术最开始是基于 Linux Container(简称 LXC)技术实现的,通过内核提供的 Namespace 和 Cgroup 机制,实现了对应用程序的 隔离 以及物理资源的 分配 。
Docker 在容器基础上发展出了一个完善的生态系统,它将容器视为一种打包格式,将应用程序所需的一切,比如依赖库、运行时环境等都集合在了在一起,使得 一次构建,到处运行 。
它将 开发与运维 很好的融合在一起。开发人员可以很轻松的 构建、打包、推送和运行 应用程序。而且还允许我们将容器视为部署单元,以 模块化 的方式发布,降低了系统的运维管理难度。
镜像就像是包含了操作系统的一张光碟,它是一个 模板文件 ,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
另外,镜像是一个 分层 的文件系统,通过一层层的组合,使得我们可以复用这些不同粒度的镜像文件。
容器的发展来源于我们码头的集装箱的思想,一次打包多方部署,简化上线流程。
简单地说,容器就是一个进程+进程的运行环境的简单整体。
容器是镜像的运行实例,我们可以把镜像看成是一个个的构建块,容器根据这些构建块搭建起了一个隔离的,拥有整个包的应用程序。每一个容器都是一个 标准化 单元,确保了在不同机子上也能拥有一致的行为。
Docker 对数据持久化的解决方案,数据不会随着容器结束而丢失,通过将宿主机的某一文件目录挂载到容器里来实现。在 Docker 里提供了三种方法来实现目录的挂载:
容器技术和虚拟机都提供了 环境隔离 的功能。不同的是。容器是运行在操作系统上的一个进程,它和其他应用程序是共享内核的,由 操作系统 提供虚拟化隔离功能;而虚拟机则是完完全全 另 起了个操作系统,将环境隔离的更加彻底。
容器生命周期管理: run、start/stop/restart、kill、rm、pause/unpause
容器操作:ps、inspect、top
镜像仓库:login、pull、push、search
本地镜像管理:images、rmi、tag、build、history
例如,当我们需要运行一个容器时,则可以执行:
使用none模式,Docker容器拥有自己的 Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过 --network=none 来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
--network=none
Docker 在主机上会创建一个 docker0 的网桥,每当有容器要创建时,便会为容器分配一个独立的网卡,然后桥接到虚拟网桥上。这其实是一对虚拟网卡,一端放在容器里,另一端放在 docker0 网桥里。当一端有数据达到时,就会把数据包转发到另一端上,这就实现了网络通信。
bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看。
Docker 在 Linux 的底层技术有:Namespaces(资源隔离)、CGroups (资源限制)、UnionFS (联合文件系统)。其中:
Mount namespaces
Network namespaces
User namespaces
iptable
docker
首先 docker 的网络通信主要分以下几种场景:
因为 docker 的 IP是无法确定的,所以比较麻烦,一般不用。
Docker1.0 开始, docker daemon 实现了一个内嵌的 DNS Server ,使得容器可以直接通过“容器名”通信。
Docker1.0
docker daemon
DNS Server
缺点:只能在 user-defined 网络中使用。
user-defined
joined
joined 容器可以是多个容器共享同一个网络栈,包括网卡以及配置信息。
容器默认能访问外网,使用了 NAT 进行网络地址转换。
NAT
使用端口映射之后,就可以利用主机 ip+端口 经过 docker-proxy 转发,从而访问到跨主机的 docker 容器。
ip+端口
docker-proxy