龙空技术网

Java面试八股-Docker

勇者热情生活家 147

前言:

此刻小伙伴们对“nginx exec format error”大体比较珍视,同学们都想要分析一些“nginx exec format error”的相关知识。那么小编在网络上汇集了一些关于“nginx exec format error””的相关文章,希望姐妹们能喜欢,咱们一起来了解一下吧!

Docker 简介

Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了

问:Docker的应用场景?

答:Web 应用的自动化打包和发布。

自动化测试和持续集成、发布。

在服务型环境中部署和调整数据库或其他的后台应用。

从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

问:如何查看docker的守护进程

答:systemctl status docker

问:如何查看docker镜像?

答:docker image ls

问:Docker Registry配置和查看

答:cat /etc/docker/daemon.json

基础环境

1、操作系统:CentOS 7.3

2、Docker版本:19.03.9 官方下载地址

3、官方参考文档:

Docker安装

1、下载

wget \_64/docker-19.03.9.tgz

注意:如果事先下载好了可以忽略这一步

2、解压

把压缩文件存在指定目录下(如root),并进行解压:

tar -zxvf docker-19.03.9.tgz

3、将解压出来的docker文件内容移动到 /usr/bin/ 目录下:

cp docker/\* /usr/bin/

4、将docker注册为service:

> cat /etc/systemd/system/docker.service

> vi /etc/systemd/system/docker.service

5、启动

chmod +x /etc/systemd/system/docker.service #添加文件权限并启动docker

systemctl daemon-reload #重载unit配置文件

systemctl start docker #启动Docker

systemctl enable docker.service #设置开机自启

6、验证

systemctl status docker #查看Docker状态

docker -v #查看Docker版本

docker info

问:如何调整镜像仓库?

答:修改/etc/docker目录下的daemon.json文件。在文件中加入{"registry-mirrors": [";]}后保存退出;然后重新启动docker

chmod +x /etc/systemd/system/docker.service #添加文件权限并启动docker

systemctl daemon-reload #重载unit配置文件

systemctl start docker #启动Docker

systemctl restart docker #重新启动Docker

systemctl enable docker.service #设置开机自启

问:如何查看docker info 的引擎信息

答: docker info

Harbor概述(开源的镜像仓库)

Habor是由VMWare公司开源的容器镜像仓库。

事实上,Habor是在Docker Registry上进行了相应的

企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访

问控制 ,AD/LDAP集成以及审计日志等,足以满足基本企业需求。

官方地址:

问:什么是Harbor?

答:

• Harbor是VMware公司开源的企业级Docker Registry项目,其目标是帮助用户迅速搭建一个企业级的Docker Registry服务

• Harbor以 Docker 公司开源的Registry 为基础,提供了图形管理UI、基于角色的访问控制(Role Based AccessControl)、AD/LDAP集成、以及审计日志(Auditlogging)等企业用户需求的功能,同时还原生支持中文

• Harbor的每个组件都是以Docker 容器的形式构建的,使用docker-compose 来对它进行部署。用于部署Harbor 的docker- compose模板位于harbor/ docker- compose.yml

问:Harbor的特性?

答:

1.基于角色控制: 用户和仓库都是基于项目进行组织的,而用户在项目中可以拥有不同的权限

2.基于镜像的复制策略: 镜像可以在多个Harbor实例之间进行复制(同步)

3.支持LDAP/AD: Harbor 可以集成企业内部有的AD/LDAP (类似数据库的一-张表),用于对已经存在的用户认证和管理

4.镜像删除和垃圾回收: 镜像可以被删除,也可以回收镜像占用的空间

5.图形化用户界面: 用户可以通过浏览器来浏览,搜索镜像仓库以及对项目进行管理

6.审计管理: 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理

7.支持RESTful API: RESTful API提供给管理员对于Harbor 更多的操控,使得与其它管理软件集成变得更容易

8.Harbor 和docker registry的 关系: Harbor实质 上是对docker registry做 了封装,扩展了自己的业务模板

问:Harbor的构成

答:Harbor在架构上主要有Proxy、 Registry、 Core services、 Database (Harbor-db) 、Log collector ( Harbor-log)、Job services六个组件

● Proxy: Harbor 的Registry、 UI、Token 服务等组件,都处在nginx 反向代理后边。该代理将来自浏览器、docker clients的请求转发到后端不同的服务上

● Registry:负责储存Docker 镜像,并处理Docker push/pull命令。由于要对用户进行访问控制,即不同用户对Docker 镜像有不同的读写权限,Registry 会指向一个Token 服务,强制用户的每次Docker pull/push 请求都要携带一个合法的Token,Registry会通过公钥对Token进行解密验证

● Core services: Harbor的核心功能,主要提供以下3个服务:

1.UI (harbor-ui) :提供图形化界面,帮助用户管理Registry. 上的镜像( image),并对用户进行授权

2.WebHook: 为了及时获取Registry.上image 状态变化的情况,在Registry. 上配置 Webhook,把状态变化传递给UI模块

3.Token 服务:负责根据用户权限给每个Docker push/pull 命令签发Token。 Docker 客户端向Registry服务发起的请求,

如果不包含Token,会被重定向到Token服务,获得Token后再重新向Registry 进行请求

● Database (harbor-db) :为core services提供数据库服务,负责储存用户权限、审计日志、Docker 镜像分组信息等数据

● Job services: 主要用于镜像复制,本地镜像可以被同步到远程Harbor 实例上

● Log collector (harbor-log) :负责收集其他组件的日志到一个地方

• Harbor的每个组件都是以Docker 容器的形式构建的,因此,使用Docker Compose 来对它进行部署。

• 总共分为7个容器运行,通过在docker-compose.yml所在目录中执行docker-compose ps命令来查看,

名称分别为: nginx、 harbor-jobservice、 harbor-ui、 harbor-db、harbor-adminserver、registry、 harbor-log.

其中harbor-adminserver主要是作为一个后端的配置数据管理,并没有太多的其他功能。harbor-ui所要操作的所有数据都通过harbor-adminserver这样一个数据配置管理中心来完成。

Docker本地镜像载入与载出

问:如何拉取镜像?

答:通过docker image pull rancher/rke-tools:v0.1.52命令可以从镜像仓库中拉取镜像,默认从[Docker Hub]() 获取。

问:如何保存镜像?

答:docker export 镜像id -o /home/mysql-export.tar

docker save 镜像tag -o /home/mysql-export.tar

问:如何载入镜像?

答:docker import mysql-export.tar

docker load -i mysql.tar

Docker本地容器相关的操作

问:如何创建容器?

答:创建名为"centos6"的容器,并在容器内部和宿主机中查看容器中的进程信息

docker run -itd -p 6080:80 -p 6022:22 docker.io/lemonbar/centos6-ssh:latest

问:如何查看活跃容器?

答:docker ps

问:如何查看全部容器?

答:docker ps -a

问:如何停止容器?

答:docker stop id

问:如何删除容器?

答:docker rm id

问:如何查看容器的进程信息?

答:docker top [OPTIONS] CONTAINER [ps OPTIONS]

容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程。

问:查找容器名称的命令

答:docker ps --format "{{.Names}}"

问:怎么查看容器信息?

答:docker inspect id

问:查看容器目录里的进程号

答:docker exec -d centos6-2 pstree -p

docker exec -d centos6-2 ps -auxf

docker exec -d centos6-2 ll /proc

问: Docker文件目录和容器内部操作?

答:Docker默认的文件目录位于Linux server的/var/lib/docker下面。目录结构如下

|-----containers:用于存储容器信息

|-----image:用来存储镜像中间件及本身信息,大小,依赖信息

|-----network

|-----swarm

|-----tmp:docker临时目录

|-----trust:docker信任目录

|-----volumes:docker卷目录

通过docker指令确认文件位置:docker info

docker指令查看某个容器的文件目录:docker exec 容器name ls

Docker-Compose 安装

Docker-Compose 项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。

Docker-Compose 项目由 Python 编写,调用 Docker 服务提供的API来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用Compose 来进行编排管理。

1.下载安装包:curl -L -`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2.复制安装包:cp /root/docker-compose /usr/local/bin/

3.添加可执行权限:# chmod +x /usr/local/bin/docker-compose

4.测试安装结果:docker-compose --version

Docker常见面试问题:

问:docker改变了什么?

答:面向产品:产品交付

面向开发:简化环境配置

面向测试:多版本测试

面向运维:环境一致性

面向架构:自动化扩容(微服务)

问:docker的工作原理是什么?

答:docker是一个Client-Server结构的系统,docker守护进程运行在宿主机上,守护进程从客户端接受命令并管理运行在主机上的容器,容器是一个运行时环境,这就是我们说的集装箱。

问:docker的组成包含哪几大部分?

答:

docker client:客户端,为用户提供一系列可执行命令,用户用这些命令实现跟docker daemon交互;

docker daemon:守护进程,一般在宿主主机后台运行,等待接收来自客户端的请求消息;

docker image:镜像,镜像run之后就生成为docker容器;

docker container:容器,一个系统级别的服务,拥有自己的ip和系统目录结构;运行容器前需要本地存在对应的镜像,如果本地不存在该镜像则就去镜像仓库下载。

问:docker技术的三大核心概念是什么?

答:

镜像:镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。

容器:容器是基于镜像创建的,是镜像运行起来之后的一个实例,容器才是真正运行业务程序的地方。如果把镜像比作程序里面的类,那么容器就是对象。

镜像仓库:存放镜像的地方,研发工程师打包好镜像之后需要把镜像上传到镜像仓库中去,然后就可以运行有仓库权限的人拉取镜像来运行容器了。

问:基本的Docker使用流程**

答:

1. 创建Dockerfile;

2. 使用Dockerfile构建容器的镜像;

3. 使用注册表进行容器镜像的推送或拉取。

4. 使用该镜像来运行容器。

问:Docker 安全么?

答:Docker 利用了 Linux 内核中很多安全特性来保证不同容器之间的隔离,并且通

过签名机制来对镜像进行验证。大量生产环境的部署证明,Docker 虽然隔离性无法与

虚拟机相比,但仍然具有极高的安全性。

问:docker与传统虚拟机的区别什么?

1、传统虚拟机是需要安装整个操作系统的,然后再在上面安装业务应用,启动应用,通常需要几分钟去启动应用,而docker是直接使用镜像来运行业务容器的,其容器启动属于秒级别;

2、Docker需要的资源更少,Docker在操作系统级别进行虚拟化,Docker容器和内核交互,几乎没有性能损耗,而虚拟机运行着整个操作系统,占用物理机的资源就比较多;

3、Docker更轻量,Docker的架构可以共用一个内核与共享应用程序库,所占内存极小;同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高;

4、与虚拟机相比,Docker隔离性更弱,Docker属于进程之间的隔离,虚拟机可实现系统级别隔离;

5、Docker的安全性也更弱,Docker的租户root和宿主机root相同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限和宿主机的root虚拟机权限是分离的,并且虚拟机利用如Intel的VT-d和VT-x的ring-1硬件隔离技术,这种技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离;

6、Docker的集中化管理工具还不算成熟,各种虚拟化技术都有成熟的管理工具,比如:VMware vCenter提供完备的虚拟机管理能力;

7、Docker对业务的高可用支持是通过快速重新部署实现的,虚拟化具备负载均衡,高可用、容错、迁移和数据保护等经过生产实践检验的成熟保障机制,Vmware可承诺虚拟机99.999%高可用,保证业务连续性;

8、虚拟化创建是分钟级别的,Docker容器创建是秒级别的,Docker的快速迭代性,决定了无论是开发、测试、部署都可以节省大量时间;

9、虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化,Docker在Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署。

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

答:LXC利用Linux上相关技术实现了容器支持; Docker早期版本中使用了LXC技术,后期演化为新的 libcontainer, 在如下的几个方面进行了改进:

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

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

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

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

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

问:什么是 Docker 镜像?

答:Docker 镜像是 Docker 容器的源代码,Docker 镜像用于创建容器。使用build 命令创建镜像。

问:什么是 Docker 容器?

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

问:Docker 容器有几种状态?

答:运行、已暂停、重新启动、已退出。

问:Dockerfile 中的命令 COPY 和 ADD 命令有什么区别?

答:

COPY 与 ADD 的区别 COPY 的 SRC 只能是本地文件,其他用法一致。 8. 解释一下 Dockerfile 的 ONBUILD 指令? 当镜像用作另一个镜像构建的基础时,ONBUILD 指令向镜像添加将在稍后执行的触发指令。如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序),这将非常有用。

问:docker常用命令?

答:

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

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

docker rm 删除容器

docker rmi 删除镜像

docker images 列出所有镜像

docker ps 列出所有容器

问:如何列出可运行的容器?

答:docker ps

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

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

问:容器与主机之间的数据拷贝命令是?

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

主机到容器:docker cp /www 96f7f14e99ab:/www/

容器到主机:docker cp 96f7f14e99ab:/www /tmp/

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

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

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

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

问:退出容器时候自动删除?

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

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

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

问:如何查看镜像支持的环境变量?**

答:使用 sudo docker run IMAGE env

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

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

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

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

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

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

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

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

问:Dockerfile的基本指令有哪些?

答:

FROM 指定基础镜像(必须为第一个指令,因为需要指定使用哪个基础镜像来构建镜像);

MAINTAINER 设置镜像作者相关信息,如作者名字,日期,邮件,联系方式等;

COPY 复制文件到镜像;

ADD 复制文件到镜像(ADD与COPY的区别在于,ADD会自动解压tar、zip、tgz、xz等归档文件,而COPY不会,同时ADD指令还可以接一个url下载文件地址,一般建议使用COPY复制文件即可,文件在宿主机上是什么样子复制到镜像里面就是什么样子这样比较好);

ENV 设置环境变量;

EXPOSE 暴露容器进程的端口,仅仅是提示别人容器使用的哪个端口,没有过多作用;

VOLUME 数据卷持久化,挂载一个目录;

WORKDIR 设置工作目录,如果目录不在,则会自动创建目录;

RUN 在容器中运行命令,RUN指令会创建新的镜像层,RUN指令经常被用于安装软件包;

CMD 指定容器启动时默认运行哪些命令,如果有多个CMD,则只有最后一个生效,另外,CMD指令可以被docker run之后的参数替换;

ENTRYOINT 指定容器启动时运行哪些命令,如果有多个ENTRYOINT,则只有最后一个生效,另外,如果Dockerfile中同时存在CMD和ENTRYOINT,那么CMD或docker run之后的参数将被当做参数传递给ENTRYOINT;

问:使用哪个命令进入docker容器?

docker attach是直接进入容器启动命令的终端,不会启动新的进程;

docker exec则是在容器里面打开新的终端,会启动新的进程;一般建议已经exec进入容器。

问:什么是 Docker Swarm?

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

问:容器内部机制?

答:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。

问:什么是Docker Hub?

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

问:镜像与** UnionFS

答:

Linux 的命名空间和控制组分别解决了不同资源隔离的问题,前者解决了进程、网络以及文件系统的隔离,后者实现了 CPU、内存等资源的隔离。

Docker 镜像其实本质就是一个压缩包,我们可以使用命令将一个 Docker 镜像中的文件导出,你可以看到这个镜像中的目录结构与 Linux 操作系统的根目录中的内容并没有太多的区别,Docker镜像就是一个文件。

UnionFS:存储驱动

Docker 使用了一系列不同的存储驱动管理镜像内的文件系统并运行容器,这些存储驱动与Docker 卷(volume)有些不同,存储引擎管理着能够在多个容器之间共享的存储

问:docker容器之间怎么隔离?

答:docker使用NameSpace解决了容器的进程、网络以及文件系容器之间资源隔离;使用control group解决了CPU、内存等资源的隔离。Linux中的PID、IPC、网络等资源是全局的,而NameSpace机制是一种资源隔离方案,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace,各个NameSpace下的资源互不干扰。

虽然有了NameSpace技术可以实现资源隔离,但进程还是可以不受控的访问系统资源,比如CPU、内存、磁盘、网络等,为了控制容器中进程对资源的访问,Docker采用control groups技术(也就是cgroup),有了cgroup就可以控制容器中进程对系统资源的消耗了,比如你可以限制某个容器使用内存的上限、可以在哪些CPU上运行等等。有了这两项技术,容器看起来就真的像是独立的操作系统了。

问:仓库( Repository)、 注册服务器( Registry)、 注册索引( Index)有何关系?

答:仓库:存放一组关联镜像的集合,比如同一个应用的不同版本的镜像。注册服务器:存放实际的镜像文件的地方。注册索引:则负责维护用户的账号、权限、搜索、标签等的管理。因此,注册服务器利用注册索引来实现认证等管理。

问:如何在生产中监控 Docker?

答:Docker 提供 docker stats 和 docker 事件等工具来监控生产中的 Docker。当我们使用容器 ID 调用 docker stats 时,我们获得容器的CPU,内存使用情况等。

使用Docker 事件是一个命令,用于查看 Docker 守护程序中正在进行的活动流。 一些常见的 Docker 事件:attach,commit,die,detach,rename,destroy 等。

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

问:Docker能在非Linux平台(比如 `macOS`或 `Windows`)上运行么?

答:可以。macOS目前需要使用 docker for mac等软件创建一个轻量级的Linux虚拟机层。 由于成熟度不高,暂时不推荐在Windows环境中使用Docker。

问:centos镜像几个G,但是docker centos镜像才几百兆,这是为什么?

答:一个完整的Linux操作系统包含Linux内核和rootfs根文件系统和选装的很多软件所以很大; 而对于容器镜像而言,所有容器共享宿主机的Linux内核,且无选装软件,只包含了rootfs根文件系统所以很小。

问: 镜像的分层结构以及为什么要使用镜像的分层结构?

答:一个新的镜像其实是从 base 镜像一层一层叠加生成的。每安装一个软件,dockerfile中使用RUM命令,就会在现有镜像的基础上增加一层,这样一层一层的叠加最后构成整个镜像。所以我们docker pull拉取一个镜像的时候会看到docker是一层层拉去的。

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

问: 容器的copy-on-write特性,修改容器里面的内容会修改镜像吗?

答:我们知道,镜像是分层的,镜像的每一层都可以被共享,同时,镜像是只读的。当一个容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。实际上,docker hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。新的镜像是从base镜像一层一层叠加生成的,每安装一个软件,就在现有的基础增加一层 。docker镜像要采用这种分层结构是为了共享资源。

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

问题是: 如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如/etc下的文件,这时其他容器的/etc是否也会被修改??? 答案是不会

修改会被限制在单个容器内, 这就是容器copy-on-write特性

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

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

在容器层中,用户看到的是一个叠加之后的文件系统。

添加文件时:在容器中创建文件时,新文件被添加到容器层中。

读取文件:在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。

修改文件:在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。

删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

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

问: Dockerfile的整个构建镜像过程

答:

1、首先,创建一个目录用于存放应用程序以及构建过程中使用到的各个文件等;

2、然后,在这个目录下创建一个Dockerfile文件,一般建议Dockerfile的文件名就是Dockerfile;

3、编写Dockerfile文件,编写指令,如,使用FORM指令指定基础镜像,COPY指令复制文件,RUN指令指定要运行的命令,ENV设置环境变量,EXPOSE指定容器要暴露的端口,WORKDIR设置当前工作目录,CMD容器启动时运行命令,等等指令构建镜像;

4、Dockerfile编写完成就可以构建镜像了,使用`docker build -t 镜像名:tag .` 命令来构建镜像,最后一个点是表示当前目录,docker会默认寻找当前目录下的Dockerfile文件来构建镜像,如果不使用默认,可以使用-f参数来指定dockerfile文件,如:`docker build -t 镜像名:tag -f /xx/xxx/Dockerfile` ;

5、使用docker build命令构建之后,docker就会将当前目录下所有的文件发送给docker daemon,顺序执行Dockerfile文件里的指令,在这过程中会生成临时容器,在临时容器里面安装RUN指定的命令,安装成功后,docker底层会使用类似于docker commit命令来将容器保存为镜像,然后删除临时容器,以此类推,一层层的构建镜像,运行临时容器安装软件,直到最后的镜像构建成功。

问: Dockerfile构建镜像出现异常,如何排查?

答:首先,Dockerfile是一层一层的构建镜像,期间会产生一个或多个临时容器,构建过程中其实就是在临时容器里面安装应用,如果因为临时容器安装应用出现异常导致镜像构建失败,这时容器虽然被清理掉了,但是期间构建的中间镜像还在,那么我们可以根据异常时上一层已经构建好的临时镜像,将临时镜像运行为容器,然后在容器里面运行安装命令来定位具体的异常。

标签: #nginx exec format error