一、Docker 概述
Docker是一个开源的应用容器引擎,基于Go语言开发,并遵循Apache2.0协议开源。Docker允许开发者将应用以及依赖包打包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux、Windows或Mac机器上,也可以实现虚拟化。容器完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。
二、Docker与虚拟机的区别
Docker与虚拟机是两种不同的虚拟化技术,它们在架构、性能、资源使用和隔离级别等方面有显著区别。
-
架构差异
- 虚拟机(VM):
- 硬件级虚拟化:每个虚拟机包括完整的操作系统、应用程序以及相关的库和依赖。
- 隔离级别:每个虚拟机之间以及虚拟机与宿主机之间完全隔离,安全性高。
- Docker(容器):
- 操作系统级虚拟化:容器共享宿主机的操作系统内核,但每个容器运行在独立的用户空间中。容器包括应用程序及其依赖,但不需要完整的操作系统。Docker引擎运行在宿主机操作系统上,负责管理容器。
- 隔离级别:容器之间通过命名空间(Namespace)和控制组(cgroups)进行隔离,但共享内核,因此隔离级别比虚拟机低。
- 虚拟机(VM):
-
性能比较
- 虚拟机(VM):
- 启动速度较慢(分钟级),因为需要启动整个操作系统。
- 资源消耗较大,每个虚拟机都需要分配独立的资源(内存、CPU等),并且有额外的操作系统开销。
- 性能有损失,因为应用程序运行在虚拟硬件上,需要通过Hypervisor层。
- Docker(容器):
- 启动速度极快(秒级甚至毫秒级),因为容器直接运行在宿主机内核上,无需启动操作系统。
- 资源消耗小,多个容器共享宿主机内核,没有额外的操作系统开销。
- 性能接近原生,因为容器直接运行在宿主机上,没有虚拟硬件层。
- 虚拟机(VM):
-
资源使用效率
- 虚拟机(VM):
- 每个虚拟机都需要完整的操作系统,因此占用磁盘空间大(通常几GB到几十GB)。
- 内存占用也大,因为每个虚拟机都要运行操作系统进程。
- Docker(容器):
- 容器共享宿主机内核,只需要存储应用程序及其依赖,因此镜像体积小(通常几MB到几百MB)。
- 内存占用少,因为多个容器可以共享宿主机的操作系统内核。
- 虚拟机(VM):
-
隔离性和安全性
- 虚拟机(VM):
- 完全隔离,每个虚拟机有独立的操作系统和内核,一个虚拟机的崩溃不会影响其他虚拟机或宿主机。
- 安全性高,攻击者需要先突破虚拟机,然后再突破Hypervisor才能访问宿主机。
- Docker(容器):
- 隔离性相对较弱,虽然容器之间通过命名空间隔离,但共享内核,因此内核漏洞可能影响所有容器。
- 安全性较低,如果容器内的应用程序获得宿主机内核的访问权限,可能会影响其他容器和宿主机。
- 虚拟机(VM):
-
可移植性
- 虚拟机(VM):
- 虚拟机镜像通常较大,迁移和分发不如容器方便。
- 虚拟机可以在不同Hypervisor上运行,但可能需要调整配置。
- Docker(容器):
- 容器镜像轻量,易于分发和迁移,适合持续集成和持续部署(CI/CD)。
- 容器可以在任何安装Docker引擎的宿主机上运行,保证了环境一致性。
- 虚拟机(VM):
-
使用场景
- 虚拟机(VM):
- 适合运行不同操作系统的应用程序(例如在Linux服务器上运行Windows应用)。
- 需要完全隔离的环境,如多租户环境、安全要求高的场景。
- 遗留系统迁移,或者需要模拟完整硬件环境的情况。
- Docker(容器):
- 微服务架构,每个服务运行在独立的容器中,便于扩展和管理。
- DevOps实践,实现快速部署和弹性伸缩。
- 云原生应用,容器可以轻松在云环境中部署和迁移。
- 虚拟机(VM):
三、Docker 的核心优势
- 轻量级:共享主机内核,无需完整操作系统
- 可移植性:一次构建,到处运行
- 隔离性:进程、网络、文件系统隔离
- 快速部署:秒级启动和停止
- 版本控制:支持镜像版本管理
- 生态丰富:Docker Hub 提供海量镜像
四、Docker核心概念
4.1 镜像(Image)
4.1.1 定义
Docker 镜像是只读的模板,包含了运行应用程序所需的一切:
- 操作系统(精简版)
- 运行时环境
- 应用程序代码
- 依赖库
- 配置文件
- 环境变量
4.1.2 镜像的核心特性
-
只读性
bash# 镜像是不可变的 docker pull ubuntu:20.04 # 下载的镜像不能修改 # 基于镜像创建容器时,会添加一个可写层 +---------------------+ | 容器可写层 | ← 容器层(可修改) +---------------------+ | 镜像只读层 | ← 镜像层(不可变) +---------------------+ -
分层存储(Layer)
bash# Dockerfile 示例 FROM ubuntu:20.04 # 第1层:基础镜像 RUN apt-get update # 第2层:执行命令 COPY app.py /app/ # 第3层:添加文件 RUN pip install flask # 第4层:安装依赖 CMD ["python", "app.py"] # 第5层:启动命令分层优势:
- 共享存储:多个镜像共享相同的基础层
- 快速构建:只重新构建变化的层
- 节省空间:相同层只存储一次
bash镜像 myapp:v1 ├── Layer 4: CMD ["python", "app.py"] (2KB) ├── Layer 3: RUN pip install flask (15MB) ├── Layer 2: COPY app.py /app/ (5KB) └── Layer 1: FROM ubuntu:20.04 (72MB) 镜像 myapp:v2 ├── Layer 5: COPY config.json /app/ (3KB) ← 新增 ├── Layer 4: CMD ["python", "app.py"] (2KB) ← 共享 ├── Layer 3: RUN pip install flask (15MB) ← 共享 ├── Layer 2: COPY app.py /app/ (5KB) ← 共享 └── Layer 1: FROM ubuntu:20.04 (72MB) ← 共享
4.1.3 镜像的生命周期
bash
# 1. 编写 Dockerfile
# 2. 构建镜像
docker build -t myapp:1.0 .
# 3. 查看本地镜像
docker images
# 4. 推送镜像到仓库
docker push myregistry.com/myapp:1.0
# 5. 拉取镜像
docker pull myregistry.com/myapp:1.0
# 6. 运行容器
docker run myapp:1.0
# 7. 删除镜像
docker rmi myapp:1.0
4.1.4 镜像操作命令
-
基本操作
bash# 查看本地镜像 docker images docker image ls # 搜索镜像 docker search nginx # 拉取镜像 docker pull ubuntu:20.04 docker pull nginx:alpine # 删除镜像 docker rmi ubuntu:20.04 docker image rm nginx:alpine # 删除所有未使用镜像 docker image prune -a -
镜像标签管理
bash# 添加标签 docker tag ubuntu:20.04 myregistry.com/ubuntu:latest docker tag myapp:1.0 myapp:production # 查看镜像历史 docker history ubuntu:20.04 # 导出镜像 docker save ubuntu:20.04 > ubuntu.tar # 导入镜像 docker load < ubuntu.tar # 导出容器为镜像 docker export container_id > container.tar -
镜像构建与优化
bash# 构建镜像 docker build -t myapp:1.0 . docker build -t myapp:1.0 -f Dockerfile.prod . # 查看构建过程 docker build --progress=plain . # 多阶段构建 docker build -t myapp:multi-stage . # 构建参数 docker build --build-arg VERSION=1.0 .
4.2 容器(Container)
4.2.1 定义
Docker 容器是镜像的运行实例,是一个轻量级、可执行的软件包,包含:
- 应用程序及其所有依赖项
- 独立的文件系统
- 网络配置
- 进程空间
- 资源限制
4.2.2 容器的核心特性
-
轻量级
bash# 与传统虚拟机对比 +-----------------------------+ | 虚拟机:重量级隔离 | | +-----------------------+ | | | Guest OS | | | | +-----------------+ | | | | | App | | | | | +-----------------+ | | | +-----------------------+ | +-----------------------------+ 启动时间:分钟级 | 内存:GB级 +-----------------------------+ | Docker容器:轻量级隔离 | | +-----------------------+ | | | App | | | +-----------------------+ | +-----------------------------+ 启动时间:秒级 | 内存:MB级 -
隔离性
bash# Linux 内核特性实现隔离 1. Namespaces:进程、网络、挂载点隔离 2. Cgroups:CPU、内存、磁盘I/O限制 3. UnionFS:分层文件系统 # 查看容器命名空间 ls -la /proc/<container-pid>/ns/
4.2.3 容器的生命周期
-
生命周期状态
bash创建(Created) → 运行(Running) → 暂停(Paused) ↓ ↓ ↓ → 停止(Stopped) → 删除(Deleted) -
状态转换命令
bash# 完整生命周期管理 docker create --name mycont nginx:alpine # 创建 docker start mycont # 启动 docker pause mycont # 暂停 docker unpause mycont # 恢复 docker stop mycont # 停止(优雅停止) docker kill mycont # 强制停止 docker restart mycont # 重启 docker rm mycont # 删除
4.2.4 容器操作命令
-
基础操作
bash# 运行容器 docker run -d --name web nginx:alpine # 运行并进入交互模式 docker run -it --name ubuntu ubuntu:20.04 bash # 查看运行中的容器 docker ps # 查看所有容器(包括停止的) docker ps -a # 查看容器详情 docker inspect web # 查看容器日志 docker logs web docker logs -f web # 实时查看 docker logs --tail 100 web # 最后100行 -
容器控制
bash# 进入运行中的容器 docker exec -it web bash docker exec -it web sh docker exec -it web /bin/bash # 在容器内执行命令(不进入) docker exec web ls -la /usr/share/nginx/html docker exec web ps aux # 复制文件 docker cp index.html web:/usr/share/nginx/html/ docker cp web:/var/log/nginx/access.log ./nginx.log # 重命名容器 docker rename web nginx-server -
资源监控
bash# 查看容器资源使用 docker stats docker stats --no-stream # 单次查看 docker stats web # 指定容器 # 查看容器进程 docker top web # 查看容器端口映射 docker port web # 查看容器元数据 docker inspect web | grep -A 10 "NetworkSettings"
4.2.5 容器运行参数详解
-
基础运行选项
bash# 完整的运行示例 docker run -d \ # 后台运行 --name myapp \ # 容器名称 --hostname app-server \ # 主机名 --restart unless-stopped \ # 重启策略 -p 8080:80 \ # 端口映射 -p 443:443 \ -v /data:/var/lib/app \ # 数据卷挂载 -e DATABASE_URL=postgres://... \ # 环境变量 --memory="512m" \ # 内存限制 --cpus="1.5" \ # CPU限制 --network my-network \ # 网络 myapp:latest # 镜像 -
端口映射
bash# 基本端口映射 docker run -p 80:80 nginx # 绑定特定IP docker run -p 127.0.0.1:80:80 nginx # 随机端口 docker run -p 80 nginx # 多端口映射 docker run -p 8080:80 -p 8443:443 nginx # UDP端口 docker run -p 53:53/udp dns-server -
环境变量
bash# 单个环境变量 docker run -e MY_VAR=value myapp # 多个环境变量 docker run -e VAR1=value1 -e VAR2=value2 myapp # 从文件读取 docker run --env-file .env myapp # 传递主机环境变量 docker run -e HOME myapp -
资源限制
bash# CPU限制 docker run --cpus=0.5 myapp # 最多使用0.5个CPU核心 docker run --cpuset-cpus="0,2" myapp # 绑定到特定CPU核心 # 内存限制 docker run --memory="512m" myapp # 内存限制512MB docker run --memory-swap="1g" myapp # 交换分区限制 docker run --memory-reservation="256m" myapp # 内存软限制 # 磁盘I/O限制 docker run --device-write-bps /dev/sda:10mb myapp -
重启策略
bash# 自动重启策略 docker run --restart no # 不自动重启(默认) docker run --restart on-failure # 失败时重启 docker run --restart on-failure:5 # 最多重启5次 docker run --restart always # 总是重启 docker run --restart unless-stopped # 除非手动停止,否则重启
4.3 仓库(Repository)
4.3.1 定义
Docker 仓库是存储和分发 Docker 镜像的中心化服务,类似代码仓库(Git),但专门用于 Docker 镜像。
4.3.2 核心概念
bash
镜像仓库生态系统:
仓库(Repository) → 注册中心(Registry) → 镜像标签(Tag)
仓库:存储特定镜像的所有版本(如 nginx, mysql)
注册中心:存放多个仓库的服务(如 Docker Hub)
标签:镜像的版本标识(如 :latest, :1.0, :alpine)
4.3.3 仓库类型
- 公共仓库
bash
# Docker Hub(官方)
https://hub.docker.com/
# 第三方公共仓库
- Google Container Registry (GCR)
- Amazon ECR Public Gallery
- Azure Container Registry
- GitHub Container Registry (GHCR)
- Quay.io
- 私有仓库
bash
# 自建私有注册中心
docker run -d -p 5000:5000 --name registry registry:2
# 云厂商托管
- AWS ECR(Amazon Elastic Container Registry)
- Google Cloud Container Registry
- Azure Container Registry
- 阿里云容器镜像服务
- 腾讯云容器镜像服务
4.3.4 仓库操作命令
-
基本操作
bash# 搜索镜像 docker search nginx docker search --filter=stars=1000 nginx docker search --filter=is-official=true nginx # 拉取镜像 docker pull nginx:alpine docker pull registry.example.com/myapp:latest # 推送镜像 docker tag myapp:latest registry.example.com/myapp:latest docker push registry.example.com/myapp:latest # 查看镜像标签 curl https://registry.hub.docker.com/v2/repositories/library/nginx/tags/ -
认证管理
bash# 登录仓库 docker login docker login registry.example.com docker login -u username -p password registry.example.com # 查看登录信息 docker info | grep -A 5 "Registry" cat ~/.docker/config.json # 登出 docker logout docker logout registry.example.com
4.3.5 企业级仓库解决方案
-
Nexus Repository Manager
bash# docker-compose.yml for Nexus version: '3.8' services: nexus: image: sonatype/nexus3:latest container_name: nexus restart: unless-stopped ports: - "8081:8081" - "5000:5000" volumes: - ./nexus-data:/nexus-data environment: - INSTALL4J_ADD_VM_PARAMS=-Xms2g -Xmx2g -XX:MaxDirectMemorySize=2g -
Harbor(企业级 Registry)
bash# Harbor 特性 - 基于角色的访问控制 (RBAC) - LDAP/AD 集成 - 镜像漏洞扫描 - 镜像复制 - Webhook 通知 - 图形化管理界面 # 快速部署 curl -s https://raw.githubusercontent.com/goharbor/harbor/master/make/harbor.yml -o harbor.yml ./install.sh