深入理解Docker(入门)
相关概念都说入门从黑话开始,我们先简单了解一下几个Docker周边听不懂的基本概念Runtime所谓运行时就是代码跑起来了,被装载到内存中去了OCIOpen Container InitiativerunCkubernetes本质容器的本质就是一个进程;与虚拟机的区别在于,每个虚拟机都有独立的操作系统内核Guest OS,而容器时一种特殊的进程,共享一个操作系统内核。Linux Namespace
相关概念
都说入门从黑话开始,我们先简单了解一下几个Docker周边的基本概念
Runtime
从生命周期的角度来说,所谓运行时就是代码跑起来了,被装载到内存中去了(相较于编译时有个区别)
从运行依赖的角度来说,运行时是一个程序在运行或是执行时的依赖,包括运行时库的依赖和运行时系统的依赖
现在回到Docker,对于Docker,运行时就是代表容器从拉取镜像到启动运行再到中止的整个生命周期。
OCI
Open Container Initiative
一个标准的容器运行时,需要文件系统,也就是镜像。这个容器标准包的定义仅仅考虑如何把容器和他的配置数据存储到磁盘上,以便运行时读取。OCI包括两种规范:
- 运行时规范
- 镜像规范
runC
runC是OCI的一种实现参考,是轻量级的容器运行引擎,包括所有Docker使用的和容器相关的系统调用代码。除此之外还有各种运行时工具和库,如rkt、containerd、cri-o。他们功能不尽相同,比如runc、LXC只有运行容器,containerd、cri-o还可以对镜像进行管理
containerd
原来Docker包含containerd,containerd专注于运行时的容器管理
containerd并不是直接面向最终用户的,主要是用于集成到更上层的系统中,比如Swarm、Kubernetes、Mesos等容器编排系统。containerd以daemon的形式运行在系统上,通过unix domain socket暴露最底层的gRPC API,上层系统可以通过这些API管理机器上的容器。每个containerd只负责一台机器,Pull镜像、对容器的操作(启动、停止等)、网络、存储都是由containerd完成的。具体运行容器时由runC负责,实际上只要符合OCI规范的容器都可以支持。
从技术栈上看,containerd比runC的层次更高,containerd可以使用runC启动容器,还可以下载镜像,管理网络。
CRI
Container Runtime Interface
CRI中定义了容器和镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务,该接口使用Protocol Buffer,基于gRPC。
两个服务:
-
ImageService:从镜像仓库拉取镜像、删除镜像、查询镜像信息的RPC调用功能
-
RuntimeService:提供容器的相关生命周期(容器创建、修改、销毁等)及容器的交互操作(exec/attach/port-forward)
kubernetes
是一种容器编排的工具,与Docker三剑客之一docker swarm类似。
本质
了解完基本基本概念,在详细介绍之前,简单的介绍一下Docker的本质
容器的本质就是一个进程;与虚拟机的区别在于,每个虚拟机都有独立的操作系统内核Guest OS,而容器是一种特殊的进程,共享一个操作系统内核,所以也可以理解为系统级虚拟化。
-
Linux Namespace对其进行资源隔离,看不到外面的世界;
-
Cgroups为其实现资源限制,最多能用多少资源;
-
pivot_root、chroot切换了进程的根目录,将容器镜像挂载为根文件系统rootfs
-
rootfs打包了应用运行的完整环境:要运行的App+应用的所有依赖库+操作系统的目录和文件
-
-
exec进入容器交互界面:是利用系统调用setns,让当前进程进入容器的Namespace中,这样就能看到容器内部的情况
形象一点怎么解释呢?租过房子的朋友可能知道隔板房,可以将容器理解为这么一个场景。每个房间类似一个容器,共享洗手间、厨房等系统资源,同在一个户室的系统内核之上。石浆板充当了Linux Namespace的功能,将你与其他租户隔开;同时它也和每个房间内的独立电表共同充当了Cgroups的角色,对电、空间等资源进行了量的限制。
但是从安全的角度来说,这种共享机制虽然带来了便捷,也更为轻量,但是同时隔离不完全也带来了潜在的容器逃逸和资源拒绝服务等风险。
更多推荐
所有评论(0)