Docker 基础操作
安装
# Ubuntu / Debian
curl -fsSL https://get.docker.com | sh
# 添加当前用户到 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 重新登录生效
# CentOS / RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker && sudo systemctl enable docker
# 验证安装
docker version
docker info
配置镜像加速(国内环境)
/etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://registry.docker-cn.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
sudo systemctl daemon-reload
sudo systemctl restart docker
镜像管理
# === 搜索 ===
docker search nginx
# === 拉取 ===
docker pull nginx # 拉取 latest
docker pull nginx:1.25-alpine # 指定版本
docker pull registry.example.com/myapp:v1 # 私有仓库
# === 查看 ===
docker images # 列出本地镜像
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
docker image inspect nginx # 镜像详细信息
docker history nginx # 查看镜像层
# === 标签 ===
docker tag nginx:latest myregistry/nginx:v1
# === 推送 ===
docker login myregistry.com
docker push myregistry/nginx:v1
# === 删除 ===
docker rmi nginx:latest # 删除指定镜像
docker image prune # 删除悬空镜像(dangling)
docker image prune -a # 删除所有未使用的镜像
# === 导出/导入 ===
docker save nginx:latest > nginx.tar # 导出
docker load < nginx.tar # 导入
容器生命周期
容器操作
# === 创建并运行 ===
docker run -d \
--name myapp \
-p 8080:80 \
-v /host/data:/app/data \
-e ENV_VAR=value \
--restart unless-stopped \
nginx:1.25-alpine
# 常用参数:
# -d 后台运行
# --name 容器名
# -p 端口映射(宿主机:容器)
# -v 挂载卷(宿主机:容器)
# -e 环境变量
# --restart 重启策略(no/always/unless-stopped/on-failure)
# --memory 内存限制
# --cpus CPU 限制
# --network 指定网络
# --rm 退出时自动删除
# === 查看 ===
docker ps # 运行中的容器
docker ps -a # 所有容器
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# === 进入容器 ===
docker exec -it myapp /bin/sh # 进入容器终端
docker exec myapp cat /etc/hosts # 在容器中执行命令
# === 日志 ===
docker logs myapp # 查看日志
docker logs -f myapp # 持续查看(类似 tail -f)
docker logs --tail 100 myapp # 最新 100 行
docker logs --since "2024-01-01" myapp # 指定时间后的日志
# === 状态信息 ===
docker inspect myapp # 容器详细信息
docker stats # 实时资源使用(CPU/内存/网络/IO)
docker top myapp # 容器中的进程
# === 停止/删除 ===
docker stop myapp # 优雅停止(发 SIGTERM,10s 后 SIGKILL)
docker stop -t 30 myapp # 延长等待时间
docker kill myapp # 强制杀死(SIGKILL)
docker rm myapp # 删除已停止的容器
docker rm -f myapp # 强制删除运行中的容器
# === 批量操作 ===
docker stop $(docker ps -q) # 停止所有容器
docker rm $(docker ps -aq) # 删除所有容器
docker system prune -a # 清理所有未使用的资源(慎用)
容器资源限制
# 内存限制
docker run -d --memory=512m --memory-swap=1g nginx
# CPU 限制
docker run -d --cpus=1.5 nginx # 最多使用 1.5 核
docker run -d --cpu-shares=512 nginx # CPU 权重(默认 1024)
# IO 限制
docker run -d --device-write-bps /dev/sda:10mb nginx
# 查看容器资源使用
docker stats --no-stream --format \
"table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
重启策略
| 策略 | 说明 |
|---|---|
no | 不自动重启(默认) |
always | 总是重启(包括手动 stop 后、Docker daemon 重启后) |
unless-stopped | 除非手动 stop,否则自动重启 |
on-failure[:max] | 非零退出码时重启,可限制最大次数 |
生产环境推荐
一般使用 unless-stopped 或 on-failure:3。always 可能导致故障容器反复重启,消耗资源。
容器文件操作
# 从容器复制文件到宿主机
docker cp myapp:/app/config.json ./config.json
# 从宿主机复制文件到容器
docker cp ./config.json myapp:/app/config.json
# 查看容器文件系统变化
docker diff myapp
# A = 新增 C = 修改 D = 删除
镜像分层原理
Copy-on-Write (CoW)
- 镜像层是只读的,多个容器共享
- 容器修改文件时,先复制到可写层再修改
- 这就是为什么容器启动快、占用空间小
- 删除容器时,可写层随之销毁
常见面试问题
Q1: Docker 容器和虚拟机的区别?
答案:
容器使用 Linux Namespace 做隔离、Cgroup 做资源限制,共享宿主机内核,是进程级隔离。虚拟机通过 Hypervisor 虚拟化硬件,运行完整的 Guest OS,是硬件级隔离。
容器优势:启动快(秒级)、体积小(MB 级)、性能接近原生、密度高。 虚拟机优势:隔离更彻底、安全性更高、可运行不同内核。
Q2: docker run 和 docker exec 的区别?
答案:
docker run:创建并启动一个新容器docker exec:在已运行的容器中执行命令
docker exec -it container /bin/sh 是进入容器调试的常用方式。
Q3: docker stop 和 docker kill 的区别?
答案:
docker stop:先发 SIGTERM 信号允许进程优雅退出,超时(默认 10s)后发 SIGKILLdocker kill:直接发 SIGKILL 信号,强制终止
生产环境应优先使用 docker stop,给应用时间完成清理工作(关闭连接、写入缓存等)。
Q4: Docker 镜像的分层原理?为什么这样设计?
答案:
Docker 镜像由多个只读层组成(UnionFS 联合文件系统),每个 Dockerfile 指令生成一层。容器运行时在最上面加一个可写层。
好处:
- 共享层:相同的 base 层可以被多个镜像/容器共享,节省磁盘
- 增量构建:修改代码只需重建变化的层,加速构建
- 增量传输:拉取镜像时只下载缺失的层