Docker面试
1. Docker和虚拟机的本质区别是啥?
这问题基本是必问的。很多人会回答“Docker轻量,虚拟机笨重”,但面试官想听的是更深层的技术原理。核心在于资源隔离的实现方式不同。
虚拟机(VM)是通过Hypervisor在物理硬件上虚拟出一整套完整的操作系统环境,包括内核、系统库、应用等,每个VM都有自己的操作系统内核。而Docker容器是使用Linux内核的Cgroups(控制资源使用)和Namespace(隔离资源视图)技术,实现进程级别的隔离,所有容器共享宿主机的内核。
简单比喻:VM是独栋别墅,Docker是合租公寓里的独立房间。别墅有自己的地基和整体结构,而公寓房间共享地基和主体结构,只是内部做了隔断。
2. 解释一下Docker镜像的分层结构
Docker镜像采用Union File System(联合文件系统),将镜像分为多层,每一层都是只读的。当你构建一个新镜像时,会在基础镜像之上添加新的可读层。这种设计的最大好处是资源共享和存储效率。
比如,如果你有10个基于Ubuntu的镜像,那么宿主机只需要存储一份Ubuntu基础层。当容器启动时,Docker会在最顶层添加一个可写的容器层,所有对文件的修改都发生在这个可写层。当容器删除时,这个可写层也会随之删除,底层镜像保持不变。
3. 如何减小Docker镜像的体积?
这是个非常实际的问题。小镜像意味着更快的传输和部署。常用技巧:
使用Alpine Linux等轻量级基础镜像
多阶段构建(Multi-stage build):在Dockerfile中使用多个FROM语句,前一个阶段用于编译构建,后一个阶段只复制必要的运行文件,丢弃中间层
合并RUN指令,减少镜像层数
使用.dockerignore文件排除不必要的文件
清理不必要的安装包和缓存
4. Docker网络模式有哪几种?
Docker默认提供五种网络模式:
bridge:默认模式,为每个容器分配独立的网络命名空间
host:容器直接使用宿主机的网络栈
none:禁用网络功能
container:共享另一个容器的网络命名空间
自定义网络:用户自定义的bridge网络,提供更好的容器间通信
实际生产中,自定义网络用得比较多,因为它提供了自动DNS解析功能,容器间可以通过容器名直接通信。
5. 数据持久化怎么实现?
容器本身是无状态的,数据持久化主要通过:
Bind Mount:直接将宿主机的目录挂载到容器
Volume:由Docker管理的存储卷,生命周期独立于容器
tmpfs mount:将数据存储在宿主机的内存中
Volume是生产环境推荐的方式,因为它不依赖于宿主机的目录结构,更容易备份和迁移。
6. Dockerfile中的COPY和ADD有啥区别?
这问题看似简单,但很多人答不全。两者都用于复制文件,但ADD功能更多:
ADD支持从URL下载文件并复制到镜像
ADD会自动解压tar压缩包
COPY只能从构建上下文复制本地文件
最佳实践是:除非需要自动解压或从URL下载,否则优先使用COPY,因为它更透明、更可预测。
7. 如何查看容器内运行的进程?
命令可以查看,这实际上是通过读取宿主机的/proc文件系统实现的,因为容器内的进程在宿主机上是可见的。
8. Docker Compose和Docker Swarm的区别
Compose主要用于定义和运行多容器应用,适合开发和测试环境。Swarm是Docker原生的集群管理工具,提供容器编排功能,适合生产环境。现在Kubernetes已经成为容器编排的事实标准,但了解Swarm仍然有助于理解编排的基本概念。
9. 容器退出后,如何查看其日志?
使用命令。Docker默认将容器的标准输出和错误输出收集起来,即使容器已退出,只要没有手动删除容器,日志仍然可以查看。
10. 实际工作中遇到的Docker问题
这个问题考察实际经验。可以讲镜像构建优化、网络配置问题、存储驱动选择、资源限制设置等。比如我曾遇到容器内存泄漏导致整个宿主机OOM(Out of Memory)的情况,后来通过设置参数限制容器内存使用解决了问题。
最后给个建议:Docker的知识点比较杂,理解其底层原理比死记硬背命令更重要。面试时如果能结合实际场景讲解,效果会好很多。祝各位面试顺利,拿到心仪的offer!
更多推荐
所有评论(0)