Docker 详解

一、Docker 概述

Docker是一个开源的应用容器引擎,基于Go语言开发,并遵循Apache2.0协议开源。Docker允许开发者将应用以及依赖包打包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux、Windows或Mac机器上,也可以实现虚拟化。容器完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。

二、Docker与虚拟机的区别

Docker与虚拟机是两种不同的虚拟化技术,它们在架构、性能、资源使用和隔离级别等方面有显著区别。

  1. 架构差异

    • 虚拟机(VM):
      • 硬件级虚拟化:每个虚拟机包括完整的操作系统、应用程序以及相关的库和依赖。
      • 隔离级别:每个虚拟机之间以及虚拟机与宿主机之间完全隔离,安全性高。
    • Docker(容器):
      • 操作系统级虚拟化:容器共享宿主机的操作系统内核,但每个容器运行在独立的用户空间中。容器包括应用程序及其依赖,但不需要完整的操作系统。Docker引擎运行在宿主机操作系统上,负责管理容器。
      • 隔离级别:容器之间通过命名空间(Namespace)和控制组(cgroups)进行隔离,但共享内核,因此隔离级别比虚拟机低。
  2. 性能比较

    • 虚拟机(VM):
      • 启动速度较慢(分钟级),因为需要启动整个操作系统。
      • 资源消耗较大,每个虚拟机都需要分配独立的资源(内存、CPU等),并且有额外的操作系统开销。
      • 性能有损失,因为应用程序运行在虚拟硬件上,需要通过Hypervisor层。
    • Docker(容器):
      • 启动速度极快(秒级甚至毫秒级),因为容器直接运行在宿主机内核上,无需启动操作系统。
      • 资源消耗小,多个容器共享宿主机内核,没有额外的操作系统开销。
      • 性能接近原生,因为容器直接运行在宿主机上,没有虚拟硬件层。
  3. 资源使用效率

    • 虚拟机(VM):
      • 每个虚拟机都需要完整的操作系统,因此占用磁盘空间大(通常几GB到几十GB)。
      • 内存占用也大,因为每个虚拟机都要运行操作系统进程。
    • Docker(容器):
      • 容器共享宿主机内核,只需要存储应用程序及其依赖,因此镜像体积小(通常几MB到几百MB)。
      • 内存占用少,因为多个容器可以共享宿主机的操作系统内核。
  4. 隔离性和安全性

    • 虚拟机(VM):
      • 完全隔离,每个虚拟机有独立的操作系统和内核,一个虚拟机的崩溃不会影响其他虚拟机或宿主机。
      • 安全性高,攻击者需要先突破虚拟机,然后再突破Hypervisor才能访问宿主机。
    • Docker(容器):
      • 隔离性相对较弱,虽然容器之间通过命名空间隔离,但共享内核,因此内核漏洞可能影响所有容器。
      • 安全性较低,如果容器内的应用程序获得宿主机内核的访问权限,可能会影响其他容器和宿主机。
  5. 可移植性

    • 虚拟机(VM):
      • 虚拟机镜像通常较大,迁移和分发不如容器方便。
      • 虚拟机可以在不同Hypervisor上运行,但可能需要调整配置。
    • Docker(容器):
      • 容器镜像轻量,易于分发和迁移,适合持续集成和持续部署(CI/CD)。
      • 容器可以在任何安装Docker引擎的宿主机上运行,保证了环境一致性。
  6. 使用场景

    • 虚拟机(VM):
      • 适合运行不同操作系统的应用程序(例如在Linux服务器上运行Windows应用)。
      • 需要完全隔离的环境,如多租户环境、安全要求高的场景。
      • 遗留系统迁移,或者需要模拟完整硬件环境的情况。
    • Docker(容器):
      • 微服务架构,每个服务运行在独立的容器中,便于扩展和管理。
      • DevOps实践,实现快速部署和弹性伸缩。
      • 云原生应用,容器可以轻松在云环境中部署和迁移。

三、Docker 的核心优势

  • 轻量级:共享主机内核,无需完整操作系统
  • 可移植性:一次构建,到处运行
  • 隔离性:进程、网络、文件系统隔离
  • 快速部署:秒级启动和停止
  • 版本控制:支持镜像版本管理
  • 生态丰富:Docker Hub 提供海量镜像

四、Docker核心概念

4.1 镜像(Image)

4.1.1 定义

Docker 镜像是只读的模板,包含了运行应用程序所需的一切:

  • 操作系统(精简版)
  • 运行时环境
  • 应用程序代码
  • 依赖库
  • 配置文件
  • 环境变量

4.1.2 镜像的核心特性

  1. 只读性

    bash 复制代码
    # 镜像是不可变的
    docker pull ubuntu:20.04  # 下载的镜像不能修改
    
    # 基于镜像创建容器时,会添加一个可写层
    +---------------------+
    |     容器可写层       | ← 容器层(可修改)
    +---------------------+
    |     镜像只读层       | ← 镜像层(不可变)
    +---------------------+
  2. 分层存储(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 镜像操作命令

  1. 基本操作

    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
  2. 镜像标签管理

    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
  3. 镜像构建与优化

    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 容器的核心特性

  1. 轻量级

    bash 复制代码
    # 与传统虚拟机对比
    +-----------------------------+
    |    虚拟机:重量级隔离       |
    |  +-----------------------+  |
    |  |      Guest OS         |  |
    |  |  +-----------------+  |  |
    |  |  |     App         |  |  |
    |  |  +-----------------+  |  |
    |  +-----------------------+  |
    +-----------------------------+
    启动时间:分钟级 | 内存:GB级
    
    +-----------------------------+
    |    Docker容器:轻量级隔离    |
    |  +-----------------------+  |
    |  |        App           |  |
    |  +-----------------------+  |
    +-----------------------------+
    启动时间:秒级 | 内存:MB级
  2. 隔离性

    bash 复制代码
    # Linux 内核特性实现隔离
    1. Namespaces:进程、网络、挂载点隔离
    2. Cgroups:CPU、内存、磁盘I/O限制
    3. UnionFS:分层文件系统
    
    # 查看容器命名空间
    ls -la /proc/<container-pid>/ns/

4.2.3 容器的生命周期

  1. 生命周期状态

    bash 复制代码
    创建(Created) → 运行(Running) → 暂停(Paused)
            ↓              ↓            ↓
            → 停止(Stopped) → 删除(Deleted)
  2. 状态转换命令

    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 容器操作命令

  1. 基础操作

    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行
  2. 容器控制

    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
  3. 资源监控

    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 容器运行参数详解

  1. 基础运行选项

    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                     # 镜像
  2. 端口映射

    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
  3. 环境变量

    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
  4. 资源限制

    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
  5. 重启策略

    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 仓库类型

  1. 公共仓库
bash 复制代码
# Docker Hub(官方)
https://hub.docker.com/

# 第三方公共仓库
- Google Container Registry (GCR)
- Amazon ECR Public Gallery
- Azure Container Registry
- GitHub Container Registry (GHCR)
- Quay.io
  1. 私有仓库
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 仓库操作命令

  1. 基本操作

    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/
  2. 认证管理

    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 企业级仓库解决方案

  1. 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
  2. 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
相关推荐
Bruce_Liuxiaowei2 小时前
Windows系统中msg命令的完整使用方法及相关示例
运维·网络·windows·网络安全
先生沉默先2 小时前
Docker+Nginx+Node.js 全栈容器化部署
nginx·docker·node.js
qq_5470261792 小时前
Dockerfile 详解
docker
专家大圣3 小时前
摆脱局域网!Logseq 搭配cpolar公网访问让笔记管理更自由
linux·网络·docker·内网穿透·cpolar
小黑要上天3 小时前
8-docker run --rm选项说明
运维·docker·容器
Evan芙3 小时前
Nginx安全相关的参数总结
运维·nginx·安全
气π3 小时前
【流程】——若依项目前后端打包发布到服务器
运维·服务器·oracle
代码游侠3 小时前
复习——Linux 系统编程
linux·运维·c语言·学习·算法
共绩算力3 小时前
给 TRAE SOLO 一台服务器,它能干什么?
运维·服务器