docker概览

1. docker简介

什么是docker?

Docker的英文翻译是”搬运工“的意思,他搬运的东西就是我们常说的集装箱Container,Container 里面装的是任意类型的App,我们的开发人员可以通过Docker 将App变成一种标准化的、可移植的、自管理的组件,我们可以在任何主流的操作系统中开发、调试和运行。

docker和虚拟机主要的区别:
  1. 虚拟化技术依赖的是物理CPU和内存,是硬件级别的;而我们的Docker是构建在操作系统层面的,利用操作系统的容器化技术,所以Docker同样的可以运行在虚拟机上面。

  2. 传统的虚拟化技术在构建系统的时候非常复杂;而Docker可以通过一个简单的Dockerfile文件来构建整个容器,更重要的是Dockerfile可以手动编写,这样应用开发人员可以通过发布Dockerfile来定义应用的环境和依赖,这样对于持续交付非常有利。

  3. 虚拟机中的系统就是我们常说的操作系统镜像,比较复杂;而Docker比较轻量级,我们可以使用Docker部署一个独立的nginx,就像类似于在虚拟机当中安装一个Redis应用,但是我们用Docker部署的应用是完全隔离的。

  4. 在传统的虚拟化技术是通过快照来保存的;而Docker引用了类似于源码的管理机制,将容器的快照历史版本一一记录下来,切换成本之低。

Docker Engine

Docker Engine是一个C/S架构的应用程序,主要包含下面几个组件

  • 常驻后台进程Dockerd
  • 一个用来和Dockerd交互的REST API Server
  • 命令行CLI接口,通过和REST API进行交互

在这里插入图片描述

docker架构

Docker使用了C/S体系架构,Docker客户端与Docker守护进程(服务端)通信,Docker守护进程负责构建,运行和分发Docker容器。Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。

在这里插入图片描述

  • Docker Daemon:用来监听Docker API的请求和管理Docker对象,比如镜像、容器、网络和Volume

  • Docker Client: docker client是我们和Docker进行交互的最主要的方式方法,比如可以通过docker run来运行一个容器,然后我们的这个client会把命令发送给上面的Docker

  • Docker Registry: 用来存储Docker镜像的仓库,Docker Hub是Docker官方提供的一个公共仓库,而且Docker默认也是从Docker Hub上查找镜像的,当然你也可以很方便的运行一个私有仓库,当我们使用docker pull或者docker run命令时,就会从我们配置的Docker镜像仓库中去拉取镜像,使用docker push命令时,会将我们构建的镜像推送到对应的镜像仓库中

  • Images 镜像:镜像是一个制度模板,带有Docker容器的说明,一般来说的,镜像会基于另外的一些基础镜像上面安装一个Nginx服务器,这样就可以构建一个属于我们自己的镜像了

  • Containers 容器:容器是一个镜像的可运行的实例,可以使用Docker REST API或者CLI来操作容器,容器的实质是进程,但与直接在宿主执行的实例进程不同,容器进程属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间、甚至自己的用户ID。容器内的经常是运行在一个隔离的环境里,使用起来,就好像在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全

2. 容器技术原理

Namespace

Namespace 是 Linux 内核的一项功能,该功能对内核资源进行隔离,使得容器中的进程都可以在单独的命名空间中运行,并且只可以访问当前容器命名空间的资源。Namespace 可以隔离进程 ID、主机名、用户 ID、文件名、网络访问和进程间通信等相关资源。

Docker 主要用到以下五种命名空间。

  • pid namespace:用于隔离进程 ID。

  • net namespace:隔离网络接口,在虚拟的 net namespace 内用户可以拥有自己独立的 IP、路由、端口等。

  • mnt namespace:文件系统挂载点隔离。

  • ipc namespace:信号量,消息队列和共享内存的隔离。

  • uts namespace:主机名和域名的隔离。

在这里插入图片描述

Cgroups

Docker容器使用Linux namespace来隔离其运行环境,使得容器中的进程看起来就像在一个独立的环境中运行。但是光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存等。关于其目的,是为了防止它占用了太多的资源而影响到其它进程;另一方面,在系统资源耗尽的时候,Linux内核会触发OOM (out of memory killer,OOM会在系统内存耗尽的情况下跳出来,选择性的干掉一些进程以求释放一些内存)这会让一些被杀掉的进程成了无辜的替死鬼,因此为了让容器中的进程更加可控,Docker使用Linux cgroups来限制容器中的进程允许使用的系统资源

Linux Cgroup可以让系统中所运行任务(进程)的用户定义组分配资源—比如CPU时间、系统内存、网络带宽

Docker UnionFS
  • UnionFS顾名思义,可以把文件系统上多个目录(分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。
  • 联合文件系统,又叫 UnionFS,是一种通过创建文件层进程操作的文件系统,因此,联合文件系统非常轻快。Docker 使用联合文件系统为容器提供构建层,使得容器可以实现写时复制以及镜像的分层构建和存储。常用的联合文件系统有 AUFS、Overlay 和 Devicemapper 等。

要理解unionFS,我们首先需要先了解bootfs和rootfs

  1. boot file system (bootfs) 包含操作系统boot loader和kernel。用户不会修改这个文件系统,一旦启动成功后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放内存。同样的内核版本不同Linux发行版,其bootfs都是一直的
  2. root file system (rootfs) 包含典型的目录结构(/dev/,/proc,/bin,/etc,/lib,/usr,/tmp)

Linux系统在启动时,rootfs首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了

假设Dockerfile内容如下

FROM ubuntu:14.04
ADD run.sh /
VOLUME /data
CMD ["./run.sh"]

联合文件系统对应的层次结构如下图所示
在这里插入图片描述

  • 图中的顶上两层,是Docker为Docker容器新建的内容,而这两层属于容器范畴。这两层分别为Docker容器的初始层(init Layer)与可读写层(Read-write Layer)

  • 初始层: 大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。

  • 读写层: Docker容器内的进程只对可读可写层拥有写权限,其它层进程而言都是只读的(Read-Only)。关于VOLUME以及容器的host、hostname、resolv.conf文件都会挂载到这里

  • FROM ubuntu:14.04 设置基础镜像,此时会使用Ubuntu:14.04作为基础镜像

  • ADD run.sh / 将Dockerfile所在目录下的run.sh加至镜像的根目录,此时新一层的镜像只有一项内容,即根目录下的run.sh

  • VOLUME /data 设置镜像的存储,此VOLUME在容器内部的路径为/data。此时并未在新一层的镜像中添加任何文件,但是更新了镜像的json文件,以便通过此镜像启动容器时获取这方面的信息

  • CMD [“./run.sh”] 设置镜像的默认执行入口,此命令同样不会在新建镜像中添加任何文件,仅仅在上一层镜像json文件的基础上更新新的镜像的json文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值