Docker面试题

Docker面试题-

1 什么Docker

1.1 什么是 Linux 容器

Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。

img

更加详细地来说,请您假定您在开发一个应用。您使用的是一台笔记本电脑,而且您的开发环境具有特定的配置。其他开发人员身处的环境配置可能稍有不同。您正在开发的应用依赖于您当前的配置,还要依赖于某些特定文件。与此同时,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。您希望尽可能多在本地模拟这些环境,而不产生重新创建服务器环境的开销。

因此,您要如何确保应用能够在这些环境中运行和通过质量检测,并且在部署过程中不出现令人头疼的问题,也无需重新编写代码和进行故障修复?答案就是使用容器。容器可以确保您的应用拥有必需的配置和文件,使得这些应用能够在从开发到测试、再到生产的整个流程中顺利运行,而不出现任何不良问题。这样可以避免危机,做到皆大欢喜。

虽然这只是简化的示例,但在需要很高的可移植性、可配置性和隔离的情况下,我们可以利用 Linux 容器通过很多方式解决难题。无论基础架构是在企业内部还是在云端,或者混合使用两者,容器都能满足您的需求。

1.2 什么Docker

Docker是一个容器化平台,它以容器的形式将您的应用程序 及其所有依赖项打包在一起,以确保您的应用程序在任何环境中无缝运行。

Docker容器是一个完整的文件系统,这个文件系统中包含了你的软件运行所需要的全部环境,如:软件的源码、运行环境、所需的软件等。也就是说,你的软件运行所需要的环境都包含在了Docker容器中,这样的话当你把代码部署到服务器上时就不需要考虑环境问题,只要服务器安装了Docker就能准确无误地运行你的软件。

1.3 Docker的目标

Docker的主要目标是”Build,Ship and Run any App,Angwhere”,构建,运输,处处运行

构建:做一个docker镜像

运输:docker pull

运行:启动一个容器

每一个容器,他都有自己的文件系统rootfs.

1.4 Docker 如何工作?

Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。这种独立性正是采用容器的目的所在;它可以独立运行多种进程、多个应用程序,更加充分地发挥基础设施的作用,同时保持各个独立系统的安全性。

容器工具(包括 Docker)可提供基于镜像的部署模式。这使得它能够轻松跨多种环境,与其依赖程序共享应用或服务组。Docker 还可在这一容器环境中自动部署应用程序(或者合并多种流程,以构建单个应用程序)。

此外,由于这些工具基于 Linux 容器构建,使得 Docker 既易于使用,又别具一格 —— 它可为用户提供前所未有的高度应用程访问权限、快速部署以及版本控制和分发能。

1.5 Docker与虚拟机有何不同?

Docker不是虚拟化方法。它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具。为此,Docker最初使用LXC驱动程序,然后移动到libcontainer现在重命名为runc。Docker主要专注于在应用程序容器内自动部署应用程序。应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。因此,Docker被视为容器化系统上的容器管理或应用程序部署工具。 A 容器不需要引导操作系统内核,因此可以在不到一秒的时间内创建容器。此功能使基于容器的虚拟化比其他虚拟化方法更加独特和可取。 B 由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能。 C 对于基于容器的虚拟化,与其他虚拟化不同,不需要其他软件。 D 主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求。 E 与虚拟机映像相比,容器状态(Docker或LXC映像)的大小很小,因此容器映像很容易分发。 F 容器中的资源管理是通过cgroup实现的。Cgroups不允许容器消耗比分配给它们更多的资源。虽然主机的所有资源都在虚拟机中可见,但无法使用。这可以通过在容器和主机上同时运行top或htop来实现。所有环境的输出看起来都很相似。

1.6 Docker镜像生命周期

img

2 Docker容器和镜像

2.1 什么是Docker Hub?

Docker hub是一个基于云的注册表服务,允许您链接到代码存储库,构建镜像并测试它们,存储手动推送的镜像以及指向Docker云的链接,以便您可以将镜像部署到主机。它为整个开发流程中的容器镜像发现,分发和变更管理,用户和团队协作以及工作流自动化提 供了集中资源。

2.2 什么是Docker镜像

Docker镜像是Docker容器的源代码,Docker镜像用于创建容器。使用build命令创建镜像。镜像参数说明。

image-20210829145728999

2.3 什么是Docker容器

Docker容器包括应用程序及其所有依赖项,作为操作系统的独立进程运行。

2.4 Docker容器有几种状态

四种状态:运行、已暂停、重新启动、已退出。

2.5 Dockerfile中最常见的指令是什么

FROM:我们使用FROM为后续指令设置基本镜像。在每个有效的Dockerfile中,FROM是第一条指令。 LABEL:我们使用LABEL按照项目,模块,许可等组织我们的镜像。我们也可以使用LABEL来帮助实现自动化。在LABEL中,我们指定一个键值对,以后可用于以编程方式处理Dockerfile。 RUN:我们使用RUN命令在当前镜像之上的新图层中执行任何指令。使用每个RUN命令,我们在镜像顶部添加一些内容,并在Dockerfile的后续步骤中使用它。 CMD:我们使用CMD命令提供执行容器的默认值。在Dockerfile中,如果我们包含多个CMD命令,则只使用最后一条指令。

2.6 Dockerfile中的命令COPY和ADD命令有什么区别

COPY与ADD的区别COPY的SRC只能是本地文件,其他用法一致

2.7 docker常用命令

docker pull 拉取或者更新指定镜像 docker push 将镜像推送至远程仓库 docker rm 删除容器 docker rmi 删除镜像 docker images 列出所有镜像 docker ps 列出所有容器

2.8 容器与主机之间的数据拷贝命令

docker cp 命令用于容器与主机之间的数据拷贝 主机到容器: docker cp /www 96f7f14e99ab:/www/ 容器到主机: docker cp 96f7f14e99ab:/www /tmp/

2.9 启动nginx容器(随机端口映射),并挂载本地文件目录到容器html的命令

docker run -d -P –name nginx2 -v /home/nginx:/usr/share/nginx/html nginx

3 Docker 其他面试题

3.1 解释一下dockerfile的ONBUILD指令

当镜像用作另一个镜像构建的基础时,ONBUILD指令向镜像添加将在稍后执行的触发指令。如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序),这将非常有用。

3.2 什么是Docker Swarm

Docker Swarm是Docker的本机群集。它将Docker主机池转变为单个虚拟Docker主机。Docker Swarm提供标准的Docker API,任何已经与Docker守护进程通信的工具都可以使用Swarm透明地扩展到多个主机。

3.3 如何在生产中监控Docker

Docker提供docker stats和docker事件等工具来监控生产中的Docker。我们可以使用这些命令获取重要统计数据的报告。 Docker统计数据:当我们使用容器ID调用docker stats时,我们获得容器的CPU,内存使用情况等。它类似于Linux中的top命令。 Docker事件:Docker事件是一个命令,用于查看Docker守护程序中正在进行的活动流。 一些常见的Docker事件是:attach,commit,die,detach,rename,destroy等。我们还可以使用各种选项来限制或过滤我们感兴趣的事件

3.4 Docker如何在非Linux系统中运行容器

通过添加到Linux内核版本2.6.24的名称空间功能,可以实现容器的概念。容器将其ID添加到每个进程,并向每个系统调用添加新的访问控制检查。它由clone()系统调用访问,该调用允许创建先前全局命名空间的单独实例。 如果由于Linux内核中可用的功能而可以使用容器,那么显而易见的问题是非Linux系统如何运行容器。Docker for Mac和Windows都使用Linux VM来运行容器。Docker Toolbox用于在Virtual Box VM中运行容器。但是,最新的Docker在Windows中使用Hyper-V,在Mac中使用Hypervisor.framework。

3.5 如何批量清理临时镜像文件?

可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令

3.6 如何查看镜像支持的环境变量?

使用sudo docker run IMAGE env

3.7 本地的镜像文件都存放在哪里

于Docker相关的本地资源存放在/var/lib/docker/目录下,其中container目录存放容器信息,graph目录存放镜像信息,aufs目录下存放具体的镜像底层文件。

3.8构建Docker镜像应该遵循哪些原则?

整体远侧上,尽量保持镜像功能的明确和内容的精简,要点包括:

  • # 尽量选取满足需求但较小的基础系统镜像,建议选择debian:wheezy镜像,仅有86MB大小
  • # 清理编译生成文件、安装包的缓存等临时文件
  • # 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖
  • # 从安全的角度考虑,应用尽量使用系统的库和依赖
  • # 使用Dockerfile创建镜像时候要添加.dockerignore文件或使用干净的工作目录

3.9 容器退出后,通过docker ps 命令查看不到,数据会丢失么?

容器退出后会处于终止(exited)状态,此时可以通过 docker ps -a 查看,其中数据不会丢失,还可以通过docker start 来启动,只有删除容器才会清除数据。

3.10 如何停止所有正在运行的容器?

使用docker kill $(sudo docker ps -q)

3.11如何清理批量后台停止的容器?

使用docker rm $(sudo docker ps -a -q)

3.12如何临时退出一个正在交互的容器的终端,而不终止它?

按Ctrl+p,后按Ctrl+q,如果按Ctrl+c会使容器内的应用进程终止,进而会使容器终止。

3.13 很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息?

使用docker logs,后面跟容器的名称或者ID信息

3.14 可以在一个容器中同时运行多个应用进程吗?

一般不推荐在同一个容器内运行多个应用进程,如果有类似需求,可以通过额外的进程管理机制,比如supervisord来管理所运行的进程

3.15 如何控制容器占用系统资源(CPU,内存)的份额?

在使用docker create命令创建容器或使用docker run 创建并运行容器的时候,可以使用-c –cpu-shares[=0]参数来调整同期使用CPU的权重,使用-m –memory参数来调整容器使用内存的大小。

4 Docker与虚拟化

4.1 Docker与LXC(Linux Container)有何不同?

LXC利用Linux上相关技术实现容器,Docker则在如下的几个方面进行了改进:

  • 移植性:通过抽象容器配置,容器可以实现一个平台移植到另一个平台;
  • 镜像系统:基于AUFS的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储;
  • 版本管理:类似于GIT的版本管理理念,用户可以更方面的创建、管理镜像文件;
  • 仓库系统:仓库系统大大降低了镜像的分发和管理的成本;
  • 周边工具:各种现有的工具(配置管理、云平台)对Docker的支持,以及基于Docker的Pass、CI等系统,让Docker的应用更加方便和多样化。

Docker与Vagrant有何不同?

两者的定位完全不同

Vagrant类似于Boot2Docker(一款运行Docker的最小内核),是一套虚拟机的管理环境,Vagrant可以在多种系统上和虚拟机软件中运行,可以在Windows。Mac等非Linux平台上为Docker支持,自身具有较好的包装性和移植性。

原生Docker自身只能运行在Linux平台上,但启动和运行的性能都比虚拟机要快,往往更适合快速开发和部署应用的场景。

4.2 开发环境中Docker与Vagrant该如何选择?

Docker不是虚拟机,而是进程隔离,对于资源的消耗很少,单一开发环境下Vagrant是虚拟机上的封装,虚拟机本身会消耗资源。

4.3 如何将一台宿主机的docker环境迁移到另外一台宿主机?

停止Docker服务,将整个docker存储文件复制到另外一台宿主机上,然后调整另外一台宿主机的配置即可

4.4 Docker容器创建后,删除了/var/run/netns 目录下的网络名字空间文件,可以手动恢复它:

查看容器进程ID,比如1234 sudo docker inspect –format=’’ $container_id 1234 # 到proc目录下,把对应的网络名字空间文件链接到/var/run/netns,然后通过正常的系统命令查看操作容器的名字空间。

4.5 Docker 安全么?

Docker 利用了 Linux 内核中很多安全特性来保证不同容器之间的隔离,并且通过签名机制来对镜像进行验证。大量生产环境的部署证明,Docker 虽然隔离性无法与虚拟机相比,但仍然具有极高的安全性。

4.6 如何清理后台停止的容器?

可以使用 sudo docker rm $sudo( docker ps -a -q) 命令。

4.7 如何查看镜像支持的环境变量?

可以使用 docker run IMAGE env 命令。

4.8 当启动容器的时候提示:exec format error?如何解决问题

检查启动命令是否有可执行权限,进入容器手工运行脚本进行排查。

4.9 本地的镜像文件都存放在哪里?

与 Docker 相关的本地资源都存放在/var/lib/docker/目录下,其中container目录存放容器信息,graph目录存放镜像信息,aufs目录下存放具体的内容文件。

4.10 如何退出一个镜像的bash,而不终止它?

按 Ctrl-p Ctrl-q。

4.11 退出容器时候自动删除?

使用 –rm 选项,例如 sudo docker run –rm -it ubuntu

4.12 怎么快速查看本地的镜像和容器?

可以通过docker images来快速查看本地镜像;通过docker ps -a快速查看本地容器。

5 Docker中的镜像分层

Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。

img

从上图可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

5.1 Docker 镜像为什么分层

镜像分层最大的一个好处就是共享资源。

比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内。这就是容器 Copy-on-Write 特性。

5.2 可写的容器层

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

img

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的

5.3 容器层的细节说明

镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。

文件操作的

文件操作 说明
添加文件 在容器中创建文件时,新文件被添加到容器层中。
读取文件 在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存
修改文件 在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
删除文件 在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。(只是记录删除操作)

只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

Java Geek Tech wechat
欢迎订阅 Java 技术指北,这里分享关于 Java 的一切。