Docker 核心知识速查笔记
·
文章目录
Docker 核心知识速查笔记 (从入门到实战)
一、核心概念速记
| 概念 | 类比 | 关键特性 | 备注 |
|---|---|---|---|
| 镜像 (Image) | Java 的 类 |
只读模板、分层存储 (UnionFS) | 包含运行所需一切,是容器的源代码 |
| 容器 (Container) | Java 的 对象 |
可读写、进程隔离、秒级启动 | 镜像的运行实例,拥有独立网络/进程空间 |
| 仓库 (Repo) | Maven/GitHub | 集中存放镜像 | Docker Hub (公), Harbor/Registry (私) |
| Docker vs VM | - | 共享内核、轻量 (MB)、秒启 | VM 是硬件虚拟化 (重),Docker 是操作系统级虚拟化 |
底层三大基石:
- Namespace:资源隔离 (PID, Net, IPC, Mnt, UTS)。
- Cgroups:资源限制 (CPU, 内存)。
- UnionFS:镜像分层 (写时复制 CoW)。
二、环境搭建
1. CentOS 7 一键安装脚本
# 1. 卸载旧版
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 2. 安装依赖 & 配置阿里云源
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装 Docker CE
yum install -y docker-ce docker-ce-cli containerd.io
# 4. 启动 & 开机自启
systemctl start docker && systemctl enable docker
# 5. 验证
docker version && docker run hello-world
2. Ubuntu 安装脚本
# 1. 卸载旧版
apt-get remove docker docker-engine docker.io containerd runc
# 2. 安装依赖
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# 3. 添加 Docker GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# 4. 添加 Docker 仓库
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 5. 安装 Docker CE
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
# 6. 启动 & 开机自启
systemctl start docker && systemctl enable docker
# 7. 验证
docker version && docker run hello-world
3. 镜像加速 (必配)
编辑 /etc/docker/daemon.json:
{
"registry-mirrors": ["https://<你的ID>.mirror.aliyuncs.com", "https://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"]
}
生效:systemctl daemon-reload && systemctl restart docker
三、高频命令速查表
1. 镜像管理 (Image)
| 操作 | 命令 | 备注 |
|---|---|---|
| 查找 | docker search <name> --limit 5 |
限制返回数量 |
| 拉取 | docker pull <name>:<tag> |
不写 tag 默认为 latest |
| 列表 | docker images |
-q 仅显示 ID, -a 显示中间层 |
| 删除 | docker rmi -f <id> |
-f 强制删除 |
| 清理 | docker image prune |
删除悬空镜像 |
| 构建 | docker build -t <name>:<tag> . |
基于 Dockerfile |
| 导入/导出 | docker save -o <file> <image> / docker load -i <file> |
备份/恢复镜像 |
2. 容器管理 (Container)
| 操作 | 命令 | 关键参数/备注 |
|---|---|---|
| 运行 | docker run [opts] <image> |
见下方详解 |
| 列表 | docker ps |
-a 所有, -q 仅 ID |
| 启动/停止 | docker start/stop/restart <id> |
kill 强制停止 |
| 删除 | docker rm -f $(docker ps -aq) |
强制删除所有容器 |
| 日志 | docker logs -f --tail 100 <id> |
-f 跟踪, --tail 行数 |
| 进入 | docker exec -it <id> bash |
推荐,新开终端 |
| 拷贝 | docker cp <id>:<path> <host_path> |
双向拷贝 |
| 详情 | docker inspect <id> |
查看 IP、挂载点等 JSON 信息 |
| 统计 | docker stats |
查看容器资源使用情况 |
3. docker run 核心参数
docker run -d \
--name my-app \
-p 8080:80 \
-v /host/data:/app/data \
--privileged=true \
--restart=always \
--network my-net \
--memory 512m \
--cpus 1 \
<image_name>
-d: 后台运行-p: 端口映射 (宿:容)-v: 数据卷挂载 (宿:容)--privileged=true: 赋予 root 权限 (解决 CentOS 挂载报错)--restart=always: 崩溃自动重启--network: 指定自定义网络--memory: 内存限制--cpus: CPU 限制
四、镜像制作 (Dockerfile)
1. 核心指令
FROM: 基础镜像 (必须第一行)RUN: 构建时执行 (安装软件),每行一层COPY/ADD: 复制文件 (ADD支持解压/URL)EXPOSE: 声明端口 (不自动映射)ENV: 设置环境变量WORKDIR: 设置工作目录CMD/ENTRYPOINT: 启动命令 (CMD可被覆盖,ENTRYPOINT不易被覆盖)VOLUME: 声明挂载点ARG: 构建时参数LABEL: 添加元数据
2. 最佳实践模板
FROM openjdk:8-jdk-alpine # 1. 使用小体积基础镜像
MAINTAINER yourname
WORKDIR /app
COPY target/my-app.jar app.jar # 2. 仅复制必要文件
ENV JAVA_OPTS="-Xms256m -Xmx256m"
EXPOSE 8080
# 3. 合并 RUN 减少层数,清理缓存
RUN apk add --no-cache curl && rm -rf /var/cache/apk/*
ENTRYPOINT ["java", "-jar", "app.jar"] # 4. 前台运行,避免容器退出
3. 多阶段构建 (Multi-stage)
# 编译阶段
FROM maven:3.8.4-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# 运行阶段
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/my-app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
五、数据持久化 (Volume)
痛点:容器删除,数据丢失。
方案:挂载宿主机目录或命名卷。
1. 常用挂载模式
# 直接挂载 (宿主机路径:容器路径)
-v /mydata/mysql/data:/var/lib/mysql
# 只读挂载
-v /config:/app/config:ro
# 继承其他容器的卷
--volumes-from <parent_container>
# 使用命名卷
docker volume create my-volume
-v my-volume:/app/data
2. 常见软件挂载清单
| 软件 | 关键挂载点 | 配置文件示例 |
|---|---|---|
| MySQL | /var/lib/mysql (数据), /etc/mysql/conf.d (配置) |
my.cnf (字符集, log-bin) |
| Redis | /data (数据), /etc/redis/redis.conf (配置) |
appendonly yes (持久化) |
| Nginx | /usr/share/nginx/html (网页), /etc/nginx (配置) |
nginx.conf |
| GitLab | /etc/gitlab, /var/log/gitlab, /var/opt/gitlab |
- |
| Elasticsearch | /usr/share/elasticsearch/data, /usr/share/elasticsearch/config |
elasticsearch.yml |
| MongoDB | /data/db, /data/configdb |
mongod.conf |
六、网络管理
1. 网络类型
| 网络类型 | 特点 | 适用场景 |
|---|---|---|
| bridge | 默认,容器间通过 IP 通信 | 单主机容器通信 |
| host | 移除网络隔离,直接使用宿主机网络 | 性能要求高的场景 |
| overlay | 跨主机通信 | Swarm/K8s 集群 |
| macvlan | 给容器分配物理 MAC 地址 | 需要物理网络环境的场景 |
| none | 无网络 | 不需要网络的场景 |
2. 网络操作命令
# 创建网络
docker network create --driver bridge my-net
# 查看网络
docker network ls
# 查看网络详情
docker network inspect my-net
# 将容器加入网络
docker network connect my-net my-container
# 将容器从网络移除
docker network disconnect my-net my-container
# 删除网络
docker network rm my-net
七、实战部署案例
1. MySQL (主从复制)
Master 配置 (my.cnf):
[mysqld]
server_id=101
log-bin=mysql-bin
binlog_format=mixed
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
Slave 配置 (my.cnf):
[mysqld]
server_id=102
relay_log=mysql-relay-bin
read_only=1
启动容器:
# Master
docker run -d --name mysql-master \
-p 3306:3306 \
-v /mydata/mysql/master/data:/var/lib/mysql \
-v /mydata/mysql/master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
# Slave
docker run -d --name mysql-slave \
-p 3307:3306 \
-v /mydata/mysql/slave/data:/var/lib/mysql \
-v /mydata/mysql/slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
连接命令 (在 Slave 执行):
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
START SLAVE;
SHOW SLAVE STATUS\G; -- 检查 Seconds_Behind_Master 是否为 0
2. Redis Cluster (3 主 3 从)
# 1. 创建网络
docker network create redis-net
# 2. 启动 6 个节点
for port in $(seq 6381 6386); do
mkdir -p /data/redis/node-$port
docker run -d --name redis-node-$port --net redis-net -p $port:6379 \
-v /data/redis/node-$port:/data \
redis:6.0.8 redis-server --cluster-enabled yes --appendonly yes --cluster-config-file nodes.conf
done
# 3. 组建集群 (在任意节点执行)
docker exec -it redis-node-6381 redis-cli --cluster create \
172.18.0.2:6379 172.18.0.3:6379 172.18.0.4:6379 \
172.18.0.5:6379 172.18.0.6:6379 172.18.0.7:6379 \
--cluster-replicas 1
3. Nginx 反向代理
配置文件 (nginx.conf):
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
启动容器:
docker run -d -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
--network my-net \
nginx:1.20
4. Spring Boot 应用
Dockerfile:
FROM openjdk:8-jdk-alpine
WORKDIR /app
COPY target/spring-boot-app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
构建并运行:
# 构建镜像
docker build -t spring-boot-app:1.0 .
# 运行容器
docker run -d --name spring-boot-app \
-p 8080:8080 \
-v /mydata/app/logs:/app/logs \
--network my-net \
spring-boot-app:1.0
八、Docker Compose (编排神器)
1. 核心结构
version: '3'
services:
web:
image: nginx
ports: ["80:80"]
volumes:
- ./html:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on: [db]
networks: [my-net]
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: mydb
volumes:
- db-data:/var/lib/mysql
networks: [my-net]
volumes:
db-data:
networks:
my-net:
driver: bridge
2. 常用命令
| 命令 | 作用 |
|---|---|
docker-compose up -d |
后台启动所有服务 |
docker-compose down |
停止并删除容器、网络 |
docker-compose ps |
查看状态 |
docker-compose logs -f |
查看实时日志 |
docker-compose restart |
重启服务 |
docker-compose build |
构建服务镜像 |
docker-compose pull |
拉取服务镜像 |
docker-compose exec <service> bash |
进入容器 |
3. 实战案例:完整的 Web 应用栈
docker-compose.yml:
version: '3'
services:
nginx:
image: nginx:1.20
ports: ["80:80"]
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
depends_on: [app]
networks: [app-net]
app:
build: ./spring-boot-app
ports: ["8080:8080"]
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 123456
depends_on: [db]
networks: [app-net]
db:
image: mysql:5.7
ports: ["3306:3306"]
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- db-data:/var/lib/mysql
networks: [app-net]
volumes:
db-data:
networks:
app-net:
driver: bridge
九、Docker Swarm (集群管理)
1. 核心概念
- 节点 (Node):集群中的主机,分为 Manager 和 Worker
- 服务 (Service):运行在集群上的容器集合
- 任务 (Task):服务的最小运行单位,一个容器实例
- 堆栈 (Stack):由多个服务组成的应用
2. 基本操作
# 初始化集群 (在 Manager 节点执行)
docker swarm init --advertise-addr <manager-ip>
# 加入集群 (在 Worker 节点执行)
docker swarm join --token <token> <manager-ip>:2377
# 查看节点
docker node ls
# 创建服务
docker service create --name web --replicas 3 -p 80:80 nginx
# 查看服务
docker service ls
# 扩展服务
docker service scale web=5
# 删除服务
docker service rm web
# 部署堆栈
docker stack deploy -c docker-compose.yml my-stack
# 查看堆栈
docker stack ls
# 删除堆栈
docker stack rm my-stack
十、故障排查与最佳实践
1. 常见问题
-
容器启动后立即退出:
- 原因:没有前台进程。
- 解决:确保 CMD/ENTRYPOINT 运行的是前台程序 (如
nginx -g 'daemon off;')。
-
挂载卷权限 denied:
- 原因:SELinux 或宿主目录权限。
- 解决:加
--privileged=true或chown -R 1000:1000 /host/path。
-
网络不通:
- 原因:防火墙或未加入同一网络。
- 解决:
firewall-cmd --zone=public --add-masquerade --permanent或使用自定义网络。
-
镜像拉取失败:
- 原因:网络问题或镜像不存在。
- 解决:配置镜像加速或检查镜像名称和标签。
2. 最佳实践
- 镜像优化:使用 Alpine 基础镜像,多阶段构建,清理缓存。
- 数据安全:敏感信息用环境变量或 Secret,不要硬编码。
- 日志管理:配置
logging-driver限制日志大小,避免占满磁盘。 - 资源限制:生产环境务必加
--memory和--cpus防止资源耗尽。 - 版本锁定:镜像 Tag 不要用
latest,指定具体版本号。 - 健康检查:为容器添加健康检查,确保服务正常运行。
- 定期清理:定期清理悬空镜像、停止的容器和未使用的卷。
- 监控告警:配置 Prometheus + Grafana 监控容器运行状态。
3. 监控与日志
Docker 自带监控:
# 查看容器资源使用情况
docker stats
# 查看容器日志
docker logs -f <container-id>
ELK 日志收集:
version: '3'
services:
elasticsearch:
image: elasticsearch:7.14.0
environment:
- discovery.type=single-node
ports: ["9200:9200"]
volumes: ["es-data:/usr/share/elasticsearch/data"]
logstash:
image: logstash:7.14.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on: [elasticsearch]
kibana:
image: kibana:7.14.0
ports: ["5601:5601"]
depends_on: [elasticsearch]
volumes:
es-data:
十一、Docker 安全
1. 安全最佳实践
- 使用官方镜像:从 Docker Hub 官方仓库拉取镜像。
- 最小化镜像:只安装必要的软件包,减少攻击面。
- 非 root 用户:在 Dockerfile 中创建非 root 用户并切换。
- 定期更新:定期更新镜像和基础系统。
- 网络隔离:使用自定义网络,限制容器间通信。
- 资源限制:设置 CPU、内存和磁盘限制。
- 只读文件系统:对不需要写入的容器使用
--read-only。 - Secret 管理:使用 Docker Secret 或外部密钥管理服务。
2. 安全扫描
使用 Trivy 扫描镜像:
# 安装 Trivy
docker pull aquasec/trivy
# 扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image <image-name>
更多推荐




所有评论(0)