Hello Docker(一)——Docker简介

心已入冬 提交于 2020-10-13 08:38:27

Hello Docker(一)——Docker简介

一、Docker简介

1、Docker简介

Docker是Docker Inc公司开源的一项基于Ubuntu LXC技术构建的应用容器引擎Docker Engine的简称,完全基于Go语言开发并遵守Apache2.0协议开源。Docker可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux版本机器上,也可以实现虚拟化。Docker容器完全使用沙箱机制,容器相互之间不会有任何接口,并且容器性能开销极低。
Hello Docker(一)——Docker简介
Docker最初在Ubuntu 12.04上基于LXC实现,从0.7版本开始使用自行开发的libcontainer,从1.11开始,进一步演进为使用runC和containerd。RedHat从RHEL6.5开始对Docker进行支持。
Docker官网:http://www.docker.com
Github Docker源码:https://github.com/docker/docker



2、Docker Engine

Docker Engine是一个Client-Server应用程序,包含三个组件:
A、docker daemon,是Docker守护进程。
B、REST API接口,用于与守护进程进行通信。
C、Docker CLI,命令行界面(CLI)客户端。
Docker引擎组件的流程如下:
Hello Docker(一)——Docker简介




3、Docker的优点

Docker优点如下:
(1)更高效地利用系统资源
Docker容器不需要硬件虚拟技术支持,是内核级的虚拟化,不需要运行完整操作系统,可以实现更高性能。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,与虚拟机技术相比,相同配置的主机可以运行更多数量的应用。
(2)更快的启动时间
传统的虚拟机技术启动应用服务往往需要数十秒,而Docker容器应用直接运行于宿主机内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间,大大节约开发、测试、部署时间。
(3)一致的运行环境
开发过程中通常存在环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug并未在开发过程中被发现,而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。
(4)快速交付和部署
使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试;而运维人员则可以直接在生产环境中快速部署镜像,甚至结合持续部署(Continuous Delivery/Deployment)系统进行自动部署,而且使用Dockerfile使镜像构建透明化,不仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署镜像。
(5)更轻松的迁移
由于Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在多种平台上运行,无论是物理机、虚拟机、公有云、私有云,其运行结果是一致的。因此用户可以很轻易地将在一个平台上运行的应用迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
(6)更轻松的维护和扩展
Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像非常简单。此外,Docker团队同各个开源项目团队一起维护了大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大降低了应用服务的镜像制作成本。











4、Docker与虚拟机

虚拟机是一个运行在宿主机上的完整的操作系统,虚拟机运行自身操作系统会占用较多的CPU、内存、硬盘资源。Docker容器不同于虚拟机,只包含应用程序以及依赖库,基于libcontainer运行在宿主机上,并处于一个隔离的环境中,因此Docker容器更加轻量高效,启动Docker容器只需几秒钟内完成。由于Docker容器轻量、资源占用少,使得Docker可以轻易地应用到构建标准化的应用中。Docker容器缺点如下:
(1)隔离效果不如虚拟机,需要共享宿主机操作系统的一些基础库等。
(2)网络配置功能相对简单,主要以桥接方式为主。
(3)查看日志也不够方便灵活。
Hello Docker(一)——Docker简介



二、Docker架构

1、Docker架构简介

Docker架构遵循C/S架构,分为客户端、Docker主机、Docker镜像仓库三部分。
客户端(Client):Docker提供命令行界面(CLI)工具,客户端与Docker守护进程交互。当使用docker命令时,客户端将相应Docker命令发送到Docker主机的Docker守护进程进行运行,客户端可以构建、运行和停止应用程序。
Docker主机:包含容器、镜像和Docker守护程序,提供完整的环境来执行和运行应用程序。Docker守护进程是一个用于监听Docker API请求的进程,用于管理Docker对象,如Docker镜像、容器、网络等。
镜像仓库(Registry):Docker镜像仓库用于存储Docker镜像。Docker提供的Docker Hub和Docker Cloud是公共镜像仓库,Docker默认在Docker Hub上查找映像。当使用docker pull或docker run命令时,从配置的Docker镜像仓库中提取所需的镜像;当使用docker push命令时,镜像被推送到配置的镜像仓库中。
Hello Docker(一)——Docker简介



2、Docker镜像

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。Docker镜像不包含任何动态数据,其内容在构建后也不会被改变。
Docker的分层存储架构充分利用了Union FS技术。Docker镜像由一组文件系统或是多层文件系统联合组成。Docker镜像会一层层构建,前一层是后一层的基础,每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己本层。比如,删除前一层文件的操作不是真的删除前一层的文件,而是仅在当前层标记为文件已删除。在Docker容器运行时,虽然不会看到文件,但实际上文件会一直跟随镜像。因此,在构建Docker镜像时需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在本层构建结束前清理掉。
分层存储的特征使得Docker镜像的复用、定制变的更为容易,可以使用构建好的镜像作为基础层,然后进一步添加新层以定制自己所需的内容,构建新镜像。

3、Docker容器

Docker镜像是静态的定义,Docker容器是Docker镜像运行时的实例,Docker容器可以被创建、启动、停止、删除、暂停等。
Docker容器的本质是进程,但与直接在宿主机执行的进程不同,Docker容器进程运行于属于自己的独立的命名空间。因此Docker容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。Docker容器内的进程是运行在一个隔离的环境里,使得容器封装的应用比直接在宿主机运行更加安全。Docker容器使用分层存储,每一个Docker容器运行时,以镜像为基础层,在其上创建一个当前容器的存储层。容器存储层的生存周期和容器一样,容器消亡时容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践要求,Docker容器不应该向其存储层内写入任何数据,Docker容器存储层要保持无状态化,所有的文件写入操作都应该使用数据卷(Volume)、或者绑定宿主机目录,在数据卷或宿主机目录位置的读写会跳过容器存储层,直接对宿主机(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,Docker容器删除或者重新运行后,数据却不会丢失。

4、Docker Registry

Docker默认Registry是Docker公司运营提供的公共镜像仓库即Docker Hub,但访问Docker Hub速度通常很慢,因此可以在本地部署一个私有Registry只供局域网内使用。

三、Docker安装指南

1、Mac平台安装

Homebrew的Cask已经支持Docker for Mac:
Hello Docker(一)——Docker简介
加速器配置使用网易的镜像地址:http://hub-mirror.c.163.com
在任务栏点击Docker for mac应用图标->Perferences... ->Daemon ->Registry mirrors。
在列表中填写加速器地址。修改完成后,点击 Apply & Restart 按钮,Docker就会重启并应用配置的镜像地址。
Hello Docker(一)——Docker简介
通过docker info来查看是否配置成功。





2、Linux平台安装

Docker运行在RHEL7上,要求系统为64位、系统内核版本为3.10以上。
Docker运行在 RHEL6.5 或更高的版本要求系统为64位、系统内核版本为2.6.32-431或者更高版本。
本文使用RHEL7.3安装Docker。
安装Docker:sudo yum install docker
启动Docker:sudo systemctl start docker
错误信息:Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
查看错误信息:systemctl status docker.service
Hello Docker(一)——Docker简介
错误原因:SELinux不支持Docker服务
解决方法:编辑sudo vim /etc/sysconfig/docker








OPTIONS='--selinux-enabled=false --log-driver=journald --signature-verification=false'
if [ -z "${DOCKER_CERT_PATH}" ]; then
    DOCKER_CERT_PATH=/etc/docker
fi

运行示例:sudo docker run hello-world
Hello Docker(一)——Docker简介

3、Windows平台安装

Win7、Win8需要利用Docker Toolbox来安装,国内可以使用阿里云的镜像来下载。
Docker ToolBox下载地址:
http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/
Docker ToolBox是一个工具集,主要包含:
A、Docker CLI客户端,用来运行docker引擎创建镜像和容器
B、Docker Machine,用于在Windows的命令行中运行docker引擎命令
C、Docker Compose,用来运行Docker Compose命令
D、Kitematic,Docker的GUI版本
E、Docker QuickStart shell,配置好Docker的命令行环境
F、Oracle VM Virtualbox,虚拟机
下载完成后直接点击安装,安装成功后,会出现三个图标:
Hello Docker(一)——Docker简介
点击Docker QuickStart图标来启动Docker Toolbox终端。
如果系统显示User Account Control窗口来运行VirtualBox,选择 Yes。
Hello Docker(一)——Docker简介
对于Win10专业版系统,Docker有专门的的安装包,需要开启Hyper-V。
Win10专业版系统Docker下载地址:
https://store.docker.com/editions/community/docker-ce-desktop-windows
















4、Docker镜像加速器安装

Docker使用daemon.json文件作为Docker服务的配置文件,Linux操作系统使用/etc/docker/daemon.json,Windows操作系统使用%programdata%\docker\config\daemon.json来配置Docker服务。如果相应目录下不存在daemon.json文件,需要创建。

{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

网易的镜像地址:http://hub-mirror.c.163.com

四、Docker核心技术

1、隔离性

为了实现每个用户实例之间相互隔离,硬件虚拟化方法的解决方案是VM,而LXC的解决方案是container,即kernel namespace。其中pid、net、ipc、mnt、uts、user等namespace将container的进程、网络、消息、文件系统、UTS(UNIX Time-sharing System)和用户空间隔离开。
(1)pid namespace
不同用户的进程通过pid namespace隔离开,且不同namespace中可以有相同pid。所有的LXC进程在Docker中的父进程为Docker进程,每个LXC进程具有不同的namespace,同时由于允许嵌套,因此可以很方便的实现 Docker in Docker。
(2)net namespace
通过pid namespace,每个namespace中的pid能够相互隔离,但网络端口还共享host的端口。网络隔离是通过net namespace实现的,每个net namespace有独立的network devices、IP addresses、IP routing tables、/proc/net目录。通过net namespace,每个container的网络就能隔离开来。Docker默认采用veth的方式将容器中的虚拟网卡同宿主机上的一个docker bridge:docker0连接在一起。
(3)ipc namespace
container中进程交互采用linux常见的进程间交互方法(interprocess communication - IPC),包括常见的信号量、消息队列和共享内存。然而与VM不同,container的进程间交互还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息——每个IPC 资源有一个唯一的32位 ID。
(4)mnt namespace
mnt namespace允许不同namespace的进程看到的文件结构不同,每个namespace中的进程所看到的文件目录就被隔离开。每个namespace 中的container在/proc/mounts的信息只包含所在namespace的mount point。
(5)uts namespace
UTS(UNIX Time-sharing System)namespace允许每个container拥有独立的hostname和domain name,使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
(6)user namespace
每个container可以有不同的user和group id,可以在container内部用container内部的用户执行程序而非Host上的用户。











2、可配额/可度量

cgroups实现了对资源的配额和度量。在/cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid 写入该文件,即可实现对该进程的资源控制。groups可以限制blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns九大子系统的资源,每个子系统的详细说明如下:
有序列表blkio子系统设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等。
cpu子系统使用调度程序为cgroup任务提供cpu的访问。
cpuacct:产生cgroup任务的cpu资源报告。
cpuset:对于多核心CPU,cpuset子系统会为cgroup任务分配单独的cpu和内存。
devices允许或拒绝cgroup任务对设备的访问。
freezer暂停和恢复cgroup任务。
memory设置每个cgroup的内存限制以及产生内存资源报告。
net_cls标记每个网络包以供cgroup方便使用。
ns名称空间子系统。








3、便携性

AUFS(Another Union FS)是一种Union FS,支持将不同目录挂载到同一个虚拟文件系统下的文件系统。AUFS支持为每一个成员目录设定readonly、readwrite和whiteout-able权限,同时AUFS有分层的概念,对readonly权限的branch可以逻辑上进行修改(增量地,不影响readonly部分)。
通常Union FS有两个用途,一是可以实现不借助LVM、RAID将多个disk挂到同一个目录下;一个是将一个readonly的branch和一个writeable的 branch联合在一起(Live CD可以允许在OS image不变的基础上允许用户在其上进行一些写操作)。
典型的启动Linux运行需要两个FS:bootfs + rootfs
Hello Docker(一)——Docker简介
bootfs(boot file system)主要包含bootloader 和 kernel,bootloader引导加载kernel,当boot成功后kernel被加载到内存中后bootfs就被umount。rootfs(root file system)包含典型Linux系统中的dev、proc、bin、etc等标准目录和文件。不同Linux发行版中bootfs基本是一致的,但rootfs会有差别,因此不同Linux发行版可以共用bootfs。
Hello Docker(一)——Docker简介
典型Linux在启动后,首先将rootfs设置为readonly,进行一系列检查,然后将其切换为readwrite供用户使用。在Docker中,初始化时将rootfs以readonly方式加载并检查,然后利用union mount方式将一个 readwrite文件系统挂载在readonly的rootfs上,并且允许再次将下层FS(file system)设定为readonly,并且向上叠加,readonly和writeable组成的结构构成一个container的运行时态,每一个FS被称作一个FS层。
Hello Docker(一)——Docker简介
基于AUFS的特性,每一个对readonly层文件/目录的修改都只会存在于上层writeable层中。由于不存在竞争,多个container可以共享readonly的FS层。因此,Docker将readonly的FS层称作image。Docker容器中,rootfs是read-write的,但所有的修改都写入最上层writeable层中,image不保存用户状态,只用于模板、新建和复制使用。
Hello Docker(一)——Docker简介
上层image依赖下层image,因此Docker中把下层image称作父image,没有父image的image称作base image。因此要从一个image启动一个容器,Docker会先加载image本身和依赖的父images以及 base image,用户进程运行在writeable的layer中。所有parent image中的数据信息以及ID、网络和LXC管理的资源限制等具体container的配置,构成一个Docker上的container。
Hello Docker(一)——Docker简介










4、安全性

Docker的安全特性包括三个方面:
A、由kernel namespaces和cgroups实现的Linux系统固有的安全标准;
B、Docker Deamon安全接口;
C、Linux本身的安全加固解决方案,例如AppArmor,SELinux;


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!