目录
Docker镜像 (镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包)
Docker Compose 初识 (python工具)--> 一个声明式的配置文件YAML描述
容器为什么出现
容器的作用
容器的应用场景
虚拟机的不足: OS的认证,OS占用额外的CPU、RAM和存储,启动较慢并且可移植性较差
容器的运行不会独占操作系统。实际上,运行在相同宿主机上的容器是共享一个操作系统的,这样就能够节省大量的系统资源。容器同时还能节省大量花费在许可证上的开销,以及为OS打补丁等运维成本。
对容器发展影响比较大的技术包括内核命名空间(Kernel Namespace)、控制组(Control Group)、联合文件系统(Union File System),当然更少不了Docker。
容器技术很早就有了,只是Docker的出现让大众所接受
运行中的容器共享宿主机的内核。这意味着一个基于Windows的容器化应用在Linux主机上是无法运行的。但现在已经成为可能。
Kubernetes: Kubernetes是保证容器部署和运行的软件体系中很重要的一部分
CRI能够帮助Kubernetes实现将运行时环境从Docker快速替换为其他容器运行时
Docker用于创建、管理和编排容器。 -- 旧金山
Docker引擎是用于运行和编排容器的基础设施工具。
GitHub上的docker/docker库也被转移到了moby/moby,并且拥有了项目自己的Logo。Logo
Moby项目的目标是基于开源的方式,发展成为Docker上游,并将Docker拆分为更多的模块化组件。
许多Docker内置的组件都可以替换为第三方的组件。良性的竞争是创新之母
OCI是一个旨在对容器基础架构中的基础组件进行标准化的管理委员会。
Docker的安装目前很方便,此处不进行笔记记录。
Docker的更新大致步骤如下:
需要重视升级操作的每个前置条件,包括确保容器配置了正确的重启策略;在Swarm Mode模式下使用服务时,需要确保正确配置了draining node。当完成了上述前置条件的检查之后,可以通过如下步骤完成升级操作。
(1)停止Docker守护程序。
(2)移除旧版本Docker。
(3)安装新版本Docker。
(4)配置新版本的Docker为开机自启动。
(5)确保容器重启成功。
Docker在Linux底层支持几种不同的存储驱动的具体实现,每一种实现方式都采用不同方法实现了镜像层和写时复制。虽然底层实现的差异不影响用户与Docker之间的交互,但是对Docker的性能和稳定性至关重要。
注意: 如果读者修改了正在运行Docker主机的存储引擎类型,则现有的镜像和容器在重启之后将不可用,这是因为每种存储驱动在主机上存储镜像层的位置是不同的。切换到原来的存储驱动,之前的镜像和容器就可以继续使用了。
如果读者希望在切换存储引擎之后还能够继续使用之前的镜像和容器,需要将镜像保存为Docker格式,上传到某个镜像仓库,修改本地Docker存储引擎并重启,之后从镜像仓库将镜像拉取到本地,最后重启容器。
Docker存储驱动的选择
在Linux上,Docker可选择的一些存储驱动包括AUFS(最原始也是最老的)、Overlay2(*)、Device Mapper、Btrfs和ZFS。
Device Mapper配置: 为了达到Device Mapper在生产环境中的最佳性能,需要将底层实现修改为direct-lvm模式。这种模式下通过使用基于裸块设备(Raw Block Device)的LVM精简池(LVM thin pool)来获取更好的性能。
运维视角: 下载镜像、运行新的容器、登录新容器、在容器内运行命令,以及销毁容器
开发视角: Dockerfile,将应用容器化,并在容器中运行它们
通过docker version 来确认客户端和服务端是否都已经成功运行,并且可以互相通信
镜像: 将Docker镜像理解为一个包含了OS文件系统和应用的对象会很有帮助
在Docker主机上运行docker image ls命令
docker container run 来启动容器
-it 参数会将Shell切换到容器终端。
按Ctrl-PQ组合键,可以在退出容器的同时还保持容器运行。这样Shell就会返回到Docker主机终端。可以通过查看Shell提示符来确认。 (依次按P 然后按Q键)
docker container exec 重新进入容器内部
使用stop和rm , 分别停止和移除已建立的容器
docker ps -a 和 docker container ls -a 应该是等价的,列出所有的容器包括未运行的
开发---- Dockerfile 并将其容器化
基于Dockerfile构建新的镜像
如果自动拉取有问题,可以手动先执行docker pull 下来基础的镜像
Docker引擎
基于开放容器计划(OCI)相关标准的要求,Docker引擎采用了模块化的设计原则,其组件是可替换的。
总体逻辑的组成
Docker首次发布时,Docker引擎由两个核心组件构成:LXC和Docker daemon。
Docker daemon是单一的二进制文件,包含诸如Docker客户端、Docker API、容器运行时、镜像构建等。
LXC提供了对诸如命名空间(Namespace)和控制组(CGroup)等基础工具的操作能力,它们是基于Linux内核的容器虚拟化技术。
早期的Docker架构
Docker公司开发了名为Libcontainer的自研工具,用于替代LXC。Libcontainer的目标是成为与平台无关的工具,可基于不同内核为Docker上层提供必要的容器交互功能。
在Docker 0.9版本中,Libcontainer取代LXC成为默认的执行驱动。
然后进行拆解Docker daemon,将其模块化,目的是小而专的工具可以组装为大型工具。
OCI制定相关的标准。
runc: 是OCI容器运行时规范的参考实现。创建容器,这一点它非常拿手,速度很快。直接下载它或基于源码编译二进制文件,即可拥有一个全功能的runc。但它只是一个基础工具,并不提供类似Docker引擎所拥有的丰富功能。
containerd: Docker引擎技术栈中,containerd位于daemon和runc所在的OCI层之间。Kubernetes也可以通过cri-containerd使用containerd。如今containerd还能够完成一些除容器生命周期管理之外的操作。不过,所有的额外功能都是模块化的、可选的,便于自行选择所需功能。
daemon使用一种CRUD风格的API,通过gRPC与containerd进行通信。
虽然名叫containerd,但是它并不负责创建容器,而是指挥runc去做。整个流程如下所示
在旧模型中,所有容器运行时的逻辑都在daemon中实现,启动和停止daemon会导致宿主机上所有运行中的容器被杀掉。将所有的用于启动、管理容器的逻辑和代码从daemon中移除,意味着容器运行时与Docker daemon是解耦的,有时称之为“无守护进程的容器(daemonless container)。Docker daemon的维护和升级工作不会影响到运行中的容器。
shim组件
shim是实现无daemon的容器不可或缺的工具。
一旦容器进程的父进程runc退出,相关联的containerd-shim进程就会成为容器的父进程。作为容器的父进程
保持所有STDIN和STDOUT流是开启状态,从而当daemon重启的时候,容器不会因为管道(pipe)的关闭而终止。
将容器的退出状态反馈给daemon。
Docker镜像 (镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包)
拉取操作会将镜像下载到本地Docker主机,读者可以使用该镜像启动一个或者多个容器。
镜像与容器的关系
在镜像上启动的容器全部停止之前,镜像是无法被删除的。镜像中还不包含内核——容器都是共享所在Docker主机的内核。容器仅包含必要的操作系统。
Windows镜像要远大于Linux镜像,