Docker
一、Docker 基础
1. Docker 是什么?
Docker 是一个开源的容器化平台,用于构建、部署和运行应用程序。
核心概念:
- 镜像(Image) - 只读模板,用于创建容器
- 容器(Container) - 镜像的运行实例
- 仓库(Repository) - 存储镜像的地方
- Dockerfile - 构建镜像的脚本
2. Docker vs 虚拟机
| 特性 | Docker | 虚拟机 |
|---|---|---|
| 虚拟化级别 | 操作系统级 | 硬件级 |
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 低 | 高 |
| 隔离性 | 进程隔离 | 完全隔离 |
| 性能 | 接近原生 | 有损耗 |
| 镜像大小 | 小(MB 级) | 大(GB 级) |
3. Docker 的优势
✅ 一致性 - 开发、测试、生产环境一致
✅ 轻量级 - 资源占用小
✅ 快速部署 - 秒级启动
✅ 可移植性 - 一次构建,到处运行
✅ 版本控制 - 镜像版本管理
✅ 隔离性 - 容器间相互隔离
二、Docker 安装
1. Linux 安装
Ubuntu/Debian:
bash
# 更新包索引
sudo apt update
# 安装依赖
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加 Docker 仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker run hello-worldCentOS/RHEL:
bash
# 安装依赖
sudo yum install -y yum-utils
# 添加 Docker 仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 Docker
sudo yum install docker-ce docker-ce-cli containerd.io
# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker2. Windows 安装
Docker Desktop for Windows:
- 下载并安装 Docker Desktop
- 需要启用 Hyper-V 或 WSL 2
3. 用户组配置
bash
# 将用户添加到 docker 组(避免每次使用 sudo)
sudo usermod -aG docker $USER
# 重新登录生效三、Docker 基本命令
1. 镜像操作
搜索镜像:
bash
docker search nginx拉取镜像:
bash
docker pull nginx
docker pull nginx:1.21
docker pull nginx:latest查看镜像:
bash
docker images
docker image ls删除镜像:
bash
docker rmi image_id
docker rmi nginx
docker image rm nginx构建镜像:
bash
docker build -t myapp:1.0 .
docker build -t myapp:1.0 -f Dockerfile.prod .2. 容器操作
运行容器:
bash
docker run nginx
docker run -d nginx # 后台运行
docker run -d -p 80:80 nginx # 端口映射
docker run -d -v /data:/app nginx # 数据卷挂载
docker run -d --name mynginx nginx # 指定名称查看容器:
bash
docker ps # 运行中的容器
docker ps -a # 所有容器
docker ps -l # 最后一个容器容器操作:
bash
docker start container_id # 启动容器
docker stop container_id # 停止容器
docker restart container_id # 重启容器
docker pause container_id # 暂停容器
docker unpause container_id # 恢复容器
docker rm container_id # 删除容器
docker rm -f container_id # 强制删除运行中的容器进入容器:
bash
docker exec -it container_id /bin/bash
docker exec -it container_id /bin/sh
docker exec -it container_id sh查看日志:
bash
docker logs container_id
docker logs -f container_id # 实时查看
docker logs --tail 100 container_id # 最后 100 行查看容器信息:
bash
docker inspect container_id
docker stats container_id # 资源使用情况3. 数据卷(Volume)
创建数据卷:
bash
docker volume create myvolume查看数据卷:
bash
docker volume ls
docker volume inspect myvolume使用数据卷:
bash
docker run -d -v myvolume:/data nginx
docker run -d -v /host/path:/container/path nginx # 绑定挂载删除数据卷:
bash
docker volume rm myvolume
docker volume prune # 删除未使用的数据卷4. 网络
查看网络:
bash
docker network ls
docker network inspect network_name创建网络:
bash
docker network create mynetwork
docker network create --driver bridge mynetwork连接容器到网络:
bash
docker network connect mynetwork container_id
docker run -d --network mynetwork nginx删除网络:
bash
docker network rm mynetwork四、Dockerfile
1. Dockerfile 基础
基本结构:
dockerfile
# 基础镜像
FROM node:16-alpine
# 工作目录
WORKDIR /app
# 复制文件
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["npm", "start"]2. Dockerfile 指令
FROM:
dockerfile
FROM ubuntu:20.04
FROM node:16-alpine
FROM scratch # 空镜像WORKDIR:
dockerfile
WORKDIR /appCOPY / ADD:
dockerfile
COPY package.json ./
COPY . /app
ADD https://example.com/file.tar.gz /tmp/ # ADD 支持 URLRUN:
dockerfile
RUN apt-get update && apt-get install -y nginx
RUN npm installEXPOSE:
dockerfile
EXPOSE 80
EXPOSE 443CMD / ENTRYPOINT:
dockerfile
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["nginx", "-g", "daemon off;"]ENV:
dockerfile
ENV NODE_ENV=production
ENV APP_VERSION=1.0ARG:
dockerfile
ARG VERSION=latest
FROM node:${VERSION}3. 多阶段构建
dockerfile
# 构建阶段
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]4. .dockerignore
dockerignore
node_modules
.git
.env
*.log
dist
.DS_Store五、Docker Compose
1. Docker Compose 基础
Docker Compose 用于定义和运行多容器 Docker 应用。
安装:
bash
# Linux
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose2. docker-compose.yml
基本配置:
yaml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
networks:
- app-network
db:
image: postgres:13
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge3. Compose 命令
bash
docker-compose up # 启动服务
docker-compose up -d # 后台启动
docker-compose down # 停止并删除
docker-compose ps # 查看服务状态
docker-compose logs # 查看日志
docker-compose logs -f # 实时查看日志
docker-compose build # 构建镜像
docker-compose restart # 重启服务
docker-compose exec service sh # 进入服务容器六、.NET Core 应用 Docker 化
1. 创建 Dockerfile
dockerfile
# 构建阶段
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "./"]
RUN dotnet restore "MyApp.csproj"
COPY . .
RUN dotnet build "MyApp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish
# 运行阶段
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyApp.dll"]2. 构建和运行
bash
# 构建镜像
docker build -t myapp:1.0 .
# 运行容器
docker run -d -p 8080:80 --name myapp myapp:1.03. docker-compose.yml
yaml
version: '3.8'
services:
web:
build: .
ports:
- "8080:80"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ConnectionStrings__DefaultConnection=Server=db;Database=mydb;User=sa;Password=YourPassword123;
depends_on:
- db
db:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=YourPassword123
volumes:
- db-data:/var/opt/mssql
volumes:
db-data:七、Docker 最佳实践
1. 镜像优化
使用多阶段构建:
dockerfile
FROM node:16 AS builder
WORKDIR /app
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html使用 .dockerignore:
dockerignore
node_modules
.git
*.log使用 Alpine 镜像:
dockerfile
FROM node:16-alpine # 更小的镜像2. 安全实践
不要使用 root 用户:
dockerfile
FROM node:16-alpine
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs扫描镜像漏洞:
bash
docker scan image_name使用官方镜像:
- 优先使用官方镜像
- 定期更新基础镜像
3. 性能优化
合理使用缓存:
dockerfile
# 先复制依赖文件,利用缓存
COPY package*.json ./
RUN npm install
COPY . .减少层数:
dockerfile
# 合并 RUN 命令
RUN apt-get update && \
apt-get install -y nginx && \
rm -rf /var/lib/apt/lists/*八、常见面试题
Q1: Docker 和虚拟机的区别?
| 特性 | Docker | 虚拟机 |
|---|---|---|
| 虚拟化级别 | 操作系统级 | 硬件级 |
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 低 | 高 |
| 隔离性 | 进程隔离 | 完全隔离 |
| 性能 | 接近原生 | 有损耗 |
Q2: Docker 镜像和容器的关系?
- 镜像 - 只读模板,用于创建容器
- 容器 - 镜像的运行实例
- 一个镜像可以创建多个容器
- 容器可以提交为新的镜像
Q3: 如何优化 Docker 镜像大小?
- 使用多阶段构建 - 只保留运行时需要的文件
- 使用 Alpine 镜像 - 更小的基础镜像
- 合并 RUN 命令 - 减少镜像层数
- 使用 .dockerignore - 排除不必要的文件
- 清理缓存 - 删除构建过程中的临时文件
Q4: Docker 数据持久化?
方案:
- 数据卷(Volume) - Docker 管理
- 绑定挂载(Bind Mount) - 主机目录
- tmpfs 挂载 - 内存文件系统
Q5: Docker 网络模式?
网络模式:
- bridge - 默认,桥接网络
- host - 使用主机网络
- none - 无网络
- overlay - 跨主机网络(Swarm)
九、最佳实践
- ✅ 使用官方镜像 - 安全可靠
- ✅ 多阶段构建 - 减小镜像大小
- ✅ 使用 .dockerignore - 排除不必要文件
- ✅ 合理使用缓存 - 优化构建速度
- ✅ 不要使用 root - 安全考虑
- ✅ 定期更新 - 保持镜像最新
- ✅ 扫描漏洞 - 定期扫描镜像
- ✅ 使用标签 - 明确镜像版本
- ❌ 不要忽略安全 - 注意镜像安全
- ❌ 不要过度优化 - 平衡大小和可维护性