🐒Docker基础入门
Last updated
Last updated
Docker是什么
Docker是基于Linux内核实现,最早是采用了 LXC技术,后来Docker自己研发了runc技术运行容器。
它基于Google Go语言实现,采用客户端/服务端架构,使用API来管理和创建容器。
虚拟机 VS Docker
Namespace
内核命名空间属于容器非常核心的一部分,能够将操作系统进行拆分,使一个系统看起来像多个互相独立的操作系统一样。
Docker容器是由各种命名空间组合而成的,本质就是命名空间
每个容器都由自己的PID、NET、MNT、IPC、UTS构成。
主要通过以下技术实现容器运行空间的相互隔离:
隔离类型
功能
系统调用参数
内核版本
MNT Namespace
提供磁盘挂载点和文件系统的隔离能力
CLONE_NEWNS
2.4.19
IPC Namespace
提供进程间通信的隔离能力,信号量、消息队列和共享内存
CLONE_NEWIPC
2.6.19
UTS Namespace
提供主机名隔离能力
CLONE_NEWUTS
2.6.19
PID Namespace
提供进程隔离能力
CLONE_NEWPID
2.6.24
Net Namespace
提供网络隔离能力,包括网络设备,端口栈,端口等
CLONE_NEWNET
2.6.29
User Namespace
提供用户隔离能力
CLONE_NEWUSER
3.8
安装Docker
容器创建过程
当执行如上命令时,Docker Client会将其转换为合适的API格式,并发送到的API端点。
daemon接收到创建容器的命令,会向containerd发出调用。
虽然名字叫containerd但是它不负责创建新容器,而是指挥runc去做。
containerd将Docker镜像转换为OCI bundle,并让runc基于此创建一个新的容器。
daemon使用一种CRUD风格的API,通过GRPC与containerd进行通信。
(gRPC是google开发的一款高性能,开源和通用的RPC框架)
然后runc与操作系统内核接口进行通信,基于所必要的工具(Namespace、CGroup等)来创建容器。
容器进程作为runc的子进程启动,启动完后runc将会退出。
shim是实现daemon的容器
containerd指挥runc创建新容器,实际上创建容器时都会fork一个新的runc实例。
一旦容器进程的父进程runc退出,相关联的containerd-shim就会成为容器的父进程。
shim职责是保持所有STDIN和STDOUT流是开启状态,从而当daemon重启的时候,容器不会因为PIPE的关闭而终止,并且将容器退出状态反馈给daemon。
Docker架构
Docker Client
docker run命令实际调用了Docker API将命令发送到dockerd进而运行。
Docker daemon
守护进程(dockerd)侦听Docker API发来的请求,作为服务端接受来自客户端的请求,主要功能包括镜像管理、镜像构建、REST API、身份验证、安全、核心网络以及编排。
守护进程还可以与其他守护进程通信以及管理Docker服务。
Docker Registry(仓库)
用于存储镜像,而Docker默认配置为在Docker Hub查找镜像
Docker Hub是一个镜像仓库
Harbor由vmware提供带Web界面自带认证功能的镜像私有仓库
Docker Objects
Images(镜像)
运行容器前需要本地存在对应的镜像,如果不存在默认会从Docker Hub镜像仓库下载。
镜像是容器运行时的只读模板,每一个镜像由一系列的层(layers)组成,用文件系统FS来将这些层联合到单独的镜像中,允许独立文件系统中的文件和文件夹被透明覆盖,形成一个单独连贯的文件系统
Containers
容器和文件夹类似,一个容器包含了所有的某个应用运行所需的环境
每一个容器都是从镜像创建的,不同的容器带有额外的可写层。
容器可以运行、开始、停止、移动和删除等操作。
runC
runc是一个轻量级的针对Libcontainer进行了包装的命令行交互工具,取代了早期Docker架构中的LXC。
runc只有一个作用,创建容器。