Docker
-
基于Linux内核的
Cgroup,Namespace,以及Union FS等技术,对进程进行封装和隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其他的隔离的进程,因此也成为容器。 -
最初实现时基于LXC,从0.7以后开始去除LXC,转而使用自行开发的
Libcontainer,从1.11开始。则进一步演进为使用runC和Containerd -
Docker在容器的基础上,进行了进一步的封装,从文件系统、网路互联到进程隔离等等,极大的简化了容器的创建和维护,使得Docker技术比虚拟技术更为轻便、快捷
应用的增量相比于项目是非常小的,应用容器出现之前文件是怎么分发的?
进行源代码编译,
- 要有一个
FileSever - 每个机器上要用一个
agent,agent接受远程的指令 - 重启
没有一个标准,统一做个事情,有了docker以后,分发的是一个运行环境,运行环境里有分层的机制,保证只要这个镜像你之前拉过,很多层会被不同的层reuse的,最大程度达到一个复用的目的,拉取镜像的时候只拉取动态的部分
容器的标准
Open Container Initiative(OCI) : 轻量级开放式管理组织(项目)
OCI主要定义两个规范
Runtime Specification- 文件系统包括如何解压到硬盘,共运行时运行。
Image Specification- 如何通过构建系统打包,生成镜像清单(Manifest)、文件系统序列化文件、镜像配置。
容器的主要特征
- 安全性
- 隔离性(Namespace)
- 便携性
- 可配额 (cgroup)
这四个之间的特性是什么?
Namespace
Namespace 的类型
[Namespace类型]{https://man7.org/linux/man-pages/man7/namespaces.7.html}
| Namespace | Flag | Page | Isolates |
|---|---|---|---|
| Cgroup | CLONE_NEWCGROUP | cgroup_namespaces(7) | Cgroup root directory |
| IPC | CLONE_NEWIPC | ipc_namespaces(7) | System V IPC,POSIX message queues |
| Cgroup | CLONE_NEWCGROUP | cgroup_namespaces(7) | Cgroup root directory |
Linux Namespace是一种Linux Kenel提供资源隔离的方案
- 系统可以为进程分配不同的Namespace
- 并保证不同的Namespace资源独立分配、进程彼此隔离,即不同Namespace下的进程互不干扰
Linux内核代码中Namespace的实现
- 进程数据结构
- Namespace数据结构
// 进程数据结构
struct task_struct {
...
/* namespaces*/
struct nsproxy *nsproxy;
}
// Namespace数据结构
struct nsproxy {
atomic_t count;
struct uts_namespace *uts_s;
struct ipc_namespace *ipc_ns;
struct mnt_namespace *mnt_ns;
struct pid_namespace *pid_ns_for_children;
struct net *net_ns;
}
Linux对Namespace 操作方法
- clone
在创建新进程的系统调用时,可以通过flags参数指定需要新建的Namespace类型
Systemd会有一个Namespace,不同的Namespace彼此之间是隔离的,
所谓容器它没有虚拟化层,它没有从操作系统做的隔离,任何的进程都是主机上开辟的进程
Docker在做出让步,不得不去接OCI的标准,本身是内嵌Containerd的
容器是一个通用称呼,Docker是容器的一种,基于容器技术实现的方案,但是Docker本身把容器带火了
,提起Docker就会认为是容器
Pid namespacenet namespaceipc namespace
A服务去调用B,B是需要有一个网路地址的,
- 当前系统的namespace
lsns
lsns -t <type>
-
当前某些进程的namespace:
ls -la /proc/<pid>/ns/ -
进入某namespace运行命令:
nsenter -t <pid> -n ip addr
nsenter
-n : 指定网络
namespace的练习
namespace只是struct中一个属性
namespace是不可以嵌套的,namespace是一个隔离环境
Cgroups
当需要搭建一个虚拟机的时候,需要进行资源管控,多少cpu。多少memory
一个进程要启动,需要指定多少cpu,多少memory,这些都是要进行限制死的,这个技术就是Cgroups
- Cgroups(Control Groups)是Linux下用于对一个或一组进程进行资源管控和监控的机制;
- 可以对诸如CPU使用时间、内存、磁盘I/O等进程所需的资源进行限制;
- 不同资源的具体管理工作由相应的Ggroup子系统(Subsystem)来实现;
- 针对不同类型的资源控制,只要将限制策略在不同的子系统上进行关联即可;
- Cgroups在不同的系统资源管理子系统中以层级树(Hierarchy)的方式来组织管理:每个Cgroup都可以包含其他的子Group,因此子Cgroup能使用的资源除了受本Cgroup配置的参数限制,还受到父Cgroup设置的资源限制。
对于一个进程要想实现资源的可配额,最重要的是CPU、Memory、IO等等,所以Cgroups会有不同的子系统
cgroups实现了对资源的配额和度量
blkio:cpu:cpuacct:cpuset:devices:
上下游的依和网络都在一个隔离的环境
docker核心技术
Docker的文件系统
典型的Linux文件系统组成
-
Bootfs (boot file system)
- Bootloader - 引导加载kernel
- Kernel - 当kernel被加载到内存中后umount bootfs
-
rootfs (root file system)
- /dev, /proc, /bin, /etc等标准目录和文件
- 对于不同的Linux发行版,bootfs基本是一致的,但rootfs会有差别
Docker启动
Linux
- 在启动后,首先将rootfs设置为readonly,进行一系列检查,然后将其切换为"readwrite"供用户使用。
Docker启动
- 初始化时也是将rootfs以readonly方式加载并检查,然而接下来利用union mount的方式将一个readwrite文件系统挂载在readonly的rootfs之上
- 并且允许再次将下层的FS(file system)设定为readonly并且向上叠加
- 这样一组readonly和一个writeable的结构构成一个container的运行时态,每一个FS被称作一个FS层
对于Docker进程它是没有bootfs的,但每一个进程需要看到自己的文件系统,所以它有自己rootfs系统,复用主机的kernel,rootfs以容器驱动加载出来,被它的进程所拥有,这个进程看到的就是这个docker的rootfs
容器存储驱动
以OverlayFS为例
OverlayFS也是一种与AUFS类似的联合文件系统,同样属于文件级的存储驱动,包含了最初的Overlay和更新更稳定的overlay2
Overlay只有两层:uppper层和lower层,Lower层代表镜像层,upper层代表容器可写层
upper层和lower层会合并成一个合并层,用mount指定两个层级
每一个容器进程都会有一个自己的mntnamespace, 这个mntnamespace的mountnamespace,这个容器文件系统看到的是和主机的系统文件是不一样的,是隔离的一个空间
容器本身是在主机上启动的一个进程,这个进程与其他的进程没有其他的差异,有了一个mntnamespace就不会对主机的文件系统有依赖 ,当有同名文件的时候以上层文件为主
将containerd替换docker,目前docker也基于containerd实现了进程的管理
containerd--> shim --> runc
docker shim的父进程就是systemd
在独立pidnamespace里边
OverlayFS文件系统是怎么隔离的?
docker inspect是如何mount文件的
–
网络
网络有独立的netnamespace,
- Null
- Host
- Container
- Bridge(–net=bridge)
Null
- 把容器放入独立的网络空间但不做任何网络配置;
- 用户需要通过运行
docker network命令来完成网配置
Host
- 使用主机网络名空间,复用主机网络
Container
- 重用其他容器的网络
Bridge(–net=bridge)
- 使用Linux网桥和iptables提供容器互联,Docker在每台主机上创建一个名叫docker0的网桥,通过
veth pair来连接该主机的每一个EndPoint.

6133

被折叠的 条评论
为什么被折叠?



