Docker 知识笔记
Docker 概述
- 定义:一款快速构建、运行、管理应用的工具,解决"在我机器上能运行"的问题
- 核心价值 :
- 环境一致性:开发、测试、生产环境一致
- 快速部署:一键部署应用,无需手动配置环境
- 资源隔离:容器间相互隔离,互不影响
- 轻量级:比虚拟机更轻量,启动更快
Docker 核心概念
镜像与容器
| 概念 | 说明 | 作用 |
|---|---|---|
| 镜像(Image) | 只读模板,包含应用程序及其依赖 | 构建容器的基础 |
| 容器(Container) | 镜像的运行实例,可理解为一个轻量级虚拟机 | 运行应用程序的环境 |
💡 关键点:
- 镜像类似于"类",容器是"实例"
- 容器是镜像的运行时表现
镜像仓库
- Docker Hub:Docker官方公共仓库(hub.docker.com)
- 私有仓库:企业可搭建私有镜像仓库(如Harbor)
- 镜像命名格式 :
Repository:TAG(如nginx:alpine)
数据卷(Volume)
- 定义:虚拟目录,用于在宿主机和容器之间映射数据
- 作用 :
- 持久化容器产生的数据(避免容器删除导致数据丢失)
- 共享数据给多个容器
- 方便修改容器内文件(无需进入容器)
💡 数据卷 vs 本地目录挂载:
- 数据卷 :由Docker管理,路径在
/var/lib/docker/volumes/,适合生产环境- 本地目录:直接挂载宿主机路径,适合开发调试
Docker 常用命令
镜像操作
| 命令 | 说明 | 示例 |
|---|---|---|
docker pull |
从镜像仓库拉取镜像 | docker pull nginx:alpine |
docker images |
列出本地镜像 | docker images |
docker build |
通过Dockerfile构建镜像 | docker build -t myapp:1.0 . |
docker rmi |
删除本地镜像 | docker rmi nginx:alpine |
容器操作
| 命令 | 说明 | 示例 |
|---|---|---|
docker run |
创建并启动容器 | docker run -d -p 8080:80 nginx |
docker ps |
列出运行中的容器 | docker ps |
docker stop |
停止容器 | docker stop nginx-container |
docker start |
启动已停止的容器 | docker start nginx-container |
docker rm |
删除容器 | docker rm nginx-container |
docker exec |
进入运行中的容器 | docker exec -it nginx-container bash |
数据卷操作
| 命令 | 说明 | 示例 |
|---|---|---|
docker volume ls |
列出所有数据卷 | docker volume ls |
docker volume create |
创建数据卷 | docker volume create mysql-data |
docker volume inspect |
查看数据卷详情 | docker volume inspect mysql-data |
docker volume rm |
删除数据卷 | docker volume rm mysql-data |
Docker 网络
默认网络模式
| 网络模式 | 说明 | 适用场景 |
|---|---|---|
| bridge | Docker默认网络,容器间通过IP通信 | 单个容器部署 |
| host | 使用宿主机网络,容器与宿主机共享网络 | 高性能网络应用 |
| none | 容器没有网络 | 安全性要求高的场景 |
自定义网络
- 创建网络 :
docker network create my-network - 容器连接网络 :
docker network connect my-network container-name - 优势 :容器可以通过容器名 互相访问(如
mysql、app)
💡 关键点:
- 自定义网络是实现多容器应用通信的最佳实践
- 默认bridge网络中,容器只能通过IP通信,不推荐使用
Docker 项目部署
前端部署(Nginx)
部署步骤
-
创建数据卷/本地目录:
bashmkdir -p /root/tlias-nginx/html mkdir -p /root/tlias-nginx/conf -
上传前端资源:
- 将打包后的前端静态资源放入
/root/tlias-nginx/html - 将Nginx配置文件放入
/root/tlias-nginx/conf
- 将打包后的前端静态资源放入
-
启动Nginx容器:
bashdocker run -d \ --name tlias-nginx \ -p 80:80 \ -v /root/tlias-nginx/html:/usr/share/nginx/html \ -v /root/tlias-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ nginx:alpine
Nginx 配置示例(nginx.conf)
nginx
server {
listen 80;
server_name localhost;
client_max_body_size 10m;
location / {
root html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
rewrite ^/api/(.*) $1 break;
proxy_pass http://backend:8080;
}
}
后端部署(Java应用)
部署步骤
-
准备Java应用:
- 修改配置文件(数据库地址、日志路径等)
- 打包为JAR文件(如
tlias-web-management.jar)
-
编写Dockerfile:
Dockerfile# 基础镜像 FROM openjdk:17 # 设置环境变量 ENV APP_HOME=/app # 创建应用目录 RUN mkdir -p $APP_HOME # 复制JAR文件 COPY tlias-web-management.jar $APP_HOME/app.jar # 设置工作目录 WORKDIR $APP_HOME # 暴露端口 EXPOSE 8080 # 启动命令 ENTRYPOINT ["java", "-jar", "app.jar"] -
构建镜像:
bashdocker build -t tlias-backend:1.0 . -
启动容器:
bashdocker run -d \ --name tlias-backend \ --network my-network \ -p 8080:8080 \ -v /root/tlias-backend/logs:/app/logs \ tlias-backend:1.0
数据库部署(MySQL)
部署步骤
-
创建数据卷:
bashdocker volume create mysql-data -
启动MySQL容器:
bashdocker run -d \ --name mysql \ --network my-network \ -p 3307:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=123 \ -v mysql-data:/var/lib/mysql \ mysql:8
💡 关键点:
- 通过
--network my-network将MySQL容器加入自定义网络- 通过
-v mysql-data:/var/lib/mysql持久化数据库数据- 通过
--name mysql使其他容器能通过mysql域名访问
Docker Compose
什么是 Docker Compose?
- 定义 :使用一个YAML文件(
docker-compose.yml)定义和运行多容器应用 - 优势 :
- 简化多容器应用的部署和管理
- 一个命令启动/停止整个应用
- 便于版本控制和团队协作
Docker Compose 文件结构
yaml
version: '3.8' # Compose文件版本
services: # 定义服务
backend:
build: ./backend # 构建上下文
ports:
- "8080:8080"
networks:
- my-network
volumes:
- ./backend/logs:/app/logs
frontend:
image: nginx:alpine
ports:
- "80:80"
networks:
- my-network
volumes:
- ./frontend/html:/usr/share/nginx/html
- ./frontend/conf/nginx.conf:/etc/nginx/nginx.conf
mysql:
image: mysql:8
ports:
- "3307:3306"
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
volumes: # 定义数据卷
mysql-data:
networks: # 定义网络
my-network:
driver: bridge
Docker Compose 命令
| 命令 | 说明 |
|---|---|
docker-compose up -d |
启动所有服务(后台运行) |
docker-compose down |
停止并删除所有服务 |
docker-compose build |
重新构建所有服务 |
docker-compose logs |
查看所有服务日志 |
docker-compose ps |
查看所有服务状态 |
补充章节:Docker 面试核心知识点
1. Docker 与虚拟机的区别
| 特性 | Docker | 虚拟机 |
|---|---|---|
| 隔离级别 | 进程级隔离 | 硬件级隔离 |
| 资源占用 | 几MB-几十MB | 几GB |
| 启动速度 | 秒级 | 分钟级 |
| 依赖 | 依赖宿主机内核 | 依赖完整操作系统 |
| 适用场景 | 应用部署、微服务 | 需要完整操作系统的场景 |
💡 面试要点:Docker是容器化技术,基于Linux内核的cgroups和namespaces实现,比虚拟机更轻量、启动更快。
2. Docker 镜像的分层结构
- 分层原理:镜像由多层组成,每层对应Dockerfile中的一条指令
- 优势 :
- 共享层:多个镜像可以共享相同的基础层
- 快速构建:修改后只需重新构建变化的层
- 节省空间:只存储变化的部分
💡 示例 :
FROM centos:7→ 1层
RUN yum install -y java→ 2层
COPY app.jar /app→ 3层
3. Dockerfile 最佳实践
| 最佳实践 | 说明 | 示例 |
|---|---|---|
| 最小化镜像 | 使用最小基础镜像 | FROM alpine(而非FROM ubuntu) |
| 多阶段构建 | 分离构建和运行阶段 | FROM maven AS build 和 FROM openjdk AS runtime |
| 使用 .dockerignore | 排除不需要的文件 | 避免将.git、.env等敏感文件打包进镜像 |
| 避免安装不必要的包 | 减少镜像大小 | RUN apt-get install -y --no-install-recommends java |
| 设置工作目录 | 提高可读性 | WORKDIR /app |
| 使用非root用户 | 提高安全性 | RUN useradd -m appuser 和 USER appuser |
4. Docker 网络模式对比
| 网络模式 | 通信方式 | 适用场景 | 安全性 |
|---|---|---|---|
| bridge | IP通信 | 单个容器 | 低 |
| host | 共享宿主机网络 | 高性能网络应用 | 低 |
| none | 无网络 | 安全性要求高的应用 | 高 |
| 自定义网络 | 容器名通信 | 多容器应用 | 中 |
💡 面试要点 :在微服务架构中,自定义网络是容器间通信的最佳实践,避免了IP依赖问题。
5. Docker 数据卷的使用场景
| 场景 | 说明 | 优势 |
|---|---|---|
| 数据库持久化 | 保存数据库数据 | 避免容器删除导致数据丢失 |
| 日志持久化 | 保存应用日志 | 方便日志分析和排查问题 |
| 配置文件共享 | 共享配置文件 | 避免在容器内修改配置 |
| 文件共享 | 共享文件给多个容器 | 例如:前端资源给Nginx容器 |
6. Docker Compose 与 Kubernetes 对比
| 特性 | Docker Compose | Kubernetes |
|---|---|---|
| 复杂度 | 低 | 高 |
| 适用场景 | 开发环境、小型应用 | 生产环境、大型微服务 |
| 管理能力 | 单机管理 | 集群管理 |
| 自动扩展 | 不支持 | 支持 |
| 服务发现 | 基于容器名 | 基于DNS |
| 学习曲线 | 简单 | 复杂 |
💡 面试要点:Docker Compose适合开发和测试环境,Kubernetes适合生产环境的集群管理。
7. Docker 安全最佳实践
- 避免使用root用户:在Dockerfile中使用非root用户运行应用
- 最小化镜像:只包含必要的组件
- 定期更新基础镜像:修复安全漏洞
- 限制容器权限 :使用
--cap-drop和--read-only等参数 - 使用安全扫描工具:如Trivy、Clair扫描镜像漏洞
- 限制网络访问:通过防火墙和网络策略限制容器间通信
💡 面试高频问题:
- 为什么Docker容器不建议使用root用户运行?
- Docker镜像分层结构对安全有什么影响?
- 如何防止Docker容器被攻击?
- 为什么说Docker是安全的?(需结合具体场景回答)