1、什么Docker
Docker是一个容器化平台,它以容器的形式将我们的应用程序及其所有依赖项打包在一起,以确保应用程序在任何环境中无缝运行。
2、Docker与虚拟机有何不同
Docker不是虚拟化方法。它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具。为此,Docker最初使用LXC驱动程序,然后移动到libcontainer现在重命名为runc。
Docker主要专注于在应用程序容器内自动部署应用程序。应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。因此,Docker被视为容器化系统上的容器管理或应用程序部署工具。
- 容器不需要引导操作系统内核,因此可以在不到一秒的时间内创建容器。此功能使基于容器的虚拟化比其他虚拟化方法更加独特和可取。
- 由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能。
- 对于基于容器的虚拟化,与其他虚拟化不同,不需要其他软件。
- 主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求。
- 与虚拟机映像相比,容器状态(Docker或LXC映像)的大小很小,因此容器映像很容易分发。
- 容器中的资源管理是通过cgroup实现的。Cgroups不允许容器消耗比分配给它们更多的资源。虽然主机的所有资源都在虚拟机中可见,但无法使用。这可以通过在容器和主机上同时运行top或htop来实现。所有环境的输出看起来都很相似。
3、什么是Docker镜像
Docker镜像是Docker容器的源代码,Docker镜像用于创建容器。可以使用Dockerfile 与 docker build命令创建一个镜像文件。在使用run启动时它们将生成容器。镜像存储在Docker注册表中,registry.hub.docker.com因为它们可能变得非常大,镜像被设计为由其他镜像层组成,允许在通过网络传输镜像时发送最少量的数据。
4、什么是Docker容器
Docker容器包括应用程序及其所有依赖的底层项,可以作为操作系统的独立进程运行。Docker容器包括应用程序及其所有依赖项,但与其他容器共享内核,作为主机操作系统上用户空间中的独立进程运行。Docker容器不依赖于任何特定的基础架构:它们可以在任何计算机,任何基础架构和任何云中运行。
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 列出所有容器
- docker load -i xxx.tar 加载镜像
- docker save -o xxxx-[tag].tar 将镜像保存到本地
9、容器与主机之间的数据拷贝命令
docker cp 命令用于容器与主机之间的数据拷贝
主机到容器:
docker cp /www 96f7f14e99ab:/www/
容器到主机:
docker cp 96f7f14e99ab:/www /tmp/
启动nginx容器(随机端口映射),并挂载本地文件目录到容器html的命令
docker run -d -P --name nginx2 -v /home/nginx:/usr/share/nginx/html nginx
10、解释一下dockerfile的ONBUILD指令
当镜像用作另一个镜像构建的基础时,ONBUILD指令向镜像添加将在稍后执行的触发指令。如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序),这将非常有用。
11、什么是Docker Swarm
Docker Swarm是Docker的本机群集。它将Docker主机池转变为单个虚拟Docker主机。Docker Swarm提供标准的Docker API,任何已经与Docker守护进程通信的工具都可以使用Swarm透明地扩展到多个主机。
12、如何在生产中监控Docker
Docker提供docker stats和docker事件等工具来监控生产中的Docker。我们可以使用这些命令获取重要统计数据的报告。
Docker统计数据:当我们使用容器ID调用docker stats时,我们获得容器的CPU,内存使用情况等。它类似于Linux中的top命令。
Docker事件:Docker事件是一个命令,用于查看Docker守护程序中正在进行的活动流。
一些常见的Docker事件是:attach,commit,die,detach,rename,destroy等。我们还可以使用各种选项来限制或过滤我们感兴趣的事件
13、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。
14、Docker是怎么工作的?
实际上docker使用了常见的C/S架构,也就是client-server模式,docker client负责处理用户输入的各种命令,比如docker build、docker run,真正工作的其实是server,也就是docker demon,值得注意的是,docker client和docker demon可以运行在同一台机器上。
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。守护进程和客户端可以运行在同一台机器上。
这就是Docker的工作原理:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。
15、Docker容器之间怎么隔离的?
Linux中的PID、IPC、网络等资源是全局的,而NameSpace机制是一种资源隔离方案,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace,各个NameSpace下的资源互不干扰。
虽然有了NameSpace技术可以实现资源隔离,但进程还是可以不受控的访问系统资源,比如CPU、内存、磁盘、网络等,为了控制容器中进程对资源的访问,Docker采用control groups技术(也就是cgroup),有了cgroup就可以控制容器中进程对系统资源的消耗了,比如你可以限制某个容器使用内存的上限、可以在哪些CPU上运行等等。
有了这两项技术,容器看起来就真的像是独立的操作系统了。
16、DockerFile中的命令COPY和ADD命令有什么区别?
COPY和ADD的区别:COPY的SRC只能是本地文件,其他用法一致。
17、一个完整的Docker由哪些部分组成?
- Docker Client客户端
- Docker Daemon守护进程
- Docker Image镜像
- DockerContainer容器
18、进入容器的方法有哪些?
- 使用 docker attach命令
- 使用docker exec命令,例如docker exec -i -t 784fd3b294d7 /bin/bash
19、什么是联合文件系统(UnionFS)?
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。UnionFS是一种分层、轻量级并且高性能的文件系统。联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
20、Docker安全吗?
Docker 利用了 Linux 内核中很多安全特性来保证不同容器之间的隔离,并且通过签名机制来对镜像进行验证。大量生产环境的部署证明,Docker 虽然隔离性无法与 虚拟机相比,但仍然具有极高的安全性。
21、如何清理后台停止的Docker容器?
sudo docker rm ${sudo(docker ps -a -q)}
或者
sudo docker rmi $(sudo docker images -q -f danging=true)
22、如何查看Docker镜像支持的环境变量?
docker run [IMAGE] env
23、当启动容器的时候提示:exec format error?如何解决问题
检查启动命令是否有可执行权限,进入容器手工运行脚本进行排查。
24、退出容器时候自动删除?
使用–rm 选项,例如 sudo docker run –rm -it ubuntu
25、构建 Docker 镜像应该遵循哪些原则?
整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括:
- 尽量选取满足需求但较小的基础系统镜像,建议选择 debian:wheezy镜像,仅有86MB大小
- 清理编译生成文件、安装包的缓存等临时文件
- 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖
- 从安全的角度考虑,应用尽量使用系统的库和依赖
- 使用 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、如何将镜像的体积制作的更小?
- 基于镜像制作是分层的模式,所以通过减小分层数可以解决,也就是把多条命令合并在一起执行;
- 构建镜像时会产生缓存,那么制作新的镜像的时候尽量使新的镜像命中已有缓存,此时把需要迭加的命令放在最后执行。
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
RUNmake /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不会等到容器“准备好它运行“。这里有一个很好的理由:
等待数据库(例如)准备就绪的问题实际上只是分布式系统更大问题的一个子集。在生产中,数据库可能随时变得不可用或移动主机。应用程序需要能够适应这些类型的故障。
要处理此问题,请将应用程序设计为在发生故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库。
最佳解决方案是在启动时以及出于任何原因丢失连接时,在应用程序代码中执行此检查。
49、退出Docker容器时候自动删除?
使用–rm 选项,例如 sudo docker run –rm -it ubuntu
50、镜像相关
- 1、如何批量清理临时镜像文件?
可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令
- 2、如何查看镜像支持的环境变量?
使用sudo docker run IMAGE env
- 3、本地的镜像文件都存放在哪里
于Docker相关的本地资源存放在/var/lib/docker/目录下,其中container目录存放容器信息,graph目录存放镜像信息,aufs目录下存放具体的镜像底层文件。
- 4、构建Docker镜像应该遵循哪些原则?
整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括:
# 尽量选取满足需求但较小的基础系统镜像,建议选择debian:wheezy镜像,仅有86MB大小
# 清理编译生成文件、安装包的缓存等临时文件
# 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖
# 从安全的角度考虑,应用尽量使用系统的库和依赖
# 使用Dockerfile创建镜像时候要添加.dockerignore文件或使用干净的工作目录
51、容器相关
- 1、容器退出后,通过docker ps 命令查看不到,数据会丢失么?
容器退出后会处于终止(exited)状态,此时可以通过 docker ps -a 查看,其中数据不会丢失,还可以通过docker start 来启动,只有删除容器才会清除数据。
- 2、如何停止所有正在运行的容器?
使用docker kill $(sudo docker ps -q)
- 3、如何清理批量后台停止的容器?
使用docker rm $(sudo docker ps -a -q)
- 4、如何临时退出一个正在交互的容器的终端,而不终止它?
按Ctrl+p,后按Ctrl+q,如果按Ctrl+c会使容器内的应用进程终止,进而会使容器终止。
- 5、很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息?
使用docker logs,后面跟容器的名称或者ID信息
- 6、使用docker port 命令映射容器的端口时,系统报错Error: No public port ‘80’ published for …,是什么意思?
创建镜像时Dockerfile要指定正确的EXPOSE的端口,容器启动时指定PublishAllport=true
- 7、可以在一个容器中同时运行多个应用进程吗?
一般不推荐在同一个容器内运行多个应用进程,如果有类似需求,可以通过额外的进程管理机制,比如supervisord来管理所运行的进程
- 8、如何控制容器占用系统资源(CPU,内存)的份额?
在使用docker create命令创建容器或使用docker run 创建并运行容器的时候,可以使用-c|–cpu-shares[=0]参数来调整同期使用CPU的权重,使用-m|–memory参数来调整容器使用内存的大小。
52、仓库相关
- 1、仓库(Repository)、注册服务器(Registry)、注册索引(Index)有何关系?
首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像,注册服务器是存放实际的镜像的地方,注册索引则负责维护用户的账号,权限,搜索,标签等管理。注册服务器利用注册索引来实现认证等管理。
-2 、从非官方仓库(如: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服务
53、配置相关
- 1、Docker的配置文件放在那里。如何修改配置?
Ubuntu系统下Docker的配置文件是/etc/default/docker,CentOS系统配置文件存放在/etc/sysconfig/docker
-2、如何更改Docker的默认存储设置?
Docker的默认存放位置是/var/lib/docker,如果希望将Docker的本地文件存储到其他分区,可以使用Linux软连接的方式来做。
54、Docker与虚拟化
- 1、Docker与LXC(Linux Container)有何不同?
LXC利用Linux上相关技术实现容器,Docker则在如下的几个方面进行了改进:
移植性:通过抽象容器配置,容器可以实现一个平台移植到另一个平台;
镜像系统:基于AUFS的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储;
版本管理:类似于GIT的版本管理理念,用户可以更方面的创建、管理镜像文件;
仓库系统:仓库系统大大降低了镜像的分发和管理的成本;
周边工具:各种现有的工具(配置管理、云平台)对Docker的支持,以及基于Docker的Pass、CI等系统,让Docker的应用更加方便和多样化。
- 2 、Docker与Vagrant有何不同?
两者的定位完全不同
Vagrant类似于Boot2Docker(一款运行Docker的最小内核),是一套虚拟机的管理环境,Vagrant可以在多种系统上和虚拟机软件中运行,可以在Windows。Mac等非Linux平台上为Docker支持,自身具有较好的包装性和移植性。
原生Docker自身只能运行在Linux平台上,但启动和运行的性能都比虚拟机要快,往往更适合快速开发和部署应用的场景。
- 3、开发环境中Docker与Vagrant该如何选择?
Docker不是虚拟机,而是进程隔离,对于资源的消耗很少,单一开发环境下Vagrant是虚拟机上的封装,虚拟机本身会消耗资源。
55、Other FAQ
- 1、Docker能在非Linux平台(Windows+MacOS)上运行吗?
可以
- 2 、如何将一台宿主机的docker环境迁移到另外一台宿主机?
停止Docker服务,将整个docker存储文件复制到另外一台宿主机上,然后调整另外一台宿主机的配置即可
- 3、Docker容器创建后,删除了/var/run/netns 目录下的网络名字空间文件,可以手动恢复它:
# 查看容器进程ID,比如1234 sudo docker inspect --format='{{. State.pid}}' $container_id 1234 # 到proc目录下,把对应的网络名字空间文件链接到/var/run/netns,然后通过正常的系统命令查看操作容器的名字空间。