docker 面试题
# 1.什么是 Docker?说说你对 Docker 的了解**
docker 是一个容器化平台,可以非常方便、非常快的部署环境,打包项目
docker 是轻量级的,不需要完整的操作系统,和宿主机共享操作系统内核
docker 有良好的可移植性,可以无缝地从开发环境迁移到生产环境,不会因为不同环境的配置差异而导致问题
依赖隔离:每个容器都包含应用程序及其所有依赖,避免了与宿主系统或其他容器之间的冲突
版本控制与镜像管理:通过 Docker Hub 或私有镜像仓库(如你正在使用的 Harbor),可以轻松地存储和分发不同版本的镜像
# 2.Docker 与虚拟机有何不同?
软件架构:虚拟机虚拟机包含一个完整的操作系统,包括内核和用户空间程序;Docker 容器不需要包含完整的操作系统,只包含应用程序及其依赖,容器与宿主系统共享同一个操作系统内核,这使得容器更加轻量
启动速度:由于需要启动整个操作系统,虚拟机的启动时间较长,通常需要几分钟;因为容器与主机共享操作系统内核,容器启动速度非常快,通常只需几秒钟即可完成
可移植性:虚拟机镜像体积大,迁移和分发不如 Docker 镜像灵活,传输效率较低;Docker 镜像体积小,通常是分层的,镜像传输和分发非常方便,更易于在不同环境中部署应用
总结来说,Docker 容器的主要优势在于轻量化、快速启动,而虚拟机则提供了更强的隔离性
# 3.Docker 镜像是什么?
Docker 镜像是一个只读的模板,包含了运行容器所需的所有文件、依赖、应用程序以及其配置环境,镜像可以被用来创建 Docker 容器,容器是镜像的运行实例
分层结构:Docker 镜像是分层构建的,使用了联合文件系统(UnionFS)技术,每一层代表一次文件系统的改动(例如安装软件、配置环境变量)
只读性:镜像本身是只读的,当镜像被用来创建容器时,Docker 会为该容器创建一个可写层
轻量化:因为镜像的分层结构,当多个镜像使用相同的底层时,Docker 只需要存储一份基础层,极大地减少了存储占用
构建:镜像可以通过 Dockerfile 构建,Dockerfile 是一个包含了一系列指令的文本文件,定义了从基础镜像到应用环境的搭建过程
可移植性:镜像可以在不同的主机、云环境中部署,确保应用程序在不同环境下保持一致性
# 4.Docker 容器是什么?
Docker 容器是 Docker 镜像的实例,容器封装了应用程序运行所需的所有环境,包括代码、库、配置文件等,确保应用程序能够在不同的环境中一致地运行
容器的生命周期:
- 创建:从镜像启动一个容器实例
- 启动:运行创建的容器
- 停止:停止运行中的容器
- 删除:删除不再需要的容器实例
# 5.DockerFile 常见指令
FROM:指定基础镜像,所有操作都是基于该镜像进行的,FROM 是 Dockerfile 中的第一个指令,必须存在
RUN:在镜像构建时执行指定的命令;通常用于安装软件包或进行其他操作系统级别的配置,每执行一次 RUN 命令,都会创建一个新的镜像层
COPY:将主机文件系统中的文件或目录复制到镜像的指定路径中,用于将代码、配置文件或其他资源添加到镜像
CMD:指定容器启动时要执行的默认命令,如果用户在运行容器时没有指定其他命令,CMD 中的命令将会执行;每个 Dockerfile 只能有一个 CMD 指令,最后的 CMD 指令会覆盖前面的
ADD:用于将文件或目录从主机系统复制到 Docker 容器镜像中的指令;如果复制的文件是 .tar 格式的压缩包,ADD 会自动解压缩它,并将内容放到目标目录中
EXPOSE:声明容器要监听的端口
WORKDIR:指定容器内的工作目录,所有后续的 RUN、CMD、COPY 等指令都将在这个目录下执行
# 6.Docker 常用命令
容器、镜像、仓库、日志、进程、元数据、拷贝
大部门命令在之前的笔记已经记录了
进入容器:docker exec -itd <容器名或容器ID> /bin/bash
查看镜像/容器详情:docker inspect <镜像名或镜像ID>
构建镜像:docker build -t <镜像名>:<标签> <Dockerfile路径>
查看容器日志:docker logs <容器名或容器ID>
实时查看容器日志:docker logs -f <容器名或容器ID>
查看最近 N 行日志:docker logs --tail N <容器名或容器ID>
查看容器内运行的进程:docker top <容器名或容器ID>
从主机拷贝文件到容器:docker cp <主机文件路径> <容器名或容器ID>:<容器目标路径>
从容器拷贝文件到主机:docker cp <容器名或容器ID>:<容器文件路径> <主机目标路径>
清理未使用的镜像、容器、网络等:docker system prune -a
# 7.什么是Docker Swarm?
Docker Swarm 是 Docker 原生的集群管理和编排工具,允许用户将多个 Docker 主机集合在一起,作为一个集群来管理和调度容器
# 8.如何批量清理临时镜像文件?
清理所有的镜像文件:docker rmi -f $(docker images -q)
停止所有正在运行的容器:docker kill $(docker ps -q)
清理未使用的镜像、容器、网络等:docker system prune -a
# 9.如何查看镜像支持的环境变量
docker inspect nginx | grep -i env -A 10
# 10.本地的镜像文件都存放在哪里
Docker 在 Linux 系统中默认将所有的镜像、容器、卷等数据存储在 /var/lib/docker 目录下
镜像文件路径:/var/lib/docker/image
容器文件路径:/var/lib/docker/containers
# 11.构建Docker镜像应该遵循哪些原则?
- 尽量选取满足需求但较小的基础系统镜像
- 清理编译生成文件、安装包的缓存等临时文件
- 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖
- 从安全的角度考虑,应用尽量使用系统的库和依赖
- 使用Dockerfile创建镜像时候要添加.dockerignore文件或使用干净的工作目录
# 12.如何退出容器不终止容器
Ctrl+P+Q
# 13.如何清理批量后台停止的容器
docker rm $(docker ps -aq)
# 14.如何控制容器占用系统资源(CPU,内存)的份额
CPU 限制:
--cpus
限制 CPU 使用量:docker run --cpuset-cpus="0,1" <image>--cpuset-cpus
绑定到特定的 CPU 核心:docker run --cpu-shares=512 <image>--cpu-shares
设置 CPU 权重:docker run --cpus="1.5" <image>
内存限制:
-m
或--memory
限制最大内存使用量:docker run -m 512m <image>--memory-swap
设置内存+交换空间上限:docker run -m 512m --memory-swap=1g <image>
# 15.如何将一台宿主机的docker环境迁移到另外一台宿主机
方式1:确保在操作前停止 Docker 服务,并且注意数据的一致性
可以使用 rsync
或 scp
等工具来拷贝 /var/lib/docker
目录,将数据复制到远程宿主机
确保文件权限和所有权没有变化,然后,重新启动 Docker 服务
方式2:使用 docker 自带的命令备份镜像
docker save 备份所有的镜像,通过 docker load 导入
通过 docker inspect 查看容器的数据卷存储位置并且备份
使用 docker commit 将容器导出为镜像备份
通过 docker network ls 查看 docker 的网络设置,在新主机上手动创建同样的网络
# 16.docker-compose 是什么
用于定义和运行多容器的应用。它允许用户通过一个简单的 YAML 文件来配置应用程序的服务、网络、卷等组件,并通过一条命令将整个应用栈启动、停止和管理
# 17.面试问道docker出现oom的情况?
使用 Docker 容器时,OOM 是指容器内存不足,导致操作系统触发 "Out of Memory" 机制,强制杀掉进程来释放内存
Docker 容器 OOM 产生的原因
- 内存泄漏:容器内的应用程序存在内存泄漏,导致内存占用越来越大
- 未设置内存限制:容器没有设置内存限制,导致容器使用了宿主机的全部内存
- 宿主机内存不足:宿主机上运行多个容器时,如果没有合理分配内存,会导致 OOM
- Swap 空间不足:宿主机的 Swap 空间设置不足,无法补充内存消耗
如何解决 Docker OOM 问题
- 设置容器的内存限制:docker run -m 2g ubuntu /bin/bash
- 使用宿主机的缓存,使用卷挂载来共享宿主机上的缓存目录,减少容器内部的存储负担,从而减轻内存压力
- docker run -v /tmp/cache:/cache nginx
- 整理 Docker 系统垃圾:docker system prune -f
- 定期监控和清理 Docker 内部的资源使用情况
- docker system df
- docker system prune
- 增加宿主机的 Swap 空间
18.什么类型的应用程序无状态或有状态更适合Docker容器?
无状态应用指的是一种应用程序设计模式,在这种模式下,每个请求都是独立的,不依赖于应用之前处理的任何请求或会话状态
有状态应用会在请求间保持数据或状态(如登录会话、购物车等),需要管理和同步状态信息
无状态应用,适合容器化,易扩展、维护:API 服务、Web 服务器、负载均衡器、任务处理器
有状态应用,可以容器化,但需要额外处理数据持久化,适合与存储卷或外部存储配合使用:数据库、缓存系统、会话管理、文件存储
# 19.说下docker网络模式
bridge:这是 Docker 的默认网络模式。每个容器都会连接到一个虚拟网桥(通常是 docker0
),容器之间可以通过 IP 地址进行通信,容器内部的网络与主机隔离
host:容器将与主机共享网络堆栈,容器不会有自己独立的网络命名空间,容器会直接使用主机的网络接口,主机的 IP 地址也就是容器的 IP 地址
none:容器没有网络接口,完全与外部网络隔离
container:让一个容器与另一个容器共享网络命名空间,两个容器将共享同一个 IP 地址和端口空间,类似于同一个网络堆栈