docker基础概念
简介
Docker使用客户端-服务器 (C/S) 架构模式,Docker daemon 作为服务端接受来自docker客户端或远程API请求。相比KVM之类最明显的特点就是启动快,资源占用小。
Docker引擎C/S模式
Docker整体架构
综上两个架构图可以理解为client- -> restapi -->docker deamon完成后续镜像和容器操作。
Namespace隔离
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWUTS | 主机名或域名 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
Network | CLONE_NEWNET | 网络、端口等 |
Mount | CLONE_NEWNS | 挂载点(文件系统) |
User | CLONE_NEWUSER | 用户组和用户组 |
- user namespace(默认关闭,开启参考这里)
Cgroup资源限制/优先级
资源限制(Resource Limitation):cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。
优先级分配(Prioritization):通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级。
资源统计(Accounting): cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能非常适用于计费。
进程控制(Control):cgroups可以对进程组执行挂起、恢复等操作。
Docker Image底层实现
- 联合文件系统(union filesystem)是一种分层、轻量级、高性能的文件系统。它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一虚拟文件系统下。
- 写时复制机制(copy on write)对于一个重复资源,若不修改,则无需立刻创建一个新的资源,该资源可以被共享使用。当发生修改的时候,才会创建新资源。这会大大减少对于未修改资源复制的消耗。
- 常见存储驱动及对比
AUFS,overlayFS(基于文件,启动快,效率稍差)
Device Mapper(基于块设备,启动慢,效率高)
对比:
前两种驱动都是基于文件,它的原理就是需要修改一个文件的时候把整个文件复制上去做修改, Device Mapper更偏底层一点,它是基于块设备的,它的好处在于当我想要修改一个文件的时候,我不会将整个文件拷上去,我会将文件修改的一些存储块拷上去做一些修改,当我有一些大文件想要修改的时候,Device Mapper会比AUFS、OverlayFS好很多。所以AUFS和OverlayFS就比较适合传统的WEB应用,它的文件操作不会很多,但是它可能对我们的应用启动速度会有一些要求,比如我可能经常要发布,我希望能够启动比较快,但是对于文件修改的一些效率我不是很关心,那可以使用基于文件的驱动,当我们是一些计算密集型的应用时候,我们就可以选择Device Mapper,虽然启动比较慢,但是它的运行效率相对表现要好一些。
Overlay2支持多个容器访问相同文件时共用page cache(缓存),AUFS的层级多搜索会有延迟
Libcontainer包管理容器
Libcontainer 是Docker中用于容器管理的包,它基于Go语言实现,通过管理namespaces、cgroups、capabilities以及文件系统等进行容器控制。可以使用Libcontainer创建容器,并对容器进行生命周期管理,不需要依赖LXC,提供了跨平台和松耦合能力。
Docker网络解析
- 网络的命名空间:Linux在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命令空间中,彼此间无法通信;docker利用这一特性,实现网络隔离。
- Veth设备对:Veth设备对的引入是为了实现在不同网络命名空间的通信。
- Iptables/Netfilter:Netfilter负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核 模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表;通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。
- 网桥:网桥是一个二层网络设备,通过网桥可以将linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。
- 路由:Linux系统包含一个完整的路由功能,当IP层在处理数据发送或转发的时候,会使用路由表来决定发往哪里。
Docker网络类型
- 单机网络模式:
Bridge :默认桥接模式。
Host:主机网络模式。
Container:连接现有容器,与其共享同一个网络空间,但是文件系统等不共享。
None:不配置网络。 - 多机网络模式:一类是 Docker 在 1.9 版本中引入Libnetwork项目,对跨节点网络的原生支持;一类是通过插件(plugin)方式引入的第三方实现方案,比如 Flannel,Calico 等等。
Dockerfile常用命令
FROM 指定基础镜像
MAINTAINER 指定维护者信息
LABEL 适用于监控系统等获取信息
RUN 在命令前面加上RUN
ADD 会自动解压
COPY 拷贝当前目录文件
WORKDIR 设置家目录,进入容器后所在目录
VOLUME 设置卷,挂载主机目录(文档类)
EXPOSE 指定对外的端口(文档类)
CMD 指定容器启动后要干的事情(推荐)
ENTRYPOINT 没有CMD的可替换特性,也就是你启动容器的时候增加运行的命令不会覆盖ENTRYPOINT指定的命令(不推荐,其使用/bin/sh -c执行命令,不是pid 1的进程,所以无法接受sigterm信号优雅退出)
USER 指定运行容器时的用户名和UID,后续的RUN指令也会使用这里指定的用户
ENV 设置环境变量,可以在RUN之前使用,然后RUN命令时调用,容器启动时这些环境变量都会被指定
Dockerfile优化技巧
1.减少RUN层
2.yum安装或wget源码包安装后删除对应cache和安装包
3.网络传输,如yum源或npm源等
4.尽量把不变的构建过程放上面,使用镜像缓存构建镜像
参考
user namespace隔离:https://www.jianshu.com/p/f2f25ca903d8
namespace api操作参考:https://blog.csdn.net/qq_37133717/article/details/86359947
cgroup参考:https://segmentfault.com/a/1190000016355300
image原理参考:https://baijiahao.baidu.com/s?id=1580774219660492898&wfr=spider&for=pc
docker镜像优化:https://baijiahao.baidu.com/s?id=1580774219660492898&wfr=spider&for=pc