Files
zhuangang/topics/devops/docker/interview.md
T

4.2 KiB
Raw Blame History

id, title, type, domain, stack, tags, level, related, week
id title type domain stack tags level related week
devops.docker.interview Docker 面试题 interview devops
docker
Docker
容器
Compose
面试
basic
devops.docker.image-dockerfile
devops.docker.compose-network-volume
3
14
16

Docker 面试题

基础

【基础】容器和虚拟机有什么区别?

参考答案:虚拟机虚拟化硬件,每个虚拟机有自己完整的操作系统内核,隔离性强但启动慢、占用大;容器共享宿主机内核,靠 Linux 的 namespace 做隔离(进程、网络、文件系统等)、cgroups 限制资源,启动快、占用小,但隔离性比虚拟机弱。

【基础】镜像和容器是什么关系?镜像为什么要分层?

参考答案:镜像是只读模板,容器是镜像运行起来的实例,在镜像之上加了一个可写层。分层让多个镜像可以共享相同的底层(节省磁盘和下载),构建时没有变化的层可以复用缓存。

【基础】CMD 和 ENTRYPOINT 的区别?COPY 和 ADD 呢?

参考答案:ENTRYPOINT 指定容器启动时固定执行的程序;CMD 提供默认参数或默认命令,docker run 后面的参数会覆盖 CMD。两者都推荐使用 exec 形式(JSON 数组),程序作为 PID 1 才能收到信号。COPY 只复制本地文件;ADD 还能自动解压 tar 和下载 URL,行为不直观,一般用 COPY。

【基础】容器里的数据怎么持久化?

参考答案:容器可写层的数据随容器删除而消失。持久化用数据卷(Docker 管理的命名卷,适合数据库)或绑定挂载(把宿主机目录挂进容器,适合开发时挂源码、挂配置文件)。

进阶

【进阶】怎么减小镜像体积、加快构建?

参考答案:多阶段构建,运行阶段只保留产物;选小的基础镜像(slim、alpine、distroless);把变化少的步骤(安装依赖)放前面,充分利用层缓存;合并 RUN 并在同一层清理缓存(如 pip install --no-cache-dir);用 .dockerignore 排除无关文件。

【进阶】docker stop 时发生了什么?怎么做优雅退出?

参考答案:Docker 向容器的 PID 1 发送 SIGTERM,等待超时(默认 10 秒)后发送 SIGKILL。程序要监听 SIGTERM,停止接受新请求、处理完进行中的请求、关闭连接后退出。前提是程序本身是 PID 1(exec 形式启动),否则信号被 shell 吞掉。

【进阶】Compose 中服务之间怎么通信?depends_on 能保证依赖服务已就绪吗?

参考答案:同一个 Compose 项目的服务在同一个网络里,用服务名作为主机名访问。depends_on 默认只保证启动顺序,不保证就绪;要配合 healthcheck 和 condition: service_healthy,应用本身也要有连接重试。

场景题

【场景题】容器启动后马上退出,怎么排查?

参考答案:docker ps -a 看退出码,docker logs <容器> 看输出。常见原因:主进程是后台进程(容器以前台进程为生命周期)、配置或环境变量缺失导致程序报错退出、二进制和基础镜像不兼容(CGO 程序放进 scratch)、权限问题(非 root 用户无权读文件)。可以用 docker run -it --entrypoint sh 镜像 进入容器手动执行排查。

【场景题】应用容器连不上数据库容器,怎么排查?

参考答案:确认连接地址用的是服务名而不是 localhost;两个容器是否在同一网络(docker network inspect);数据库是否真的就绪(健康检查、日志);端口是否是容器内端口而不是宿主机映射端口;用户名密码和数据库名是否和初始化时一致(数据卷已存在时环境变量不会重新生效)。

【场景题】怎么避免把密钥打包进镜像?

参考答案:不在 Dockerfile 里写密钥,不把 .env 等文件复制进镜像(.dockerignore 排除);运行时通过环境变量或密钥管理系统(Kubernetes Secret、云厂商的密钥服务)注入;构建时确实需要的密钥(如私有依赖仓库的 token)用 BuildKit 的 --secret 挂载,不会留在镜像层里;镜像推送前用扫描工具检查。