Docker在面试中常见的48道问题

2022-09-07 13:25:22

1、什么Docker?

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

  • Docker容器,将一个软件包装在一个完整的文件系统中,该文件系统包含运行所需的一切:代码,运行时,系统工具,系统库等可以安装在服务器上的任何东西。

  • 这可以保证软件始终运行相同,无论其环境如何。

2、Docker与虚拟机有何不同

答:Docker不是虚拟化方法。它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具。为此,Docker最初使用LXC驱动程序,然后移动到libcontainer现在重命名为runc。Docker主要专注于在应用程序容器内自动部署应用程序。应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。因此,Docker被视为容器化系统上的容器管理或应用程序部署工具。Docker是轻量级的沙盒,在其中运行的只是应用,虚拟机里面还有额外的系统。

  • 容器不需要引导操作系统内核,因此可以在不到一秒的时间内创建容器。此功能使基于容器的虚拟化比其他虚拟化方法更加独特和可取。

  • 由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能。

  • 对于基于容器的虚拟化,与其他虚拟化不同,不需要其他软件。

  • 主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求。

  • 与虚拟机映像相比,容器状态(Docker或LXC映像)的大小很小,因此容器映像很容易分发。

  • 容器中的资源管理是通过cgroup实现的。Cgroups不允许容器消耗比分配给它们更多的资源。虽然主机的所有资源都在虚拟机中可见,但无法使用。这可以通过在容器和主机上同时运行top或htop来实现。所有环境的输出看起来都很相似。

3、什么是Docker镜像

答:Docker镜像是Docker容器的源代码,Docker镜像用于创建容器。可以使用Dockerfile 与 docker build命令创建一个镜像文件。在使用run启动时它们将生成容器。镜像存储在Docker注册表中,registry.hub.docker.com因为它们可能变得非常大,镜像被设计为由其他镜像层组成,允许在通过网络传输镜像时发送最少量的数据。

(When running a container, it uses an isolated filesystem. Thiscustom filesystem is provided by a container image. Since the image contains the container’s filesystem, it mustcontain everything needed to run an application - alldependencies, configuration, scripts, binaries, etc. The image also contains other configuration for the container, such asenvironment variables, a default command to run, and other metadata.

4、什么是Docker容器

答:Docker容器包括应用程序及其所有依赖的底层项,可以作为操作系统的独立进程运行。Docker容器包括应用程序及其所有依赖项,但与其他容器共享内核,作为主机操作系统上用户空间中的独立进程运行。Docker容器不依赖于任何特定的基础架构:它们可以在任何计算机,任何基础架构和任何云中运行。

(a container is simply anotherprocess on your machine that has been isolated from all other processes on the host machine. That isolation leverageskernel namespaces and cgroups, features that have been in Linux for a long time. Docker has worked to make these capabilities approachable and easy to use.)

5、Docker容器有几种状态

答:四种状态:运行、已暂停、重新启动、已退出。可以使用如下命令查看指定状态的容器是否运行正常

docker inspect --format "{{.State.Running}}" CONTAINER_NAME

6、Dockerfile中最常见的指令是什么

答:FROM:指定基础镜像

LABEL:功能是为镜像指定标签

RUN:运行指定的命令

CMD:容器启动时要运行的命令

ADD:拷贝文件,支持拷贝远程主机上的文件

COPY:拷贝本地文件

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

答:一般而言,虽然ADD并且COPY在功能上类似,但是首选COPY。那是因为它比ADD更易懂。COPY仅支持将本地文件复制到容器中,而ADD具有一些额外的功能(如仅限本地的tar提取和远程URL支持),这些功能并不是很明显。因此,ADD的最佳用途是将本地tar文件自动提取到镜像中,如ADD rootfs.tar.xz /。COPY与ADD的区别COPY的SRC只能是本地文件,其他用法一致

8、docker常用管理命令

答:

docker pull 拉取或者更新指定镜像

docker push 将镜像推送至远程仓库

docker rm 删除容器

docker rmi 删除镜像

docker images 列出所有镜像

docker ps 列出所有容器

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

答:docker cp 命令用于容器与主机之间的数据拷贝

主机到容器:

docker cp /www 96f7f14e99ab:/www/

容器到主机:

docker cp 96f7f14e99ab:/www /tmp/

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

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

11、解释一下dockerfile的ONBUILD指令

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

12、什么是Docker Swarm

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

13、如何在生产中监控Docker

答:Docker提供docker statsdocker事件等工具来监控生产中的Docker。我们可以使用这些命令获取重要统计数据的报告。

Docker统计数据:当我们使用容器ID调用docker stats时,我们获得容器的CPU,内存使用情况等。它类似于Linux中的top命令。

Docker事件:Docker事件是一个命令,用于查看Docker守护程序中正在进行的活动流。

一些常见的Docker事件是:attach,commit,die,detach,rename,destroy等。我们还可以使用各种选项来限制或过滤我们感兴趣的事件

14、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。

15、进入容器的方法有哪些?

答:

1)、使用 docker attach 命令

2)、使用 exec 命令,例如docker exec -i -t 784fd3b294d7 /bin/bash

16、解释基本的Docker使用工作流程是怎样的?

答:(1)、从Dockerfile开始,Dockerfile是镜像的源代码;

(2)、创建Dockerfile后,可以构建它以创建容器的镜像。镜像只是“源代码”的“编译版本”,即Dockerfile;

(3)、获得容器的镜像后,应使用注册表(registry)重新分发容器。注册表就像一个git存储库,可以推送和拉取镜像;接下来,可以使用该镜像运行容器。在许多方面,正在运行的容器与虚拟机(但没有虚拟机管理程序)非常相似。

17、什么类型的应用程序无状态或有状态更适合Docker容器?

答:最好为Docker Container创建无状态应用程序。我们可以从应用程序中创建一个容器,并从应用程序中取出可配置的状态参数。现在我们可以在生产环境和具有不同参数的QA环境中运行相同的容器。这有助于在不同场景中重用相同的镜像。另外,无状态应用程序比有状态应用程序更容易使用Docker容器进行扩展。

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

19、如何清理后台停止的容器? 答:可以使用 sudo docker rm $sudo( docker ps -a -q) 命令 或者 使用 sudo docker rmi $(sudo docker images -q -f danging=true)命令

20、如何查看镜像支持的环境变量? 答:可以使用 docker run IMAGE env 命令。

21、当启动容器的时候提示:exec format error?如何解决问题 答:检查启动命令是否有可执行权限,进入容器手工运行脚本进行排查。

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

23、如何退出一个镜像的 bash,而不终止它? 答:按 Ctrl+p,后按 Ctrl+q,如果按 Ctrl+c 会使容器内的应用进程终止,进而会使容器终止。

24、退出容器时候自动删除? 答:使用–rm 选项,例如 sudo docker run –rm -it ubuntu

25、构建 Docker 镜像应该遵循哪些原则? 答:整体远侧上,尽量保持镜像功能的明确和内容的精简,要点包括: 1)、尽量选取满足需求但较小的基础系统镜像,建议选择 debian:wheezy镜像,仅有86MB大小 2)、清理编译生成文件、安装包的缓存等临时文件 3)、安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖 4)、从安全的角度考虑,应用尽量使用系统的库和依赖 5)、使用 Dockerfile 创建镜像时候要添加.dockerignore文件或使用干净的工作目录

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

27、如何停止所有正在运行的容器? 答:使用 docker kill $(sudo docker ps -q)

28、很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息? 答:使用 docker logs,后面跟容器的名称或者 ID 信息

docker logs -f -t --tail 100 datacenter

命令格式:

$ docker logs [OPTIONS] CONTAINEROptions: --details 显示更多的信息 -f, --follow 跟踪实时日志 --since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟) --tail string 从日志末尾显示多少行日志, 默认是all -t, --timestamps 显示时间戳 --until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)

例子:

查看指定时间后的日志,只显示最后100行:

$ docker logs -f -t --since="2018-02-08"--tail=100 CONTAINER_ID

查看最近30分钟的日志:

$ docker logs --since 30m CONTAINER_ID

查看某时间之后的日志:

$ docker logs -t --since="2018-02-08T13:23:37" CONTAINER_ID

查看某时间段日志:

$ docker logs -t --since="2018-02-08T13:23:37" --until "2018-02-09T12:23:37" CONTAINER_ID

29、使用 docker port 命令映射容器的端口时,系统报错 Error: No public port ‘80’,published for …,是什么意思? 答:创建镜像时 Dockerfile 要指定正确的 EXPOSE 的端口,容器启动时指定 PublishAllport=true

30、如何将镜像的体积制作的更小?

答:1)、基于镜像制作是分层的模式,所以通过减小分层数可以解决,也就是把多条命令合并在一起执行;2)、构建镜像时会产生缓存,那么制作新的镜像的时候尽量使新的镜像命中已有缓存,此时把需要迭加的命令放在最后执行。

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

32、如何控制容器占用系统资源(CPU,内存)的份额? 答:在使用 docker create 命令创建容器或使用 docker run创建并运行容器的时候, 可以使用-c|–cpu-shares[=0]参数来调整同期使用 CPU 的权重,使用-m|–memory 参数来调整容器使用内存的大小。

33、仓库(Repository)、注册服务器(Registry)、注册索引(Index)有何关系? 答:首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像,注册服务器是存放实际的镜像的地方,注册索引则负责维护用户的账号,权限,搜索, 标签等管理。注册服务器利用注册索引来实现认证等管理。

34、从非官方仓库(如:http://dl.dockerpool.com)下载镜像的时候,有时候会提 示“Error:Invaild registry endpointhttps://dl.docker.com:5000/v1/…”? 答:Docker 自 1.3.0 版本往后以来,加强了对镜像安全性的验证,需要手动添加对非官方仓库的信任。 DOCKER_OPTS="-insecure-registry dl.dockerpool.com:5000”,重启 docker 服务

35、Docker 的配置文件放在那里。如何修改配置? 答:默认情况下,Ubuntu系统中 Docker 的配置文件是/etc/default/docker,CentOS系统配置文件存放在/etc/sysconfig/docker

36、如何更改 Docker 的默认存储设置? 答:Docker 的默认存放位置是/var/lib/docker,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来做。

37、Docker 与 LXC(Linux Container)有何不同? 答:LXC 利用 Linux 上相关技术实现容器,Docker 则在如下的几个方面进行了改进:

  • 移植性:通过抽象容器配置,容器可以实现一个平台移植到另一个平台;

  • 镜像系统:基于 AUFS 的镜像系统为容器的分发带来了很多的便利,同时共同的 镜像层只需要存储一份,实现高效率的存储;

  • 版本管理:类似于 GIT 的版本管理理念,用户可以更方面的创建、管理镜像文件;

  • 仓库系统:仓库系统大大降低了镜像的分发和管理的成本;

  • 周边工具:各种现有的工具(配置管理、云平台)对 Docker 的支持,以及基于 Docker 的 Pass、CI 等系统,让 Docker 的应用更加方便和多样化。

38、Docker 与 Vagrant 有何不同? 答:两者的定位完全不同 Vagrant 类似于 Boot2Docker(一款运行 Docker 的最小内核),是一套虚拟机的管理环境,Vagrant可以在多种系统上和虚拟机软件中运行,可以在 Windows。Mac 等非 Linux 平台上为 Docker 支持,自身具有较好的包装性和移植性。 原生 Docker 自身只能运行在 Linux 平台上,但启动和运行的性能都比虚拟机要快, 往往更适合快速开发和部署应用的场景。

39、开发环境中Docker与Vagrant该如何选择? 答:Docker 不是虚拟机,而是进程隔离,对于资源的消耗很少,单一开发环境下 Vagrant 是虚拟机上的封装,虚拟机本身会消耗资源。

40、Docker 能在非 Linux 平台(Windows+MacOS)上运行吗? 答:可以

41、如何将一台宿主机的 docker 环境迁移到另外一台宿主机? 答:停止 Docker 服务,将整个 docker 存储文件复制到另外一台宿主机上,然后调整另外一台宿主机的配置即可

42、Docker 容器创建后,删除了/var/run/netns 目录下的网络名字空间文件,可以手动恢复吗? 答:查看容器进程 ID,比如 1234

sudo docker inspect --format='{{. State.pid}}' $container_id 1234

# 到 proc 目录下,把对应的网络名字空间文件链接到 /var/run/netns,然后通过正常的系统命令查看操作容器的名字空间。

43、容器内部机制?

大约在2006年,包括Google的一些员工在内的人们实现了名为命名空间的新的Linux内核级功能(不过这个想法早在FreeBSD中就已存在)。操作系统的一个功能是允许将全局资源(如网络和磁盘)共享到进程。如果将这些全局资源包装在命名空间中,以使它们仅对在同一命名空间中运行的那些进程可见,该怎么办?比如说,你可以获得一大块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法查看或访问它。类似地,名称空间X中的进程无法访问分配给名称空间Y的内存中的任何内容。当然,X中的进程无法查看或与名称空间Y中的进程通信。这为全局资源提供了一种虚拟化和隔离。这就是Docker的工作原理:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。

44、如何使用Docker构建与环境无关的系统?有三个主要功能有助于实现这一目标:

  • 存储卷Volumes:单独挂在到一个指定的卷中,实现本地存储

  • 环境变量注入:环境变量是通过其执行上下文提供给程序的键值对。它可以让你在改变一个程序的配置时,无须修改任何文件或更改用于启动该程序的命令。

  • 只读文件系统:使用只读文件系统产生以下两个积极效果。首先,你对容器不能更改它所包含的文件产生信心;其次,你也会进一步树立信念:容器中的攻击者无法破坏文件。

45、什么是Docker Hub?

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

46、Docker镜像和层有什么区别?

  • 镜像:Docker镜像是由一系列只读层构建的

  • 层:每个层代表镜像Dockerfile中的一条指令。

下面的Dockerfile包含四个命令,每个命令都创建一个层。

FROM ubuntu:15.04 
COPY . /app
RUN make /app
CMD python /app/app.py

重要的是,每个层只是与之前一层的一组差异层(相同的就不再放到新层中)。

47、如何在多个环境中使用Docker?

可以进行以下更改:

  • 删除应用程序代码的任何卷绑定,以便代码保留在容器内,不能从外部更改

  • 绑定到主机上的不同端口

  • 以不同方式设置环境变量(例如,减少日志记录的详细程度,或启用电子邮件发送)

  • 指定重启策略(例如,重启:始终)以避免停机

  • 添加额外服务(例如,日志聚合器)

因此,您可能希望定义一个额外的Compose文件,例如production.yml,它指定适合生产的配置。此配置文件只需要包含您要从原始Compose文件中进行的更改。

docker-compose -f docker-com

48、为什么Docker Compose不会等待容器准备就绪,然后继续以依赖顺序启动下一个服务?

Compose按照依赖顺序启动和停止容器,决定依赖关系语句有 depends_on, links, volumes_from, 和network_mode: "service:...".

但是,对于启动,Compose不会等到容器“准备好它运行“。这里有一个很好的理由:

  • 等待数据库(例如)准备就绪的问题实际上只是分布式系统更大问题的一个子集。在生产中,数据库可能随时变得不可用或移动主机。应用程序需要能够适应这些类型的故障。

  • 要处理此问题,请将应用程序设计为在发生故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库。

  • 最佳解决方案是在启动时以及出于任何原因丢失连接时,在应用程序代码中执行此检查。

  • 作者:陛戈伯德
  • 原文链接:https://blog.csdn.net/qq_40916808/article/details/120235927
    更新时间:2022-09-07 13:25:22