ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Docker、Docker Compose 与 Kubernetes:分别解决什么问题?

2026/8/29 20:54:41 拓冰建站 浏览量
Docker、Docker Compose 与 Kubernetes:分别解决什么问题? 刚接触容器技术时Docker、Docker Compose 和 Kubernetes 经常一起出现很容易让人误以为它们是三种差不多的工具。其实它们解决的问题处在不同层次Docker 负责把一个应用装进容器并运行起来。Docker Compose 负责在一台机器上组织多个容器。Kubernetes 负责在多台机器上管理大量容器并让系统持续稳定运行。可以先记住一句简单的话Docker 管一个容器Docker Compose 管一组容器Kubernetes 管一个容器集群。一、为什么需要 Docker假设你开发了一个 Java 网站在自己的电脑上运行正常。交给同事或部署到服务器后却出现了各种问题服务器没有安装 Java。Java 版本不一致。缺少某些系统依赖。配置文件路径不同。同事不知道该执行哪些启动命令。这就是开发中常见的“在我电脑上明明能运行”。Docker 的做法是把应用程序、运行环境、依赖和启动命令一起打包成镜像。Docker 官方将镜像描述为运行容器所需文件、程序库和配置的标准化软件包。拿日常外卖举个例子应用代码是食物。Java、Node.js 等运行环境是餐具。配置和依赖是调料。Docker 镜像是封装好的外卖套餐。容器是这份套餐真正被打开并使用的状态。同一个镜像可以启动多个容器就像同一份套餐模板可以制作出很多份外卖。1、镜像和容器有什么区别镜像是一份只读模板容器是镜像运行后的实例。可以把它们理解为镜像 程序安装包容器 已经启动的程序例如通过下面的命令启动一个 Nginx 容器docker run -d -p 8080:80 --name my-nginx nginx这条命令做了几件事获取nginx镜像。根据镜像创建一个名为my-nginx的容器。在后台运行容器。把本机的 8080 端口映射到容器的 80 端口。访问http://localhost:8080就能看到 Nginx 页面。2、Dockerfile 是什么如果要把自己的应用制作成镜像通常需要编写 Dockerfile。下面是一个简单的 Java 应用示例FROM eclipse-temurin:17-jreWORKDIR /appCOPY target/demo.jar app.jarEXPOSE 8080CMD [java, -jar, app.jar]它表达的意思很直接使用带有 Java 17 的基础镜像。把工作目录设为/app。将项目生成的 JAR 文件复制进去。声明应用使用 8080 端口。容器启动时执行java -jar app.jar。然后构建并运行docker build -t demo-app:1.0 . docker run -d -p 8080:8080 demo-app:1.0这样其他人不需要手动安装 Java也不必研究项目的启动方式。只要能运行容器就能按照同样的方式启动这个应用。二、为什么还需要 Docker Compose只有一个容器时使用docker run并不麻烦。实际项目通常不止一个服务。例如一个普通网站可能包含前端 Nginx↓Java 后端↓MySQL 数据库↓Redis 缓存如果全部使用docker run需要分别配置端口、网络、环境变量和数据卷。启动命令会越来越长而且很容易漏掉参数。Docker Compose 就是用来处理这种情况的。它允许我们在一个 YAML 文件中定义多个服务、网络和数据卷再通过一条命令统一启动。Docker 官方把 Compose 定义为“用于定义和运行多容器应用的工具”。举一个简单示例下面的compose.yaml定义了一个 Java 应用和一个 MySQL 数据库services: app: build: . ports: - 8080:8080 environment: DB_HOST: mysql DB_PORT: 3306 DB_NAME: demo DB_USER: root DB_PASSWORD: 123456 depends_on: - mysql mysql: image: mysql:8.4 environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: demo volumes: - mysql-data:/var/lib/mysql volumes: mysql-data:在这个文件所在目录执行docker compose up -dCompose 会完成这些工作构建并启动 Java 应用。下载并启动 MySQL 镜像。建立容器之间的网络。创建数据库存储卷。把后端服务的 8080 端口暴露给本机。查看日志可以执行docker compose logs -f停止并删除这些容器docker compose down docker compose down -v //-v 会删除数据库使用的数据卷已有数据可能随之消失。注早期版本使用带连字符的独立命令docker-compose up -d现在主流版本已经把 Compose 集成进 Docker CLI通常使用docker compose up -d两者只是写法不同罢了。三、为什么又出现了 KubernetesDocker Compose 很适合开发、测试和单机部署。不过当系统运行在多台服务器上时事情会迅速变复杂。假设一个电商网站原来只有一个后端容器。促销开始后访问量突然增加需要运行十个后端实例。此时会遇到一连串问题十个容器应该分配到哪些服务器某台服务器宕机后容器怎么办某个容器崩溃后谁负责重启用户请求怎样分发到不同容器发布新版本时怎样避免整个网站停机访问量下降后怎样减少实例节省资源这些事情靠人工处理并不现实。Kubernetes简称 K8s就是用来自动管理容器化应用的。Kubernetes 是一个用于管理容器化工作负载和服务的平台支持声明式配置和自动化。四、理解 Kubernetes 的几个基本概念Kubernetes 的概念很多入门时先抓住 Node、Pod、Deployment 和 Service 就够了。1、Node运行容器的机器Node 是 Kubernetes 集群中的工作机器可以是物理服务器也可以是云服务器或虚拟机。举个例子Kubernetes 集群├── Node 1192.168.1.11├── Node 2192.168.1.12└── Node 3192.168.1.13Kubernetes 会把应用分配到这些 Node 上运行。一个标准集群由控制平面和一台或多台工作节点组成。2、PodKubernetes 中最小的部署单位Kubernetes 通常不直接管理单个容器而是管理 Pod。一个 Pod 可以包含一个或多个关系非常紧密的容器。大多数业务场景中一个 Pod 里只有一个主要应用容器。Pod└── Java 应用容器Pod├── Java 应用容器└── ELK日志采集容器同一个 Pod 内的容器共享网络环境也可以共享存储。可以暂时把 Pod 理解为“给容器套了一层 Kubernetes 管理外壳”。3、Deployment管理 Pod 的数量和版本如果我们希望运行三个 Java 应用实例可以定义一个 DeploymentapiVersion: apps/v1 kind: Deployment metadata: name: demo-app spec: replicas: 3 selector: matchLabels: app: demo-app template: metadata: labels: app: demo-app spec: containers: - name: demo-app image: example/demo-app:1.0 ports: - containerPort: 8080其中replicas: 3表示期望运行三个 Pod。Kubernetes 会不断检查实际状态如果其中一个 Pod 崩溃Deployment 会重新创建一个。Kubernetes 关心的不是某个具体 Pod 必须永远活着而是系统要始终保持三个可用副本。4、Service给 Pod 提供稳定入口Pod 可能随时被销毁和重建IP 地址也可能变化。客户端不能把请求直接绑定到某个 Pod 的 IP。Service 会在一组 Pod 前面提供一个稳定的访问入口用户请求↓Service↙ ↓ ↘Pod Pod Pod即使后面的 Pod 被替换Service 的访问方式仍然可以保持不变。它还能把请求分发给多个 Pod。Kubernetes 官方将 Service 描述为向一个或多个 Pod 暴露网络应用的方法。对应的参考配置apiVersion: v1 kind: Service metadata: name: demo-app-service spec: selector: app: demo-app ports: - port: 80 targetPort: 8080 type: ClusterIP这里的选择器selector:app:demo-app会找到带有相同标签的 Pod。五、三者之间到底是什么关系接下来我们用个餐厅做比喻1、Docker负责标准化每一道菜。Docker 规定菜怎么做、需要哪些原料、做好后装进什么盒子。同一个镜像在不同机器上运行环境差异会小很多。2、Docker Compose负责一桌套餐。一个网站不只有后端还需要数据库和缓存。Compose 把这些服务写进同一份菜单一份套餐├── 前端├── 后端├── MySQL└── Redis执行一条命令整套服务一起启动。它通常管理的是一台主机上的多个容器。3、Kubernetes负责经营连锁餐厅。当应用分布在多台服务器上Kubernetes 开始发挥作用哪台服务器有空闲资源就把 Pod 调度过去。某个实例坏了就创建新的。顾客变多时可以增加应用副本。发布新版本时可以逐批替换旧版本。对外提供统一入口把请求分给不同实例。因此三者不是简单的替代关系而是层次不同应用代码↓Dockerfile 构建镜像↓Docker 运行容器↓Docker Compose 组织单机上的多个容器↓Kubernetes 编排集群中的容器化应用六、写在最后三者的定位可以简化为下面这张表工具主要用途常见使用场景Docker构建镜像、运行容器打包和运行单个应用Docker Compose定义并启动多个关联容器本地开发、测试、单机部署Kubernetes在集群中调度和管理容器化应用多机部署、扩容、故障恢复、滚动更新