所有托管服务节省 15%

测试技能,享折扣

使用代码: Skills 开始使用
China
Linux 虚拟服务器

Docker 是什么以及它如何工作?开发人员和系统管理员完整指南

Docker 从根本上改变了现代应用程序的构建、交付和部署方式。无论您是厌倦了环境不一致的开发人员,还是在多个服务器上管理数十个服务的系统管理员,Docker 都提供了一个清洁、高效和便携的解决方案。在这份综合指南中,我们将详细分解 Docker 是什么、它如何在幕后工作,以及为什么它已成为当今 DevOps 领域中不可或缺的工具。

什么是 Docker?

Docker 是一个开源平台,使用容器化技术自动化应用程序的部署、扩展和管理。Docker 的核心是将应用程序与其所有依赖项——库、配置文件、运行时环境和环境变量——打包到一个称为容器的单一、自包含的单元中。

这里的关键优势是一致性。无论 Docker 容器在开发人员的笔记本电脑、暂存服务器还是云中的生产环境上运行,其行为都完全相同。这消除了困扰软件团队数十年的臭名昭著的”在我的机器上可以工作”问题。

Docker 与传统虚拟机的比较

要真正理解 Docker,了解它与传统虚拟机 (VM) 的区别会很有帮助:

功能Docker 容器虚拟机
OS 开销共享主机 OS 内核需要完整的客户 OS
启动时间分钟
资源使用轻量级重量级
可移植性高度可移植可移植性有限
隔离进程级隔离完整的硬件级隔离

传统 VM 虚拟化整个硬件堆栈,每个实例都需要一个完整的操作系统。相比之下,Docker 容器共享主机操作系统的内核,同时保持严格的进程隔离。结果是启动时间大幅加快、内存消耗降低,以及服务器资源的使用效率大幅提高。

如果您在 VPS 托管计划上运行容器化工作负载,这种效率会直接转化为成本节省和更好的性能投资回报率。

Docker 的关键组件

理解 Docker 需要熟悉其核心构建块。每个组件在容器生命周期中都发挥特定的作用。

1. Docker Engine

Docker Engine 是整个平台的核心。它是一个客户端-服务器应用程序,负责构建、运行和管理容器。Engine 包括两个主要部分:

  • Docker Daemon (dockerd): 一个持久的后台服务,监听 Docker API 请求并管理 Docker 对象,如镜像、容器、网络和卷。守护进程承担繁重的工作——它构建镜像、启动容器并处理所有编排任务。
  • Docker CLI (命令行界面): 开发人员和管理员用来与 Docker Daemon 交互的命令行工具。docker builddocker rundocker ps 等命令都通过 CLI 执行,CLI 通过 REST API 与守护进程通信。

2. Docker 镜像

Docker 镜像是一个只读的、不可变的模板,用于创建容器。可以将其视为应用程序在特定时间点的快照或蓝图。镜像包含:

  • 应用程序源代码或编译的二进制文件
  • 所有必需的运行时库和依赖项
  • 环境变量和配置设置
  • 文件系统结构和元数据

镜像以的形式构建。Dockerfile 中的每条指令都在前一层的基础上添加新层。这种分层架构使 Docker 能够缓存中间构建步骤,使后续构建速度显著加快。当你仅更新应用程序代码时,Docker 会重用所有缓存的依赖项层,仅重新构建已更改的部分。

3. Dockerfile

Dockerfile 是一个纯文本脚本,包含 Docker 遵循的一系列指令来组装镜像。它定义了基础镜像、工作目录、要复制的文件、要运行的命令以及要公开的端口。Dockerfile 是如何构造应用程序镜像的唯一真实来源,使构建完全可重现且可版本控制。

4. Docker Hub 和容器注册表

Docker Hub 是 Docker 镜像的默认公共云注册表。它充当中央存储库,开发人员可以在其中发布、共享和拉取镜像。Docker Hub 托管数千个流行软件堆栈的官方镜像——包括 Node.js、Python、Nginx、MySQL、Redis 等——你可以将其用作自己应用程序的基础镜像。

除了 Docker Hub,组织通常运行私有注册表来安全地存储专有镜像。这在生产环境中尤其重要,因为你不想暴露内部应用程序逻辑。

5. Docker 容器

容器是 Docker 镜像的运行实例。虽然镜像是静态的和只读的,但容器是一个活的、可执行的环境。你可以同时从同一镜像运行多个容器,每个容器都在完全隔离的环境中运行,拥有自己的文件系统、网络接口和进程空间。

容器在设计上是临时的——它们可以启动、停止、移动和删除,而不会影响底层镜像或其他容器。这使它们非常适合微服务架构和水平扩展。

Docker 如何工作:分步演练

让我们从编写第一个 Dockerfile 到运行实时容器,完整地走过 Docker 工作流程。

第 1 步:编写 Dockerfile

该过程从在项目的根目录中创建 Dockerfile 开始。以下是 Node.js Web 应用程序的实际示例:

# Use the official Node.js 18 LTS image as the base
FROM node:18-alpine

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy dependency manifests first (leverages layer caching)
COPY package*.json ./

# Install production dependencies
RUN npm install --only=production

# Copy the rest of the application source code
COPY . .

# Expose the port the application listens on
EXPOSE 8080

# Define the default command to start the application
CMD ["node", "app.js"]

为什么在复制其余代码之前复制 package.json这是一个最佳实践,利用了 Docker 的层缓存。由于 npm install 耗时,将其放在复制应用程序代码之前意味着 Docker 仅在依赖项实际更改时才重新运行安装步骤 — 而不是每次修改源文件时都运行。

第 2 步:构建 Docker 镜像

准备好 Dockerfile 后,使用 docker build 命令构建镜像:

docker build -t my-node-app:1.0 .

分解此命令:

  • docker build — 指示 Docker Engine 构建新镜像
  • -t my-node-app:1.0 — 使用名称 my-node-app 和版本 1.0 标记镜像
  • . — 指定构建上下文(当前目录),Docker 将其发送到守护程序

Docker 逐行读取 Dockerfile,执行每条指令并将结果作为新的镜像层提交。在后续构建中,未更改的层从缓存中提取,使过程快得多。

第 3 步:运行 Docker 容器

构建镜像后,从中启动一个容器:

docker run -d -p 8080:8080 --name my-running-app my-node-app:1.0

标志分解:

  • -d — 在分离模式(后台)运行容器
  • -p 8080:8080 — 将主机机器上的端口 8080 映射到容器内的端口 8080
  • --name my-running-app — 为容器分配易读的名称
  • my-node-app:1.0 — 指定要使用的镜像

您的应用程序现在可在 http://localhost:8080 访问。

第 4 步:管理运行中的容器

Docker 提供了一套丰富的命令来管理容器生命周期:

# List all running containers
docker ps

# View logs from a container
docker logs my-running-app

# Stop a running container
docker stop my-running-app

# Remove a stopped container
docker rm my-running-app

# List all locally available images
docker images

第 5 步:将镜像推送到注册表

要共享镜像或将其部署到远程服务器,请将其推送到 Docker Hub 或私有注册表:

# Log in to Docker Hub
docker login

# Tag the image with your Docker Hub username
docker tag my-node-app:1.0 yourusername/my-node-app:1.0

# Push the image to the registry
docker push yourusername/my-node-app:1.0

从任何安装了 Docker 的服务器 — 包括专用服务器 — 您可以使用单个命令拉取并运行镜像。

Docker Compose:管理多容器应用程序

现实世界的应用程序很少由单个服务组成。典型的Web应用程序可能包括Node.js API服务器、PostgreSQL数据库、Redis缓存和Nginx反向代理。单独管理所有这些容器会很繁琐且容易出错。

Docker Compose通过允许您使用单个docker-compose.yml文件定义和运行多容器应用程序来解决此问题:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8080:8080"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:password@db:5432/mydb
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb

  redis:
    image: redis:7-alpine

volumes:
  postgres_data:

有了这个文件,您可以使用一个命令启动整个应用程序堆栈:

docker-compose up -d

Docker Compose自动处理容器之间的网络连接——每个服务都可以通过其服务名称到达其他服务(例如,Web服务通过主机名db连接到数据库)。

使用 Docker 的主要优势

✅ 跨环境可移植性

Docker 容器封装了应用程序运行所需的一切。这意味着在开发人员的 macOS 工作站上构建的容器将在 Linux 生产服务器或 Windows CI/CD 管道上完全相同地运行。不再有依赖项冲突或特定于环境的错误。

✅ 一致且可重现的构建

由于整个环境都在代码中定义(Dockerfile),构建是完全可重现的。任何团队成员都可以检出存储库并从头开始构建相同的环境。这对于新开发人员的入职和在受监管行业中维护审计跟踪非常宝贵。

✅ 进程隔离和安全性

每个容器都在自己的隔离命名空间中运行,具有自己的文件系统、网络堆栈和进程树。这种隔离意味着一个容器中的崩溃或安全漏洞不会自动影响在同一主机上运行的其他容器。结合适当的网络策略和只读文件系统,Docker 显著降低了应用程序的攻击面。

✅ 卓越的资源效率

与传统虚拟机相比,Docker 容器非常轻量级。它们在几秒钟内启动,而不是几分钟,并且消耗的内存和 CPU 开销只是虚拟机的一小部分。在单个 VPS 托管实例上,您可以轻松运行数十个容器化微服务,而这在过去需要多个虚拟机。

✅ 简化的依赖项管理

Docker 消除了应用程序之间的依赖项冲突。两个需要不同版本 Python、Node.js 或任何其他运行时的服务可以在同一主机上和平共存,因为每个容器都携带自己的隔离依赖项堆栈。

✅ 加速的 CI/CD 管道

Docker 与现代 CI/CD 工具(如 GitHub Actions、GitLab CI、Jenkins 和 CircleCI)无缝集成。容器提供干净、隔离的构建环境,确保您的测试针对与生产部署完全相同的堆栈运行,大大降低了与环境相关的发布失败风险。

✅ 轻松的水平扩展

由于容器在设计上是无状态和可一次性使用的,水平扩展应用程序就像在负载均衡器后面启动额外的容器实例一样简单。Kubernetes 和 Docker Swarm 等编排平台完全自动化了这个过程。

Docker 安全最佳实践

在生产环境中运行容器需要关注安全性。以下是每个系统管理员应该遵循的最重要的实践:

  1. 使用最小化基础镜像: 基于 Alpine 的镜像(node:18-alpinepython:3.11-alpine)的攻击面比完整操作系统镜像小得多。
  2. 以非 root 用户身份运行容器: 在 Dockerfile 中添加 USER 指令,以避免在容器内以 root 身份运行进程。
  3. 扫描镜像中的漏洞: 使用 docker scout、Trivy 或 Snyk 等工具定期扫描镜像中的已知 CVE。
  4. 保持镜像更新: 定期重建镜像以整合来自基础镜像更新的安全补丁。
  5. 使用只读文件系统: 在可能的情况下,将容器文件系统挂载为只读,以防止篡改。
  6. 限制资源消耗: 使用 --memory--cpus 标志来防止单个容器垄断主机资源。
  7. 保护您的注册表: 将敏感镜像存储在具有访问控制的私有注册表中,而不是公共 Docker Hub 上。

对于生产部署,将 Docker 与正确配置的服务器配对至关重要。AlexHost 的 专用服务器 提供运行大规模容器化工作负载所需的原始性能和完全 root 访问权限,而 VPS 托管 计划为较小的部署提供了经济高效的入门选择。

Docker 在您的托管基础设施中的应用

理解 Docker 只是解决方案的一部分。要有效部署容器化应用程序,您需要可靠的底层基础设施。

  • 对于小型项目和暂存环境:共享网络托管非常适合静态网站和简单的 PHP 应用程序,尽管 Docker 通常在 VPS 或专用环境中使用。
  • 对于容器化网络应用程序:VPS 托管计划为您提供完整的 root 访问权限、专用资源以及安装 Docker 和任何所需编排工具的自由。
  • 对于大规模微服务:专用服务器提供最高性能,消除了共享环境中常见的”嘈杂邻居”问题。
  • 对于容器中的机器学习和 AI 工作负载:GPU 托管支持 GPU 加速的 Docker 容器,用于深度学习、模型训练和推理工作负载。
  • 对于保护容器化网络服务:将您的部署与 SSL 证书配对,以加密用户与 Docker 化应用程序之间的流量。

关于 Docker 的常见问题

Q: Docker 免费使用吗?

Docker Engine 是开源的,个人和小型企业可以免费使用。Docker Desktop 对于较大的组织需要付费订阅。Docker Hub 提供免费的公共存储库,但拉取次数有限制。

Q: Docker 和 Kubernetes 有什么区别?

Docker 是一个容器运行时 — 它构建和运行单个容器。Kubernetes 是一个容器编排平台,可自动化在机器集群中部署、扩展和管理大量容器。它们是互补的技术;Kubernetes 通常在底层使用 Docker(或另一个容器运行时)。

Q: Docker 可以在 Windows 上运行吗?

可以。Docker Desktop for Windows 使用 WSL 2(Windows Subsystem for Linux)或 Hyper-V 在 Windows 上运行 Linux 容器。也支持原生 Windows 容器。

Q: Docker 与虚拟机有什么不同?

如前所述,虚拟机虚拟化硬件并需要完整的客户操作系统,使其更重且启动速度更慢。Docker 容器共享主机 OS 内核,轻量级得多,尽管隔离性略低于完整虚拟机。

Q: 单容器应用程序需要 Docker Compose 吗?

不需要。Docker Compose 对多容器应用程序最有价值。对于单个容器,标准 docker run 命令就足够了。

结论

Docker已成为现代软件开发和系统管理中的基础技术。通过将应用程序及其依赖项打包到便携式、隔离的容器中,Docker消除了环境不一致性,加快了部署管道,与传统虚拟化相比大幅提高了资源利用率。

无论您是部署简单的Web应用程序还是构建复杂的微服务平台,掌握Docker都将从根本上改进您构建和运营软件的方式。本指南涵盖的概念——Dockerfiles、镜像、容器、Docker Compose和安全最佳实践——构成了您自信入门所需的基础。

准备好将Docker付诸实践了吗?AlexHost的VPS Hosting计划提供完整的root访问权限和开箱即用的Docker支持,为您提供可靠的高性能环境来部署您的容器化应用程序。