第二部分:Docker 基础篇(构建你的第一个容器)

📝 前言

回顾下,在上一部分我们介绍了云原生的基础概念和演进过程

其中容器技术已成为现代软件开发的基础设施,而 Docker 作为其中最流行的实现,承担了非常重要的角色,为开发者和运维提供了极大的便利。

无论你是刚刚接触后端开发、系统部署,还是开始探索 DevOps 或云原生体系,Docker 都是你无法绕开的技能。

🧭 背景

2015年,当我还在从事 Android 系统级应用开发时,第一次接触到了 Docker 容器技术。

当时我负责开发手机桌面(Launcher)和应用商店这两个系统级应用,这些应用与普通应用不同,需要频繁进行系统编译。

你可能想象不到,当时的系统编译环境搭建有多麻烦:需要安装大量依赖包,稍有不慎就会导致服务器崩溃。每次准备干净的编译环境都要耗费大量时间,这让我非常困扰。

直到有一天,我发现了 Docker 这个解决方案。

它通过将应用和运行环境打包成统一镜像,完美解决了环境一致性和快速部署的问题。相比传统虚拟机,Docker 更加轻量便捷,很快就帮我摆脱了环境配置的噩梦。

正是这次经历让我对 Docker 产生了浓厚兴趣。

后来转型做 Web 开发后,我发现 Docker 的应用场景更加广泛,这也让我在技术道路上走得更远。

本章作为 Docker 的基础篇,主要介绍 Docker 的一些基础概念、常用命令以及如何快速入门。

🧠 本章知识卡片

后续每章节尽量同时带上知识卡片,以帮助读者快速了解本章的核心知识内容。

❓Docker 是什么

以下摘自 Docker 官方文档说明

Docker 是一个开源平台,用于开发、打包和运行应用程序。

Docker 可以让你将应用程序与基础设施分离,从而快速交付软件。

使用 Docker,你可以像管理应用程序一样管理基础设施。

通过利用 Docker 的打包、测试和部署代码的方法论,你可以显著减少从编写代码到在生产环境中运行代码之间的延迟。

🆚 Docker 与传统虚拟机的区别

虽然 Docker 和传统虚拟机(简称 VM)都可以提供隔离的运行环境,但它们的架构和运行方式有本质区别,以下为两者的对比:

架构对比

PS:本图为原创设计

核心参数对比

总的来说 Docker 更轻、更快、更适合微服务和持续集成,而传统虚拟机则更重、更稳、更适合强隔离和完整操作系统模拟的场景。

各自都有优缺点,也没必要一味的全部都只上 Docker,可根据实际业务需要进行选择。

🧩 使用场景

Docker 主要在以下场景中使用的较多:

  • 开发人员希望快速构建和部署测试环境
  • 运维人员进行轻量级应用封装与交付
  • DevOps 自动化流程中的 CI/CD 环节
  • 构建多平台一致的运行环境(Mac、Windows、Linux)

当然现在实际远不止这些了,Docker 也已拓展到了 AI 领域。

🖼️ 组成架构

以下摘自 Docker 官方文档说明

Docker 使用客户端-服务器架构。

Docker 客户端与 Docker 服务器端通信,后者负责构建、运行和分发 Docker 容器。

Docker 客户端和服务器端可以运行在同一系统上,或者您可以将 Docker 客户端连接到远程的 Docker 服务器端。

Docker 客户端和服务器端通过 REST API 进行通信,基于 UNIX 套接字或网络接口。

PS:本图为原创设计

通过以上的这张图我们可以发现,Docker 核心组成部分包括:客户端(Client)、服务器端(Daemon)、镜像(Images)、容器(Containers)和仓库(Registry)。

各组成大概说明:

  • 客户端:这就是我们最常使用的 Docker 命令,在下面会介绍到有哪些常用命令。
  • 服务器端:用于接收客户端命令传递的请求,进行实际的业务运行,如启动容器、上传镜像等。
  • 镜像:一个只读的模板,用于创建 Docker 容器,需要注意的是一旦镜像构建完成即不可修改。
  • 容器:镜像的运行时实例,是一个轻量级、可移植、隔离的进程环境。
  • 仓库:用于存储和分发 Docker 镜像的中央服务,企业或个人也可以部署私有的 Registry(如 Harbor)。

这里就不详细展开了,不然每个部分都可以单开一章:(

🚀 文章小节

1️⃣ 快速安装 Docker

安装比较简单,可参考之前写的一篇文章:《Docker 与 Docker Compose 安装部署》

2️⃣ Docker 常用命令

容器管理相关命令 作用
docker run -it 镜像名 运行容器并进入交互模式
docker run -d 镜像名 后台运行容器
docker ps 查看正在运行的容器
docker ps -a 查看所有容器(包括已停止)
docker start 容器ID 启动已停止的容器
docker stop 容器ID 停止正在运行的容器
docker restart 容器ID 重启容器
docker rm 容器ID 删除容器
docker logs 容器ID 查看容器日志
docker exec -it 容器ID /bin/bash 进入容器的终端交互环境
镜像管理命令 作用
docker images 查看本地镜像
docker pull 镜像名 从远程仓库拉取镜像
docker rmi 镜像名 删除本地镜像
docker build -t 镜像名 . 使用当前目录下的 Dockerfile 构建镜像
docker tag 源镜像 新镜像名 给镜像打标签
docker save -o xxx.tar 镜像名 导出镜像为文件
docker load -i xxx.tar 从文件导入镜像
仓库相关命令 作用
docker login 登录 Docker 仓库,默认是登录官方仓库,可添加私有仓库地址,则登录私有仓库
docker logout 退出登录,默认是退出官方仓库,可添加私有仓库地址,则退出私有仓库
docker push 镜像名 推送镜像到远程仓库
docker pull 镜像名 从仓库拉取镜像

3️⃣ 运行第一个容器

使用以下命令快速运行第一个容器:

1
2
3
4
5
6
7
8
9
10
11
# 由于网络原因,官方镜像地址可能无法运行
# docker run hello-world:latest

# 阿里云公开仓库地址
docker run registry.cn-hangzhou.aliyuncs.com/lusyoe/hello-world:latest

# 打印如下内容则表示运行成功
Hello from Docker!
This message shows that your installation appears to be working correctly.

...省略部分...

参数说明:

  • docker run:运行容器的命令
  • registry.cn-hangzhou.aliyuncs.com:私有(非官方)镜像仓库地址,默认不填则为官方地址:hub.docker.com
  • lusyoe:命名空间
  • hello-world:镜像名称
  • latest:镜像tag,又被称为镜像版本。

4️⃣ Dockerfile 基础

当我们需要自定义容器镜像时,就可以通过 Dockerfile 编写镜像构建规则。

创建一个简单的 Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用官方镜像作为基础镜像
# FROM python:3.11-slim
FROM registry.cn-hangzhou.aliyuncs.com/lusyoe/python:3.11-slim

# 设置工作目录
WORKDIR /app

# 拷贝当前目录内容到容器中
COPY . .

# 暴露端口
EXPOSE 8000

# 设置容器启动命令
CMD ["python", "main.py"]

完整项目代码: https://github.com/lusyoe/python-docker-demo

基于 Dockerfile 构建镜像:

1
docker build . -t registry.cn-hangzhou.aliyuncs.com/lusyoe/python-demo:latest

参数说明:

  • docker build:构建镜像命令
  • . :当前上下文目录

运行自定义镜像容器:

1
2
docker run -dp 8000:8000 \
registry.cn-hangzhou.aliyuncs.com/lusyoe/python-demo:latest

参数说明:

  • docker run:启动容器
  • -dp:d参数表示容器在后台启动,p参数表示指定映射本地端口到容器内的端口

访问容器服务:

1
2
3
4
curl http://localhost:8000

# 打印如下内容表示容器启动成功
Hello, World

5️⃣ Docker 镜像仓库

在上一步我们已经构建出了自己的镜像,那么如何将该镜像部署到服务器上呢。

这里就需要用到镜像仓库进行分发,我们可以使用阿里云的免费个人版镜像仓库,也可以自己搭建Harbor 私有仓库。

使用以下命令上传镜像并在服务器运行容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 登录镜像仓库
docker login <镜像仓库地址>
# 例如:
# docker login registry.cn-hangzhou.aliyuncs.com

# 上传镜像
docker push <镜像仓库地址>/<命名空间>/<镜像名称>:<镜像版本>
# 例如:
# docker push registry.cn-hangzhou.aliyuncs.com/lusyoe/python-demo:latest

# 在服务器运行容器,若服务器不存在该镜像会自动进行下载
docker run -dp 8000:8000 \
registry.cn-hangzhou.aliyuncs.com/lusyoe/python-demo:latest

✅ 总结

最后总结一下,本文首先介绍了 Docker 的基础概念,然后带领大家从 0 开始构建第一个 Docker 容器,涵盖安装、运行、构建、上传等关键步骤。

通过理解镜像与容器的关系,你应该可以在任何平台上快速复用环境、部署应用,提升开发效率与可维护性。

Docker 是走向现代 DevOps 与云原生架构的第一步,后续还有多篇关于 Docker 的实战介绍,感兴趣的同学可以持续关注~