返回八股知识点
八股知识点 / 发布 2026-06-12 16:30 / 更新 2026-06-15 00:32

容器化与编排

整理 Docker、Docker Compose、Kubernetes、K8s、K3s、Service、Ingress 和 NodePort 的概念、区别、作用与常见面试回答。

DockerKubernetes容器化K8s

Docker 是什么,有什么作用

书面笔记版

Docker 是一种容器化技术,用来把应用程序和它依赖的运行环境一起打包、分发和运行。它解决的核心问题是:开发、测试、生产环境不一致导致“我本地能跑,线上跑不了”。

常见概念:

概念 作用
镜像 Image 应用和依赖环境的只读模板,比如 JDK、应用 Jar、启动脚本
容器 Container 镜像运行起来后的进程实例
仓库 Registry 存放和分发镜像,比如 Docker Hub、Harbor
Dockerfile 描述如何构建镜像
数据卷 Volume 持久化容器数据,避免容器删除后数据丢失
网络 Network 让容器之间、容器和宿主机之间通信

Docker 的主要作用:

  • 环境一致:把应用依赖打进镜像,减少环境差异。
  • 部署简单:一条命令启动应用和依赖环境。
  • 隔离性好:容器有独立文件系统、进程、网络视图。
  • 资源开销小:容器共享宿主机内核,比虚拟机更轻量。
  • 方便扩缩容:镜像标准化后可以快速拉起多个实例。

Docker 不是虚拟机。虚拟机会虚拟完整操作系统内核,容器共享宿主机内核,启动更快、占用更少,但隔离强度通常弱于虚拟机。

面试口述版

Docker 是容器化技术,作用是把应用和依赖环境打包成镜像,再通过容器运行。它主要解决环境不一致、部署复杂和应用隔离的问题。镜像可以理解成模板,容器是镜像运行起来的实例,数据卷负责持久化数据,网络负责容器通信。和虚拟机比,Docker 共享宿主机内核,所以启动更快、资源占用更小。

Docker 部署有什么好处

书面笔记版

Docker 用来部署应用时,最大的好处不是“命令变少”这么简单,而是把部署对象从“服务器上的一堆环境配置”变成“一个可版本化、可分发、可重复运行的镜像”。

Docker 部署的主要好处:

  • 环境一致:应用依赖的 JDK、Node.js、系统库、启动脚本等都可以固化到镜像里,开发、测试、生产环境使用同一套镜像,减少“我本地能跑,线上跑不了”的问题。
  • 部署流程标准化:传统部署可能要手动安装运行环境、复制文件、改配置、写启动脚本;Docker 部署通常是拉取镜像、传入配置、启动容器,流程更固定。
  • 迁移方便:镜像可以推送到镜像仓库,在另一台服务器上拉下来就能运行,不太依赖某台机器上提前装好的环境。
  • 回滚简单:镜像天然有版本,比如 demo-app:1.0demo-app:1.1。新版本出问题时,可以重新启动旧版本镜像。
  • 启动快、资源开销小:容器共享宿主机内核,比虚拟机轻量,启动速度通常更快,适合快速发布和扩缩容。
  • 隔离性更好:不同应用可以运行在不同容器里,文件系统、进程、网络视图相对隔离,依赖冲突更少。
  • 方便配合自动化部署:镜像标准化以后,可以结合 Docker Compose、Kubernetes、CI/CD 实现批量部署、滚动发布、弹性扩缩容。

举个例子:一个 Spring Boot 项目依赖 JDK 17,同时还需要 MySQL 和 Redis。

传统部署方式一般是:

  1. 在服务器上安装 JDK 17。
  2. 上传 Jar 包。
  3. 配置环境变量、启动脚本、日志目录。
  4. 再单独安装和配置 MySQL、Redis。
  5. 如果换一台服务器,还要重复安装这些环境。

Docker 部署方式可以先给应用写一个 Dockerfile,把运行环境和 Jar 包打成镜像:

FROM eclipse-temurin:17-jre
COPY target/demo.jar /app/demo.jar
ENTRYPOINT ["java", "-jar", "/app/demo.jar"]

然后构建并运行:

docker build -t demo-app:1.0 .
docker run -d -p 8080:8080 demo-app:1.0

这样服务器不需要手动配置 JDK 和应用启动脚本,只要能运行 Docker,就可以通过镜像启动应用。如果还要一起启动 MySQL、Redis、Nginx,就可以再用 Docker Compose 把多个容器统一编排起来。

需要注意:Docker 主要解决的是应用打包、运行和单机容器管理问题。多机器调度、服务自愈、滚动发布、服务发现等更完整的生产级编排能力,通常交给 Kubernetes。

面试口述版

Docker 部署的好处是把应用和运行环境一起打包成镜像,让开发、测试、生产环境尽量一致。部署时服务器只需要拉镜像、启动容器,不用手动安装一堆依赖,迁移和回滚也更方便。比如一个 Java 应用原来要在服务器上装 JDK、传 Jar、配启动脚本,用 Docker 后可以把 JDK 和 Jar 打进镜像,用同一个镜像在不同环境运行。如果项目依赖 MySQL、Redis,还可以配合 Docker Compose 或 K8s 一起部署和管理。

Docker 和 Docker Compose 的区别

书面笔记版

Docker 和 Docker Compose 都属于 Docker 生态,但定位不同。

对比点 Docker Docker Compose
定位 容器运行和镜像管理工具 单机多容器编排工具
配置方式 常用 docker run 参数启动单个容器 compose.yml 描述多个服务
管理对象 镜像、容器、网络、数据卷 一组相关服务、网络和数据卷
典型场景 启动一个 MySQL、Redis、应用容器 一次启动 app + MySQL + Redis + Nginx
适用范围 单容器或手动管理多个容器 开发、测试、小规模单机部署

文件关系可以这样理解:

  • Dockerfile 解决的是“镜像怎么构建出来”。比如一个 Java 项目要把 JDK、Jar 包、启动命令打进镜像,就需要写 Dockerfile。
  • docker run 解决的是“一个容器怎么运行起来”。比如根据某个镜像启动一个应用容器,并指定端口、环境变量、数据卷等。
  • compose.yml 或旧写法 docker-compose.yml 解决的是“多个容器怎么一起运行起来”。比如一次性启动后端应用、MySQL、Redis、Nginx,并声明它们的网络、端口、数据卷、依赖关系。

所以不能简单理解成“Docker 只需要 Dockerfile,Docker Compose 必须需要 Dockerfile”。更准确地说:

场景 常见文件 说明
只构建自己的应用镜像 Dockerfile docker build 构建镜像,再用 docker run 启动容器
用 Docker Compose 启动现成服务 compose.yml 如果直接使用 mysql:8redis:7nginx:latest 这类现成镜像,可以不写 Dockerfile
用 Docker Compose 启动自己的应用和依赖服务 Dockerfile + compose.yml Compose 通过 build 字段引用 Dockerfile 构建应用镜像,再同时启动 MySQL、Redis 等服务

Docker Compose 的价值是把多容器启动参数写成声明式配置。例如一个后端项目需要 MySQL、Redis、RabbitMQ 和应用服务,如果只用 docker run,要手动创建网络、启动多个容器并维护参数;用 Compose 可以写在一个 compose.yml 里,用 docker compose up -d 一次拉起。

例如只用 Docker 部署一个后端应用时,通常是:

docker build -t demo-app:1.0 .
docker run -d --name demo-app -p 8080:8080 demo-app:1.0

如果这个后端还依赖 MySQL 和 Redis,就可以写成 Compose:

services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: demo

  redis:
    image: redis:7

然后执行:

docker compose up -d

这时 Compose 会根据 appbuild: . 找到当前目录下的 Dockerfile 构建应用镜像,同时拉起 MySQL 和 Redis。对于 MySQL、Redis 这种直接使用现成镜像的服务,就不需要单独写 Dockerfile。

需要注意:Compose 主要解决单机多容器编排,不负责跨机器调度、自愈、滚动发布和大规模服务治理。这类能力通常交给 Kubernetes。

面试口述版

Docker 主要负责构建镜像、运行容器;Docker Compose 是在 Docker 之上的单机多容器编排工具。比如只启动一个 Redis,用 docker run 就够了;如果一个项目要同时启动后端、MySQL、Redis、Nginx,就适合用 Compose 写成一个 compose.yml,一条命令启动。Compose 更适合开发测试和小规模单机部署,不像 K8s 那样做跨机器调度和自愈。

Kubernetes 和 K8s 是什么

书面笔记版

Kubernetes 简称 K8s,是容器编排平台。Docker 解决“怎么把应用打包成容器并运行”,K8s 解决“很多容器在多台机器上如何部署、调度、发现、扩缩容和故障恢复”。

常见核心对象:

对象 作用
Pod K8s 最小调度单位,通常包含一个主容器
Deployment 管理 Pod 副本、滚动更新和回滚
Service 给一组 Pod 提供稳定访问入口和负载均衡
Ingress 管理 HTTP/HTTPS 入口路由
ConfigMap 管理普通配置
Secret 管理密码、证书、Token 等敏感配置
Namespace 做资源隔离和环境划分

K8s 的主要能力:

  • 调度:根据资源、节点状态和策略把 Pod 分配到合适节点。
  • 自愈:Pod 挂了自动重建,节点异常时迁移。
  • 服务发现:通过 Service 屏蔽 Pod IP 变化。
  • 负载均衡:把请求分发到多个 Pod。
  • 弹性伸缩:根据副本数或指标扩缩容。
  • 滚动发布:逐批替换旧版本,支持回滚。
  • 配置管理:通过 ConfigMap、Secret 解耦配置。

面试口述版

Kubernetes 简称 K8s,是容器编排平台。Docker 更关注单个容器怎么运行,K8s 关注一堆容器在多台机器上怎么部署、调度、扩缩容、自愈和服务发现。K8s 里最小调度单位是 Pod,Deployment 管理副本和发布,Service 提供稳定访问入口,Ingress 做 HTTP 入口路由,ConfigMap 和 Secret 管理配置。

K8s 服务暴露和访问链路

书面笔记版

K8s 里外部请求通常不是直接访问 Pod。因为 Pod 会重建、漂移,Pod IP 不稳定,所以一般会通过 Service 提供稳定入口,再根据是否需要对外暴露选择 NodePortLoadBalancerIngress

常见三层可以这样记:

Pod / Deployment -> Service -> Ingress / NodePort / LoadBalancer
层级 作用
Pod / Deployment Pod 真正运行容器;Deployment 管理 Pod 副本、滚动发布和自愈
Service 给一组 Pod 提供稳定访问入口,并做集群内负载均衡
Ingress / NodePort / LoadBalancer 把服务暴露给集群外部访问

Service 常见类型:

类型 访问范围 说明
ClusterIP 集群内部 默认类型,只能在集群内通过 Service 名或 ClusterIP 访问
NodePort 集群外部可访问 在每个节点暴露一个端口,通过 NodeIP:NodePort 访问 Service
LoadBalancer 集群外部可访问 通常依赖云厂商负载均衡,把公网入口转发到 Service

Ingress 负责 HTTP/HTTPS 七层路由,常用于按域名、路径转发:

用户 -> 域名/公网入口 -> Ingress Controller -> Ingress 规则 -> Service -> Pod

需要注意:

  • Ingress 不是 ipress,正确名称是 Ingress
  • Ingress 本身只是规则,必须有 Ingress Controller 才能真正接流量和转发。
  • Ingress 常和域名一起用,生产环境一般会配域名和 HTTPS;但从概念上说,它核心是 HTTP/HTTPS 路由规则,不是“必须有域名才能存在”。
  • 标准 K8s 不一定默认自带外部网关或 Ingress Controller,需要自己安装 Nginx Ingress Controller、Traefik 等。
  • K3s 默认常带 Traefik 作为 Ingress Controller,所以学习或小规模部署时会觉得“默认有网关”。
  • 不用 Ingress 也能暴露服务,简单场景可以用 NodePort,直接访问 节点IP:端口

几种方式的选择:

方式 适合场景 优缺点
ClusterIP 服务只在集群内部被其他服务调用 安全简单,但外部不能直接访问
NodePort 临时测试、小规模暴露服务 简单直接,但端口范围固定,生产管理不够优雅
LoadBalancer 云环境生产暴露服务 使用方便,但依赖云厂商负载均衡资源
Ingress 多个 HTTP 服务共用入口、域名、路径和 HTTPS 适合生产 Web/API 入口,但需要 Ingress Controller

所以,NodePortIngress 都可以让外部访问服务,但层次不同:NodePort 是四层端口暴露;Ingress 是七层 HTTP/HTTPS 路由,通常更适合统一入口、域名、路径和证书管理。

面试口述版

K8s 里一般不是直接访问 Pod,因为 Pod IP 会变化。通常是 Deployment 管理 Pod,Service 给一组 Pod 提供稳定入口,然后再决定怎么对外暴露。ClusterIP 是默认类型,只能集群内部访问;NodePort 会在每个节点开一个端口,可以直接用 NodeIP:NodePort 访问,所以不用 Ingress 也能暴露服务;LoadBalancer 一般依赖云厂商负载均衡。Ingress 是 HTTP/HTTPS 七层入口,常按域名或路径转发到 Service,但它本身只是规则,必须有 Ingress Controller,比如 Nginx Ingress 或 Traefik。K3s 默认常带 Traefik,所以会感觉它有一个默认网关。

K8s 和 K3s 的区别

书面笔记版

K3s 是 Rancher 推出的轻量级 Kubernetes 发行版,可以理解成“瘦身版、易安装版 K8s”。它仍然兼容 Kubernetes API,但对组件、依赖和默认配置做了简化。

对比点 K8s K3s
定位 标准 Kubernetes 集群 轻量级 Kubernetes 发行版
资源占用 相对更高 更低,适合小机器和边缘节点
安装复杂度 组件多,搭建和维护成本更高 单二进制,安装更简单
默认组件 原生组件更完整,选择更灵活 内置轻量组件,如 SQLite、Traefik 等默认选项
适用场景 中大型生产集群、云原生平台 学习、测试、边缘计算、小规模部署

选择上可以这样理解:

  • 公司标准生产环境、复杂网络和多团队平台化:优先标准 K8s 或云厂商托管 K8s。
  • 个人学习、小项目、边缘设备、低资源服务器:K3s 更轻更快。
  • K3s 不是另一个完全不同的技术,它本质仍是 Kubernetes 生态。

面试口述版

K8s 是标准 Kubernetes,适合生产级、大规模容器编排;K3s 是轻量级 Kubernetes 发行版,兼容 K8s API,但安装更简单、资源占用更低。一般大公司生产环境会用标准 K8s 或云厂商托管 K8s,小机器、边缘节点、个人学习和小规模部署可以用 K3s。简单说,K3s 是更轻量、更易用的 K8s。