docker1
一、docker 简介
1.1 docker的组成
官网:https://docs.docker.com/engine/docker-overview/
docker主机(host):一个物理机或虚拟机,用于运行docker服务进程和容器
docker服务端(server):docker守护进程,运行docker容器。
docker客户端(client):客户端使用docker命令或其他工具调用dockerAPI
docker仓库(Registry):保存镜像的仓库,类似于git或svn这样的版本控制系统。官方仓库:https://hub.docker.com/
docker镜像(images):镜像可以理解为创建实例使用的模板
docker容器(container):容器是从镜像生成对外提供服务的一个或一组服务
1.2:docker对比虚拟机
1、资源利用率更高:一 台物理机可以运行数百个容器,但是般只能运行数十个虚拟机 。
2、开销更小:不需要启动单独的 虚拟机 占用硬件资源。
3、启动速度更快:可以在数秒内完成启动
1.3:docker的底层隔离实现技术
1.3.1:Linux Namespace
namespace 是 Linux系统的底层概念,系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内 ,各个docker容器运行在同一个docker 主进程并且共用同一个宿主机系统内核 ,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间 ,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络进程等,目前主要通过以下技术实现容器运行空间的相互隔离:
目前Linux中提供了六类系统资源的隔离机制,分别是:
Mount
: 隔离文件系统挂载点。Mount Namespace
用来隔离文件系统的挂载点,不同Mount Namespace
的进程拥有不同的挂载点,同时也拥有了不同的文件系统视图。
宿主机是使用了chroot技术把容器锁定到一个指的运行目录里面。例如上图中:/var/lib/containerd/io.containerd.runtime.v1.linux/moby/容器ID
UTS
: 隔离主机名和域名信息。由于主机名和域名可以用来代替IP地址,如果没有这一层隔离,同一主机上不同的容器的网络访问就可能出问题。UTS Namespace
提供了主机名和域名的隔离,也就是struct utsname
里的nodename
和domainname
两个字段。不同Namespace
中可以拥有独立的主机名和域名。
默认容器ID,一般不建议去改,容器访问不是通过主机名访问,不利于横向扩展。
IPC
: 隔离进程间通信。IPC Namespace
是对不同容器跨容器进程间通信的隔离,进程间通信常见的方法有信号量、消息队列和共享内存。IPC Namespace
要达到的目标是相同的标识符在不同的Namepspace
中代表不同的通信介质(比如信号量、消息队列和共享内存)。
PID
: 隔离进程的ID。PID Namespace
对进程PID重新标号,即不同的Namespace
下的进程可以有同一个PID。新创建的PID Namespace
中的第一个进程PID为1,成为新Namespace的systemd
进程。一个 容器内的进程间通信 ,允许 一个 容器内的不同进程 的(内存 、缓存等 )数据访 问,但是不能夸容器访问其他 容器的数据 。
容器内核版本高于宿主机内核版本,容器内的命令照样可以运行,因为是基于二进制文件,只要cpu可以解析二进制文件即可,另外官方也有考虑。
Network
: 隔离网络资源。不同Namespace种可以拥有独立的网络资源,包括网络设备(网卡、网桥)、IPV4或IPV6协议栈、路由表、防火墙、端口等信息。如果需要打通不同Namespace
的通信,可以通过创建vnet pair
虚拟网络设备对的形式。
容器内网卡显示
宿主机网卡信息
网桥信息
开启:net.ipv4.ip_forward = 1跨网段
iptables
网络拓扑图:
User
: 隔离用户和用户组的ID。·一个普通进程(Namespace外面的用户ID非0)在Namespace里面的用户和用户组ID可以为0,换句话说这个普通进程在Namespace里面可以拥有root特权的权限。
涉及到Namespace
的操作接口包括clone()
、setns()
、unshare()
以及还有/proc
下的部分文件。可以通过clone
系统调用来创建一个独立Namespace
的进程,setns()
函数可以把进程加入到指定的Namespace
中,unshare()
系统调用用于将当前进程和所在的Namespace
分离,并加入到一个新的Namespace
中,相对于setns()
系统调用来说,unshare()
不用关联之前存在的Namespace
,只需要指定需要分离的Namespace
就行,该调用会自动创建一个新的Namespace
。通过/proc文件查看进程所属的namespace。
1.3.2:Linux control groups
Cgroups全称Control Groups,是Linux内核提供的物理资源隔离机制,通过这种机制,可以实现对Linux进程或者进程组的资源限制、隔离和统计功能。它最主要的作用, 就是限制一个进程组能够使用的资源上,包括 CPUCPU 、内存磁盘网络带宽等。此外,还能够对进程行优先级设置以及将挂起和恢复操作
groups中内存模块:
查看系统cgroups:
root@ubuntu:~# ll /sys/fs/cgroup/ total 0 drwxr-xr-x 15 root root 380 Feb 15 11:06 ./ drwxr-xr-x 10 root root 0 Feb 15 11:06 ../ dr-xr-xr-x 5 root root 0 Feb 15 11:06 blkio/ #块设备IO限制 lrwxrwxrwx 1 root root 11 Feb 15 11:06 cpu -> cpu,cpuacct/ #使用调度程序为 cgroup任务提供cpu的访问 lrwxrwxrwx 1 root root 11 Feb 15 11:06 cpuacct -> cpu,cpuacct/ #产生cgroup任务的cpu资源报告 dr-xr-xr-x 5 root root 0 Feb 15 11:06 cpu,cpuacct/ dr-xr-xr-x 3 root root 0 Feb 15 11:06 cpuset/ #如果是多核心的cpu,这个子系统会为cgroup任务分配单独的任务分配单独的cpu和内存。 dr-xr-xr-x 5 root root 0 Feb 15 11:06 devices/ #允许或拒绝cgroup任务对设备的访问 dr-xr-xr-x 3 root root 0 Feb 15 11:06 freezer/ #暂停和恢复cgroup任务 dr-xr-xr-x 3 root root 0 Feb 15 11:06 hugetlb/ dr-xr-xr-x 5 root root 0 Feb 15 11:06 memory/ #设置每个cgroup的内存限制以及产生资源报告 lrwxrwxrwx 1 root root 16 Feb 15 11:06 net_cls -> net_cls,net_prio/ #标记每个网络包以供cgroup方便使用 dr-xr-xr-x 3 root root 0 Feb 15 11:06 net_cls,net_prio/ lrwxrwxrwx 1 root root 16 Feb 15 11:06 net_prio -> net_cls,net_prio/ dr-xr-xr-x 3 root root 0 Feb 15 11:06 perf_event/ #增加了对每group的 、监测跟踪能力,可以属于某个特定的group的所有线程以及运行在特定CPU上的线程 dr-xr-xr-x 5 root root 0 Feb 15 11:06 pids/ dr-xr-xr-x 2 root root 0 Feb 15 11:06 rdma/ dr-xr-xr-x 6 root root 0 Feb 15 11:06 systemd/ dr-xr-xr-x 5 root root 0 Feb 15 11:06 unified/
1.4:容器管理工具
1.4.1:docker
Docker启动一个容器也需要一个外部模板但是较多镜像, docker的镜像可以 保 存在一 个公共的地方享使用, 只要 把镜像下载来就可以使用 ,最主要的是可以在镜像基础之上做自定义配置 并且 可以 再把其提交 为一个镜像 ,可以被 启动 为多个容器。
Docker的镜像是分层,镜像底层为库文件且只读层即不能写入也不能删除数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到容器目录 ,但是容器内的数据在删除后也会被随之删除。
容器内文件显示:
宿主机文件显示:
1.4.2:pouch
https://www.infoq.cn/article/alibaba-pouch
https://github.com/alibaba/pouch
1.5:docker(容器)的核心技术
容器 runtime:
runtime是真正运行容器的地方,因此为了运行不同的容器runtime需要和操作系统内核紧密合相互在支持 ,以便为容器提供相应的运行环境 。
目前主流的三种 runtime:
Lxc:linux上早期的runtime ,Docker早期 就是采用 lxc作为runtime。
runc :目前 Docker默认的runtime 。
rkt:是 CoreOS开发的容器runtime,也符合OCI规范,所以使用rktruntime也可以运行 Docker容器
容器管理工具:管理工具连接 runtime与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给runtime 执行 。
Runc的管理工具是 docker engine,docker engine包含后台deamon和cli两部分,大家经常提到的 Docker就是指的docker engine。
容器定义工具:容器定义工具允许用户容器的属性和内容,以方便容器能够被保存、共享和重建 。
Docker image :是docker容器 的模板, runtime依据 docker image创建容器。
Dockerfile :包含 N个命令的文本文件,通过 dockerfile创建出 docker image。
Registry:统一 保存镜像而且是多个不同镜像版的地方叫做镜像仓库 。
Docker hub:docker官方的公共仓库 ,已经保存了大量的常用镜像,可以方便大家直接使用。
Harbor:vmware提供的自带 web界面自带认证功能的镜像仓库,目前的镜像仓库,目前有很多公司在使用。
编排工具:
Kubernetes:google领导开发的容器编排引擎 ,内部项目为Borg,且其同时支持 docker和 CoreOS。