docker课程

一、Docker 基础概念

1. 什么是 Docker

Docker 是基于 Linux 内核容器技术 的开源容器化平台; 容器:操作系统级虚拟化,共享宿主机内核,独立文件系统、网络、进程空间;

对比虚拟机:

  • 虚拟机:Hypervisor + 完整 OS,笨重、启动慢、资源开销大
  • Docker 容器:共享宿主机内核,只打包应用 + 依赖,轻量、秒级启动

2. 核心四大组件

  1. Docker Engine(引擎) :C/S 架构,后台守护进程 dockerd
  2. Docker Client(客户端)docker 命令行,和 daemon 通信
  3. Docker Registry(仓库):存放镜像,官方:Docker Hub;私有仓库:Harbor
  4. Docker Objects 对象:镜像、容器、网络、数据卷

3. 镜像 (Image) vs 容器 (Container)

  • 镜像:只读模板,分层文件系统,静态模板(类程序安装包)
  • 容器:镜像运行实例,镜像启动后生成可读写层(类进程)

一句话:镜像创建容器,一个镜像可以启动 N 个容器

4. 分层存储原理

  • 镜像由多层只读层叠加;
  • 启动容器,自动在最上层新增可读写层
  • 容器删除,仅销毁读写层,底层镜像不变;
  • 相同镜像层复用,节省磁盘空间。

5. UnionFS 联合文件系统

Docker 底层存储驱动,实现多层文件叠加,AUFS/overlay2(主流默认 overlay2)。

(如果容器要修改一个只读层里的文件: 触发 写时复制(CoW Copy-on-Write) 把文件复制一份到顶层可写层,修改副本;底层原始文件纹丝不动。)

  1. 宿主机 Linux 内核 bootfs 打底
  2. 加载一堆只读镜像层(centos→jdk→tomcat)
  3. docker run 启动容器 → 新增一层可写容器层
  4. UnionFS 把所有层联合,合成完整 rootfs 给容器使用
  5. 容器内所有文件改动全部保存在顶层读写层
  6. 执行 docker commit:读写层改动固化为新只读镜像,生成新镜像
  7. docker rm 容器:仅仅销毁顶层可写层,底层所有只读镜像保留

三、安装与基础环境

1. 系统要求

Linux 内核 ≥3.10,推荐 CentOS7+/Ubuntu18.04+; Windows/Mac 使用 Docker Desktop(内置虚拟机)

2. 核心配置文件

  • /etc/docker/daemon.json(最重要!) 常用配置:镜像加速器、日志驱动、存储驱动、代理、私有仓库 http 支持

    {
    // 配置国内镜像加速,拉镜像更快
    "registry-mirrors": "阿里云镜像地址",
    // 日志使用默认json文件方式存储
    "log-driver": "json-file",
    // 日志文件单文件上限100M,最多保存3个,防止撑爆磁盘
    "log-opts": {"max-size":"100m","max-file":"3"},
    // 使用overlay2存储驱动,管理镜像分层、容器读写层
    "storage-driver": "overlay2"
    }

生效命令

复制代码
systemctl daemon-reload
systemctl restart docker

3. 服务管理

复制代码
systemctl start docker
systemctl stop docker
systemctl enable docker
# 查看docker信息
docker info
# 查看版本
docker version

四、Docker 镜像操作命令

复制代码
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:1.25
# 列出本地镜像
docker images
# 删除镜像
docker rmi 镜像ID/镜像名
# 导出镜像(离线)
docker save -o nginx.tar nginx:1.25
# 导入镜像
docker load -i nginx.tar
# 镜像打标签
docker tag nginx:1.25 harbor.local/nginx:v1
# 推送镜像到私有仓库
docker push harbor.local/nginx:v1
# 查看镜像分层历史
docker history nginx
# 清理无用镜像
docker image prune -a

五、容器生命周期 & 容器命令

容器生命周期

创建 → 启动 → 运行 → 暂停 / 停止 → 删除

复制代码
# 创建并启动容器
docker run [参数] 镜像名

# 常用run参数
-d          # 后台运行(守护进程)
-p 宿主机端口:容器端口  # 端口映射
--name      # 指定容器名称
-v 宿主机目录:容器目录  # 数据挂载
--network   # 指定网络
-e KEY=VAL  # 设置环境变量
--restart=always # 容器退出自动重启
#容器退出之后,Docker 是否自动重启这个容器
#参数  no             不重启
       on-failure     异常退出重启
       always         无论什么原因退出,一律自动重启
       unless-stopped 手动 stop 之后,重启宿主机不会拉起

-it         # 交互式终端
--rm        # 容器停止自动删除

# 示例
docker run -d --name nginx -p 80:80 nginx

# 查看运行中容器
docker ps
# 查看所有容器(含停止)
docker ps -a

# 启动/停止/重启容器
docker start 容器名
docker stop 容器名 # 优雅关闭(10s超时)
docker kill 容器名 # 强制杀死

# 删除容器
docker rm 容器名
# 批量删除停止容器
docker container prune

# 进入运行中容器
docker exec -it nginx /bin/bash

# 查看容器日志
docker logs nginx
# 实时跟踪日志
docker logs -f --tail 100 nginx

# 查看容器资源占用
docker stats

# 容器与宿主机拷贝文件
docker cp 宿主机文件 容器名:/路径
docker cp 容器名:/路径 宿主机路径

# 查看容器详细信息(IP、挂载、配置)
docker inspect 容器名

六、Dockerfile 镜像构建(核心重点)

1. Dockerfile 构建流程

docker build -t myapp:v1 . 读取 Dockerfile → 逐层执行指令 → 生成镜像;每一条指令生成一层缓存。

2. 常用指令大全

指令 作用
FROM 基础镜像,必须第一条
MAINTAINER 维护者(废弃,推荐 LABEL)
LABEL 镜像元数据标签
ENV 设置环境变量
ARG 构建阶段临时变量(容器运行不可见)
WORKDIR 设置工作目录(自动创建)
COPY 复制宿主机文件到镜像,支持文件保留权限
ADD 复制 + 自动解压 tar 包,远程 URL 下载(不推荐优先用 COPY)
RUN 构建时执行命令,生成镜像层
CMD 容器默认启动命令,可被 run 传入参数覆盖
ENTRYPOINT 入口程序,CMD 作为参数传给它
EXPOSE 声明容器使用端口(仅文档,不会自动映射端口)
VOLUME 声明匿名数据卷
USER 指定运行用户,不要默认 root 运行
HEALTHCHECK 容器健康检查

3. CMD vs ENTRYPOINT 区别

  1. Dockerfile 中 ENTRYPOINTCMD 都是指定容器启动命令,核心区别:

  2. ENTRYPOINT :定义容器主执行程序
  3. CMD :作为默认参数传给 ENTRYPOINT;运行时传入指令可以覆盖 CMD,但不能直接覆盖 ENTRYPOINT。

另外语法分 shell 模式exec 数组模式[] ,生产统一推荐exec 数组格式 ,shell 模式会产生 shell 子进程,无法接收信号,docker stop不能优雅关闭进程。

分两种组合模式:

只有 CMDdocker run 镜像 传入参数,参数直接完全替换 CMD; ENTRYPOINT + CMD 配合:传入参数覆盖 CMD,追加给 ENTRYPOINT 执行;

4. 多阶段构建 Multi-stage(减小镜像体积)

适用:Java、Go、前端编译,编译环境和运行环境分离

复制代码
# 编译阶段
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o app main.go


# 运行阶段(只拷贝二进制,无编译环境) --from=builder  起作用 只需要编译的结果 不需要环境
FROM alpine
COPY --from=builder /app/app /usr/local/bin/
CMD ["/usr/local/bin/app"]

5. 构建缓存优化

文件变更越少,越能命中缓存; 把频繁变动代码放 Dockerfile 靠后位置;不常变动依赖靠前。

七、Docker 数据持久化(Volume)

容器删除后读写层数据丢失,三种持久化方案:

  1. Volume 数据卷(推荐) docker 管理,宿主机路径 /var/lib/docker/volumes/xxx/_data

    创建卷

    docker volume create nginx-data

    使用卷

    docker run -v nginx-data:/usr/share/nginx/html nginx

  2. Bind Mount 绑定挂载 手动指定宿主机任意目录和容器目录映射(开发常用)-v /host/html:/usr/share/nginx/html

  3. Tmpfs Mount 内存挂载 数据存内存,重启丢失,用于临时机密数据

读写权限

:ro 容器内只读 -v /host:/container:ro

数据卷命令

复制代码
docker volume ls
docker volume inspect xxx
docker volume rm xxx
# 删除未使用卷
docker volume prune

最佳实践:生产优先使用 Volume,不要直接宿主机目录挂载管理权限。

八、Docker 网络(重中之重)

Docker 内置 5 种网络驱动模式

复制代码
# 查看网络
docker network ls
# 创建自定义网络
docker network create mynet

1. bridge(默认)

默认网桥 docker0;同一 bridge 内容器互通;跨 bridge 默认不通;容器通过宿主机 SNAT 访问外网。

注意:不要使用默认 docker0,推荐自定义 bridge 网络,支持 DNS 自动解析容器名!默认的docker0 容器之间无法通过容器名访问,以前没考虑到

2. host

容器直接共享宿主机网络栈,不再端口映射;容器 IP = 宿主机 IP;隔离最弱。

3. none

关闭所有网络,无网卡,完全隔离。

4. container 复用网络

--net container:其他容器ID,和另一个容器共享网卡(sidecar 常用)

复制代码
docker run -it --name sidecar --network container:main-nginx1 alpine

新创建的容器不创建独立网络栈,直接共享另一个已有容器的:

  1. 两个容器 IP 完全一样!
  2. 端口不能冲突:A 容器占用 80 端口,复用网络的 B 容器不能再监听 80
  3. 容器之间通信:直接 127.0.0.1 互通(像本机进程)
  4. 经典场景:Sidecar 边车模式(日志采集、监控代理)

5. overlay(Swarm 集群网络)

跨主机容器通信,Docker Swarm 集群使用。

网络关键特性

  • 自定义 bridge 网络:容器之间可以直接用容器名称 DNS 通信,默认 docker0 不支持!

  • 端口映射原理:iptables DNAT

  • 外部访问容器:宿主机防火墙放行端口

    容器加入已有网络

    docker run --network mynet

    容器动态连接网络,相当于两块网卡,加入另外一个交换机

    docker network connect mynet 容器名

九、Docker Compose(单机多容器编排)

作用

通过 yaml 文件定义一组容器,一键启动 / 停止依赖服务(开发、测试环境首选) 文件默认名称 docker-compose.yml

核心命令

复制代码
# 创建并启动服务
docker-compose up -d
# 停止
docker-compose down
# 重启
docker-compose restart
# 查看日志
docker-compose logs -f
# 构建镜像
docker-compose build
# 扩缩容
docker-compose up -d --scale app=3

yaml 核心字段

复制代码
version: "3.8"
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    networks:
      - webnet
    depends_on:
      - app
    restart: always
networks:
  webnet:
volumes:
  data:

注意:depends_on 只控制启动顺序,不等待服务就绪,需要程序内部重试。

十、Docker 安全要点

  1. 尽量不以 root 用户运行容器 USER xxx

    --user test

  2. 禁用特权容器 --privileged(高危)

  3. 只读文件系统 --read-only(整个容器都不可以写,:ro只是挂载的不可以写)

  4. 资源限制:CPU、内存

    --memory 512m --cpus 0.5

  5. 镜像扫描,不要使用未信任公共镜像

  6. 宿主机内核安全,定期更新

  7. 限制 capabilities 能力 --cap-drop=ALL

  8. 不要把宿主机 docker.sock 挂载进容器(权限逃逸)

    一旦挂载,容器内可以操控宿主机docker,权限逃逸

    docker run -v /var/run/docker.sock:/var/run/docker.sock xxx

十一、资源限制

run 参数限制容器资源,防止容器耗尽宿主机资源

复制代码
# 内存限制
--memory 1g
# CPU核心
--cpus 1.5
# 内存+swap
--memory-swap 2g

十二、Docker 日志

默认驱动 json-file; 生产一定要配置日志滚动,防止磁盘打满 daemon.json 配置日志最大大小

复制代码
"log-driver": "json-file",
"log-opts": {
  "max-size": "100m",
  "max-file": "3"
}

十三、harbor私有仓库

1、下载离线安装包

复制代码
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar zxvf harbor-offline-installer-v2.10.0.tgz
cd harbor

2、复制配置模板

复制代码
cp harbor.yml.tmpl harbor.yml

3、配置 harbor.yml

设置 hostname: harbor.local

记住密码 Harbor12345

复制代码
# 修改1:主机名,不要用IP,尽量域名
hostname: harbor.local

# 修改2:https配置
#https:
 ## port: 443
 # certificate: /data/harbor/cert/harbor.crt
 # private_key: /data/harbor/cert/harbor.key

# http关闭(生产)
http:
  port: 80
  # 可选:关闭http
  # relative_url: false

# admin初始密码,务必修改
harbor_admin_password: Harbor12345

# 数据持久化目录
data_volume: /data/harbor/data

# 漏洞扫描器,启用trivy
trivy:
  enabled: true

4.测试环境 HTTP(不推荐生产)

复制代码
修改 docker daemon 配置 `/etc/docker/daemon.json`

```
{
  "insecure-registries": ["harbor.local"]
}
```

重启 docker

风险:明文传输镜像,用户名密码泄露,仅测试使用!

4、执行安装

复制代码
# 自动生成docker-compose.yml、配置文件
./install.sh

5、查看并且进入

复制代码
docker compose ps

访问:https://harbor.local 账号:admin,密码配置文件内设置

6、登录 Harbor

复制代码
docker login harbor.local
# 输入admin / 密码

7、 镜像标签规范

格式:harbor地址/项目名称/镜像名:版本

复制代码
# 原始镜像
docker pull nginx:1.24

# 重新打标签
docker tag nginx:1.24 harbor.local/library/nginx:1.24

注意:必须指定项目名,library 是 Harbor 默认公开项目

  1. 推送镜像

    docker push harbor.local/library/nginx:1.24

  2. 其他机器拉取镜像

    同样需要配置证书/insecure-registry

    docker pull harbor.local/library/nginx:1.24

相关推荐
腻害兔1 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
达子6662 小时前
第9章_HarmonyOs图解 用Java开发UI
java·ui·harmonyos
龙虾PRO3 小时前
能源与股票量化核心差异,AI全链路落地实操手册
java·面试·职场和发展
llwszx3 小时前
【Java/Go后端手撸原生Agent(第九篇):Plan-and-Execute规划模式——从“走一步看一步“到“先谋后动“】
java·python·golang·agent开发·plan模式·规划执行模式
ZJH__GO4 小时前
网络编程v2--多客户端互通
java·运维·服务器·开发语言·计算机网络
霸道流氓气质4 小时前
SpringBoot中基于 AES-GCM + KMS 密钥管理的数据加解密 Starter 实践
java·数据库·spring boot
Gofarlic_OMS4 小时前
NX浮动许可调度黑名单机制,对比两款谁更合理
java·大数据·运维·开源·制造
取谖慕12.4 小时前
Docker容器从入门到精通
docker·容器·eureka
乐观的Terry4 小时前
8、发布系统-完整流水线的核心
java·spring boot·spring·spring cloud