4.2 KiB
id, title, type, domain, stack, tags, level, related, week
| id | title | type | domain | stack | tags | level | related | week | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| devops.docker.interview | Docker 面试题 | interview | devops |
|
|
basic |
|
|
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 挂载,不会留在镜像层里;镜像推送前用扫描工具检查。