从零理解容器化:Docker 核心原理与 Kubernetes 初探

从零理解容器化:Docker 核心原理与 Kubernetes 初探

系统梳理 Docker 的诞生背景、基本概念、常用命令与 Dockerfile 实践,并初步了解 Kubernetes 的设计哲学,帮助 Java 开发者快速建立容器化思维体系。


1 为什么需要 Docker?

Docker 出现之前的困境

在 Docker 出现之前,软件的开发、交付与部署面临着一个长久以来没有彻底解决的问题:「在我的机器上明明是好的!」

软件运行依赖于操作系统、JDK 版本、环境变量、配置文件等一系列条件。开发者在本地搭建好环境、跑通测试,但一旦交付给运维或者部署到生产服务器,往往因为环境不一致导致各种莫名其妙的故障。

  • 软件交付方式繁琐:需要附带厚重的部署文档,逐步指导运维重建环境
  • 部署过程耗时:在新机器上安装依赖、配置参数,动辄耗费数小时
  • 不同应用之间的依赖冲突难以隔离

Docker 带来了什么?

能力 说明
环境一致性 保证开发、测试、交付、部署全链路的运行环境完全一致,彻底消灭「环境差异」导致的 Bug
资源隔离 每个容器拥有独立的网络、文件系统和进程空间,互不干扰,安全可靠
用完即弃 快速启动临时环境用于测试或 CI/CD,使用完毕直接销毁,零污染
秒级弹性扩容 相比虚拟机分钟级启动,容器可以在秒级内完成超大规模部署与扩缩容

2 Docker 核心概念:镜像与容器

镜像(Image)

镜像是一个预定义好的模板文件,Docker 引擎可以按照这个模板启动无数个一模一样、互不干扰的容器。

类比: 镜像就像蛋糕的模具,容器就是用这个模具做出来的蛋糕。同一个模具可以做出无数个一样的蛋糕,每个蛋糕相互独立,你吃了这个不影响另一个。

镜像在结构上是分层的(Layered) ,这是为了最大化复用------多个镜像可以共享相同的底层,节省存储空间与下载时间。

容器(Container)

容器是镜像运行后的实例,本质上是一台「虚拟的计算机」,拥有独立的:

  • 网络:独立的 IP 地址与端口空间
  • 文件系统:与宿主机完全隔离
  • 进程:容器内的进程对外不可见

⚠️ 注意: 容器默认与宿主机不发生任何交互,这意味着容器内的数据是没有持久化的 !容器一旦被删除,其内部数据随之消失。如果需要持久化数据,必须通过 -v 参数挂载宿主机目录。


3 Docker 常用命令详解

拉取与查看镜像

bash 复制代码
# 拉取指定版本的镜像
docker pull mysql:5.7.28

# 查看本地已有的所有镜像
docker images

# 删除指定镜像
docker rmi <镜像ID或镜像名>

镜像名称由三部分组成:

markdown 复制代码
registry.cn-beijing.aliyuncs.com/dr1/   hcsp   :0.0.16
|____________镜像仓库地址_____________|  |镜像名|  |Tag|

启动容器

ini 复制代码
# 交互式启动(前台运行,Ctrl-C 退出)
docker run -it <镜像名> <命令>

# 后台 daemon 模式运行
docker run -d <镜像名>

# 完整示例:启动一个 MySQL 容器
docker run -d \
  --name mysql-dev \
  --restart=always \
  -p 3306:3306 \
  -v /data/mysql:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  mysql:5.7.28

docker run 的常用参数说明:

参数 说明
--name <名字> 为容器指定一个可读的名称,便于后续引用
--restart=always 容器异常退出时自动重启,适用于生产服务
-v <本地路径>:<容器路径> 挂载宿主机目录到容器,实现数据持久化
-p <本地端口>:<容器端口> 端口映射,将容器内端口暴露给宿主机
-e NAME=VALUE 设置环境变量,如 MySQL 密码、Redis 配置等
-d 以 daemon 后台模式运行,不占用当前终端

容器生命周期管理

命令 说明
docker ps 查看正在运行的容器;加 -a 查看所有容器(含已停止)
docker start / stop 启动 / 停止一个容器,类比为「开关机」操作
docker rm 删除一个容器,类比「把电脑丢掉」,数据随之丢失
docker exec 进入运行中的容器执行命令,类比 SSH 登录
docker logs 查看容器输出;加 -f 参数可实时跟踪日志
docker inspect 查看容器的详细状态(网络、挂载点、环境变量等)
bash 复制代码
# 进入容器内部(调试必备)
docker exec -it <容器ID> bash

# 实时跟踪容器日志
docker logs -f <容器ID>

💡 调试必备: docker exec -it <容器ID> bash 是排查容器内部问题的核心手段,配合 docker logs -f <容器ID> 实时查看日志,几乎可以定位 90% 的容器运行问题。


4 Dockerfile 与镜像构建

手动拉取现成镜像固然方便,但更多时候我们需要将自己的应用打包成镜像。这就需要编写 Dockerfile------一个描述「如何构建镜像」的配置文件。

一个典型的 Java 应用 Dockerfile

bash 复制代码
# 指定基础镜像(分层结构的起点)
FROM eclipse-temurin:17-jre-alpine

# 设置工作目录
WORKDIR /app

# 将编译好的 jar 包复制进镜像
COPY target/myapp.jar app.jar

# 声明容器对外暴露的端口
EXPOSE 8080

# 容器启动时执行的命令
ENTRYPOINT ["java", "-jar", "app.jar"]

编写好 Dockerfile 后,在同目录执行构建命令:

bash 复制代码
# 构建镜像,. 代表使用当前目录的 Dockerfile
docker build -t myapp:1.0.0 .

构建完成后,每个镜像会生成一个唯一的 ID,也可以通过 -t 参数为其指定一个更易读的 tag 名称。


5 镜像仓库与 Tag 管理

类似于 Maven 的 Nexus 私服,Docker 也有自己的镜像仓库体系。Tag 操作决定了镜像的归属与存储位置。

bash 复制代码
# 为镜像打 Tag,指向私有仓库
docker tag myapp:1.0.0 registry.cn-beijing.aliyuncs.com/myorg/myapp:1.0.0

# 推送到远程仓库
docker push registry.cn-beijing.aliyuncs.com/myorg/myapp:1.0.0

# 从私有仓库拉取
docker pull registry.cn-beijing.aliyuncs.com/myorg/myapp:1.0.0

生产环境中,通常会搭建私有镜像仓库,通过以下 Docker 启动参数配置:

  • --registry-mirror:配置镜像加速源(如阿里云加速器),解决拉取 Docker Hub 镜像慢的问题
  • --insecure-registry:允许使用 HTTP 协议连接私有仓库(非 HTTPS),适用于内网环境

6 Kubernetes 概念简介

有了 Docker,我们可以在单台机器上轻松管理容器。但当服务规模扩展到数十台、数百台机器时,如何统一调度和管理这些容器?这正是 Kubernetes(K8s) 解决的问题。

宠物与家畜:理解运维哲学的转变

类比 特点
传统服务器 养宠物 每台服务器都有名字、独特的配置,出了问题要仔细修复,不能轻易替换,珍贵而脆弱
Docker 容器 变成家畜 容器是标准化、可替换的。一个挂了,直接启动一个新的,完全一样,无需留恋
Kubernetes 牧场主 K8s 是自动化牧场:自动决定把容器跑在哪台机器上,自动扩缩容,自动故障恢复

这个比喻深刻揭示了云原生时代运维思维的转变:我们不再关心某一台具体的服务器,而是声明「我需要 10 个 MySQL 实例」,由 K8s 自动完成调度、部署与运维。

学习路径建议

Docker 基础 → Dockerfile 实践 → 镜像仓库管理 → Kubernetes 核心概念(Pod / Service / Deployment)→ K8s 实战部署

Docker 是 K8s 的基石,打好 Docker 基础后,K8s 的很多设计会豁然开朗。

相关推荐
也许明天y2 小时前
Spring AI 核心原理解析:基于 1.1.4 版本拆解底层架构
java·后端·spring
舒一笑2 小时前
一文讲透 Temporal:为什么大厂都在用它做 AI 与分布式系统的“流程大脑”?
后端·程序员·llm
希望永不加班2 小时前
SpringBoot 自定义 Starter:从零开发一个私有 Starter
java·spring boot·后端·spring·mybatis
悟空码字3 小时前
别再System.out了!这份SpringBoot日志优雅指南,让你告别日志混乱
java·spring boot·后端
程序员张33 小时前
自定义跨字段校验必填注解
java·后端
那个失眠的夜3 小时前
Spring 的纯注解配置
xml·java·数据库·后端·spring·junit
Rust研习社3 小时前
Rust 堆内存指针 Box 详解
开发语言·后端·rust
ffqws_3 小时前
Spring Boot:用JWT令牌和拦截器实现登录认证(含测试过程和关键注解讲解)
java·spring boot·后端
Java水解4 小时前
Go语言中的Pool:对象复用的艺术
后端·go