知已难寻头像
第 4 篇 · 容器与 Kubernetes:云原生的核心引擎封面图

第 4 篇 · 容器与 Kubernetes:云原生的核心引擎

第 4 篇 · 容器与 Kubernetes:云原生的核心引擎

本篇覆盖全景图的 第 ④ 层:容器与编排(CaaS),是云原生的核心。

上一篇我们看到,虚拟机仍带完整操作系统、启动慢。容器用更轻的"进程级隔离"解决了这个问题;
但当容器数量成千上万、跨多台机器时,如何调度、故障自愈、服务发现、弹性伸缩?这就需要 容器编排,而 Kubernetes(K8s)是这个领域的事实标准。

本篇把容器原理、Docker、容器运行时、Kubernetes 架构与核心对象讲透。


一、容器到底是什么:从原理说起

1. 容器不是"轻量虚拟机"

很多人以为容器是"精简版虚拟机",这是误解。正确的理解是:

容器本质上是宿主机上的一个普通进程,但被 Linux 内核的 Namespace 和 Cgroups 技术加上了"边界",让它看起来像一台独立的机器。

  • 虚拟机的隔离由 Hypervisor 实现,要虚拟出完整硬件、跑独立 Guest OS;
  • 容器的隔离由 Linux 内核实现,所有容器共享宿主机内核,没有独立的操作系统。

容器的实现依赖三大内核技术:Namespace(隔离"看得到什么")、Cgroups(限制"用得了多少")、联合文件系统(提供"独立的文件")。

2. Namespace:让容器"看到"独立的世界

Namespace(命名空间)通过内核技术,让容器中的进程只能看到自己这一份系统资源,从而实现"隔离"。

每次你运行一个容器,Docker 就会为它创建一组 Namespace:

Namespace隔离的资源作用
PID进程编号容器内进程从 1 开始编号,看不到宿主机和其他容器的进程
NET网络设备/协议栈容器有独立的网卡、IP、端口、路由表
MNT挂载点(文件系统)容器看到独立的目录树
UTS主机名/域名容器有自己的 hostname
IPC进程间通信容器内的信号量、消息队列隔离
USER用户/用户组容器内 root 可映射为宿主机普通用户
CgroupCgroup 根目录容器看到的资源视图隔离

对比:docker run --pid=host nginx 会让容器共享宿主机 PID Namespace,它就能看到宿主机所有进程——这反过来说明了 PID Namespace 的隔离作用。

3. Cgroups:限制容器"能用多少"资源

Namespace 解决"隔离",但容器内进程仍可能吃光所有 CPU/内存。Cgroups(Control Groups)负责限制一组进程能使用的资源上限。

Cgroups 可以限制:

  • CPU:占用比例(cpu.shares)、CPU 核数(cpuset)、配额(cpu.cfs_quota_us);
  • 内存:内存使用上限(memory.limit_in_bytes),超了会触发 OOM 被杀;
  • 磁盘 I/O:读写带宽、IOPS;
  • 设备访问:允许使用哪些设备。

一句话:Namespace 管"隔离",Cgroups 管"限额"。
例如 docker run --cpus=1 --memory=512m nginx 就是在配置 Cgroups。

4. 联合文件系统与 rootfs:容器的"独立文件"

容器要有自己的文件系统(/bin、/etc、应用文件等),这就是 rootfs(根文件系统)。

  • rootfs 是容器启动时挂载的根目录,它不包含操作系统内核,只包含文件和目录(内核共享宿主机的)。
  • rootfs 通过 联合文件系统(UnionFS) 实现,采用分层结构:

镜像分层(只读,从上到下)

可读写层(容器运行时,可读写)

基础镜像层(如 Debian,只读)

镜像层(应用 + 依赖)

Init 层(存放 /etc/hosts、hostname 等)

常见联合文件系统:Overlay2(Docker 默认)、AUFS、Device Mapper、Btrfs。

分层的好处:多个容器可以共享只读的基础镜像层,各自只加一层可读写层,节省磁盘、启动快。

5. 容器 vs 虚拟机(再强调一次)

对比虚拟机容器
隔离技术Hypervisor(KVM/ESXi)Namespace + Cgroups
是否共享内核否(独立 Guest OS)是(共享宿主机内核)
隔离强度强(硬件级)较弱(进程级)
启动速度分钟级秒级/毫秒级
镜像大小几 GB几 MB~几百 MB
单机数量几十上千
跨平台一般一次构建、到处运行

二、Docker:容器的"打包与运行"平台

1. Docker 架构

Docker 是一个 C/S 架构的平台:

REST API

docker CLI(命令行客户端)

Docker Daemon(dockerd,守护进程)

containerd(容器管理,行业标准)

runc(真正创建/运行容器的底层工具)

容器进程(带 Namespace/Cgroups)

  • Docker Client(CLI):用户输入命令的地方;
  • Docker Daemon(dockerd):守护进程,监听 API、管理镜像、容器、网络、卷;
  • containerd:从 Docker 中剥离出来的容器管理组件,负责镜像传输、容器生命周期(但不直接创建容器);
  • runc:OCI 参考实现,真正调用 Namespace/Cgroups 把容器跑起来。

2. 镜像与容器

  • 镜像(Image):容器的"只读模板",打包了应用和运行环境(rootfs + 配置)。镜像分层、只读、可复用。
  • 容器(Container):镜像的一个运行实例。关系类似"类与对象"、“程序与进程”。

镜像名格式:[仓库地址/]名称:标签,如 nginx:1.25、registry.cn-hangzhou.aliyuncs.com/xxx/app:v1。

3. Dockerfile:用代码构建镜像

Dockerfile 是一个文本文件,用一条条指令描述如何构建镜像。 它是实现"基础设施即代码"的关键。

指令作用
FROM指定基础镜像(如 FROM openjdk:17)
WORKDIR设置工作目录
COPY / ADD把文件复制进镜像
RUN构建时执行命令(如装依赖)
ENV设置环境变量
EXPOSE声明容器端口
CMD容器启动时默认执行的命令(可被覆盖)
ENTRYPOINT容器启动时固定执行的入口

示例(一个 Java 应用):

FROM openjdk:17-jre-slim
WORKDIR /app
COPY target/demo.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
# 构建镜像
docker build -t demo:v1 .
# 运行容器(-d 后台,-p 端口映射)
docker run -d -p 8080:8080 --name mydemo demo:v1
# 查看 / 进入 / 停止 / 删除
docker ps ; docker exec -it mydemo sh ; docker stop mydemo ; docker rm mydemo

4. 容器网络

Docker 单主机默认有几种网络模式:

模式说明
bridge(默认)容器连到虚拟网桥 docker0,通过 NAT 与外界通信,容器间可互通
host容器直接用宿主机网络,无网络隔离,性能最高
none只有 lo 回环,无网络,需自己配置
container复用另一个容器的网络栈

单主机网络够用,但跨主机的容器如何互通?这是 K8s + CNI 网络插件要解决的(见后文)。

5. 数据卷(Volume)

容器的可读写层在容器删除后会丢失。要持久化数据,需要数据卷:

  • Volume:由 Docker 管理的独立存储,挂载进容器;
  • Bind Mount:挂载宿主机指定目录;
  • 容器内数据(如数据库文件)应放到卷里,避免容器重建丢数据。

6. 容器运行时与 OCI 标准

  • OCI(开放容器倡议):定义了容器的两大标准——镜像规范(镜像长什么样)和运行时规范(容器怎么运行)。
  • 底层运行时:runc(最常用);
  • 高层运行时(负责镜像、网络、存储):containerd、CRI-O(RedHat 主推,专用于 K8s)。

演进:早期 Docker 是"大而全"的单体;后来 containerd 被剥离并捐赠给社区,成为云原生的标准运行时。K8s 通过 CRI(容器运行时接口) 调用 containerd 或 CRI-O,现代 K8s 已经不依赖完整的 Docker。


三、为什么需要容器编排

当你只有几个容器,手动 docker run 没问题。但在生产环境,问题接踵而至:

  • 容器挂了,谁来自动重启?
  • 一台机器宕了,上面的容器怎么办?
  • 流量大了,谁来自动扩容到 100 个副本,过后再缩?
  • 容器分散在几十台机器上,怎么让它们互相找到、怎么把流量负载均衡过去?
  • 怎么滚动更新而不中断业务?出问题怎么一键回滚?

这些问题靠人工或脚本无法解决,需要一个"集群操作系统"统一管理,这就是容器编排(Orchestration)。

编排领域曾经有三大方案(同类竞争):

方案特点现状
Kubernetes(K8s)Google 开源,功能强大、生态繁荣事实标准,胜出
Docker SwarmDocker 原生,简单、轻量小众,适合小规模
Apache Mesos早期大数据/混合调度强已基本退出主流

K8s 源自 Google 内部使用了十余年的 Borg 系统,2014 年开源,2015 年由 CNCF 托管。


四、★ Kubernetes:集群的"操作系统"

1. Kubernetes 是什么

Kubernetes(K8s,8 代表中间的 8 个字母)是一个开源的容器编排平台,负责在多台机器组成的集群上自动部署、调度、扩缩、管理容器化应用。

它提供的核心能力:

  • 服务发现与负载均衡:给容器一个统一入口,自动分发流量;
  • 自动装箱(调度):根据资源需求把容器放到合适的节点;
  • 自愈(Self-healing):容器挂了自动重启,节点坏了重新调度;
  • 自动扩缩容(HPA):按 CPU/内存/自定义指标自动增减副本;
  • 滚动更新与回滚:逐步替换旧版本,可一键回退;
  • 密钥与配置管理:ConfigMap、Secret,不用重新打包镜像;
  • 存储编排:自动挂载本地存储、云盘、NFS 等。

2. 集群架构:Master 与 Node

工作节点 Node(干活的机器)

控制平面 Master(大脑,管理集群)

watch/上报

工作节点 Node

kubelet + kube-proxy + 运行时 + Pods

kube-apiserver
所有操作的唯一入口,REST API

etcd
分布式键值库,存集群所有状态/配置

kube-scheduler
决定 Pod 放到哪个节点

kube-controller-manager
各类控制器,维持期望状态

cloud-controller-manager
对接云厂商 API

kubelet
管理本机 Pod 生命周期,向 Master 汇报

kube-proxy
维护 Service 网络规则/负载均衡

容器运行时
containerd / CRI-O

Pod1

Pod2

控制平面组件:

  • kube-apiserver:所有组件都通过它交互(其他组件不直接互相通信),是集群的"网关",负责认证、鉴权;
  • etcd:高可用键值数据库,集群的唯一数据源,存所有 Pod、Service、配置等状态(生产环境通常 3/5 个节点做冗余);
  • kube-scheduler:监听待调度 Pod,根据资源/亲和性/污点等选择最合适的节点;
  • kube-controller-manager:运行一系列控制器(节点控制器、副本控制器、端点控制器等),不断把"实际状态"向"期望状态"靠拢;
  • cloud-controller-manager:与云厂商交互(创建云盘、负载均衡器)。

工作节点组件:

  • kubelet:每个节点上的代理,接收 Pod 定义、调用运行时创建容器、健康检查、汇报状态;
  • kube-proxy:维护节点上的网络规则,实现 Service 的负载均衡和访问;
  • 容器运行时:containerd / CRI-O,负责真正跑容器。

3. 核心对象:Pod 是最小调度单位

K8s 不直接管理"容器",而是管理 Pod:

  • Pod:K8s 中最小的部署和调度单元,一个 Pod 里通常有一个主容器(也可有多个紧密配合的 Sidecar 容器),它们共享网络和存储(同一 IP、同一网络命名空间)。
  • Pod 是"用完即弃"的,故障重建后 IP 会变,所以不能直接依赖 Pod IP。

4. 声明式 API:YAML 与"期望状态"

K8s 的核心哲学是声明式(Declarative):

  • 你不需要一步步告诉它"怎么干"(命令式),只需用 YAML 描述"我想要什么状态"(如"我要 3 个 nginx 副本");
  • 控制器持续工作,让实际状态 = 期望状态。这就是"自愈"的来源。

一个 Deployment 示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 3                 # 期望 3 个副本
  selector:
    matchLabels:
      app: nginx
  template:                   # Pod 模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80
# 应用 / 查看 / 删除
kubectl apply -f deploy.yaml
kubectl get pods -o wide
kubectl describe pod <pod>
kubectl delete -f deploy.yaml

5. 常用工作负载对象

对象作用
Pod最小单元,一个或多个容器
Deployment管理无状态应用的多副本,支持滚动更新、回滚(最常用)
ReplicaSet维持指定副本数(通常由 Deployment 管理,不直接用)
StatefulSet管理有状态应用(数据库、消息队列),提供稳定的网络标识和持久化存储
DaemonSet每个节点跑一个 Pod(日志采集、监控代理、网络插件)
Job / CronJob一次性任务 / 定时任务

6. 配置与密钥

对象作用
ConfigMap存放非敏感配置(如配置文件、环境变量),可挂载或注入
Secret存放敏感信息(密码、证书、镜像拉取凭证),以 Base64 编码

好处:配置和镜像分离,换配置不用重新构建镜像。

7. ★ 服务发现与网络:Service、DNS、Ingress

因为 Pod IP 会变、且有多个副本,K8s 用 Service 提供稳定的访问入口:

访问请求

Service
固定 ClusterIP + 名称
(负载均衡器)

Pod1 (10.1.1.1)

Pod2 (10.1.1.2)

Pod3 (10.1.1.3)

  • Service:为一组 Pod 提供固定的虚拟 IP(ClusterIP)和 DNS 名称,并自动负载均衡到后端健康的 Pod。即使 Pod 重建,Service 不变。
  • Label / Selector:Service 通过标签(Label)找到它要代理的 Pod。
  • DNS(CoreDNS):集群内置 DNS,服务之间直接用服务名访问(如 http://user-service:8080)。

Service 的几种类型:

类型说明
ClusterIP(默认)集群内部访问的虚拟 IP
NodePort在每个节点上开放一个端口(30000-32767),可从外部访问
LoadBalancer对接云厂商负载均衡器,提供公网入口(云上标准)
ExternalName映射到外部域名

Ingress:

  • Service 工作在四层(TCP),而 Ingress 工作在七层(HTTP/HTTPS),可以基于域名、路径把流量路由到不同 Service,并提供 SSL 终止;
  • 需要 Ingress 控制器(如 Nginx Ingress、Traefik)。

a.com/api

b.com

外部 HTTP 流量

Ingress 控制器

Service A

Service B

CNI:跨主机容器网络

K8s 自身不规定容器怎么联网,而是通过 CNI(容器网络接口) 插件实现跨主机 Pod 互通。常见 CNI(同类):

  • Flannel:简单(常用 VXLAN 覆盖网络),适合入门;
  • Calico:基于 BGP、支持网络策略(NetworkPolicy),性能与安全强,生产主流;
  • Cilium:基于 eBPF,高性能、可观测性强,是新兴热门;
  • 云厂商方案:AWS VPC CNI、阿里云 Terway。

网络策略(NetworkPolicy)相当于容器间的"防火墙规则",类比物理网络的防火墙 / 安全组。

8. 存储:PV、PVC、StorageClass

容器有状态数据需要持久化,K8s 用一套抽象对接各种存储:

挂载

绑定

Pod 中的容器

PVC(用户的存储申请,声明要多大/什么类型)

PV(实际存储资源,管理员或自动创建)

StorageClass
(动态创建 PV 的模板)

后端:NFS / 云盘 / Ceph / iSCSI

  • PV(PersistentVolume):集群中的一块实际存储(如一块云盘、一个 NFS 目录);
  • PVC(PersistentVolumeClaim):用户对存储的"申请"(要 10GB、读写模式),无需关心底层细节;
  • StorageClass:定义"动态供给"模板,PVC 提交时自动创建 PV(对接云盘/Ceph),无需管理员手动建;
  • CSI(容器存储接口):存储插件标准,让 K8s 能接入各种存储(类似网络的 CNI)。

对比记忆:CNI 管网络、CSI 管存储、CRI 管容器运行时——K8s 用这三大接口 + 插件实现"可插拔"。

9. 调度、自愈与弹性

  • 调度:Scheduler 监听新 Pod,根据资源请求(requests/limits)、节点选择器、亲和性(Affinity)、污点容忍(Taints/Tolerations)选择节点;
  • 自愈:kubelet 做**探针(Probe)**健康检查:
    • livenessProbe(存活探针,失败重启容器);
    • readinessProbe(就绪探针,失败则从 Service 摘除流量);
    • startupProbe(启动探针,保护慢启动应用);
  • HPA(水平自动扩缩):根据 CPU/内存/自定义指标自动增减 Pod 副本数;
  • 滚动更新:Deployment 逐步创建新 Pod、删除旧 Pod,全程业务不中断;kubectl rollout undo 可回滚。

10. 一个请求的完整链路(串起来)

用户

云负载均衡 / Ingress

Service(kube-proxy 规则)

Pod(容器)

StatefulSet 数据库 / 挂载 PVC


五、Helm、Operator:K8s 的"包管理"与"自动化运维"

1. Helm:K8s 的包管理器

裸写一堆 YAML 部署复杂应用(如 MySQL、Redis 集群)很繁琐。Helm 把一组 YAML 模板打包成 Chart,可参数化、版本化、一键安装/升级,类似 Linux 的 apt/yum。

  • Chart:应用模板包;Release:Chart 的一次安装实例;
  • 常用:helm install、helm upgrade、helm rollback。

2. CRD 与 Operator

  • CRD(自定义资源定义):允许你在 K8s 原生对象之外定义新的资源类型(如 MySQLCluster);
  • Operator = CRD + 自定义控制器,把人类运维专家的知识(部署、备份、故障恢复、扩容)编码成软件,实现复杂有状态应用的自动化运维。
  • 例如:PostgreSQL Operator 能自动建主从、自动备份、故障切换。

同类工具:Kustomize(K8s 原生的模板化方案,无模板语法)。


六、K8s 与虚拟化、云的关系(定位)

K8s 集群(跑在虚拟机或裸金属上)

IaaS 云(OpenStack / 阿里云)

虚拟机(KVM/ESXi)

Node 节点

大量 Pod(容器)

  • K8s 节点可以是物理机(裸金属 K8s),也可以是 OpenStack/公有云上的虚拟机(云上托管 K8s,如阿里云 ACK、AWS EKS、华为 CCE);
  • 定位:KVM/ESXi 虚拟化的是"资源",K8s 编排的是"应用(容器)";前者是 IaaS,后者是 CaaS。

七、本篇总结

核心记忆点:

  • 容器三大内核技术:Namespace(隔离)、Cgroups(限额)、UnionFS(分层文件);
  • 容器本质:带边界的普通进程,共享宿主机内核;
  • Docker 架构:CLI → dockerd → containerd → runc;
  • 标准:OCI(镜像/运行时),运行时 containerd / CRI-O;
  • K8s 架构:Master(apiserver/etcd/scheduler/controller)+ Node(kubelet/kube-proxy/运行时);
  • K8s 核心:Pod、Deployment、Service、Ingress、ConfigMap、PV/PVC;
  • 三大接口:CRI(容器)、CNI(网络)、CSI(存储);
  • 上层:Helm(包管理)、CRD/Operator(自动化运维);
  • 编排同类:K8s(胜出)/ Swarm / Mesos。

下一篇:有了 K8s 这个"底座",如何围绕它构建完整的云原生应用?
我们讲 微服务、服务网格、DevOps/CI-CD、GitOps、基础设施即代码、可观测性(监控/日志/链路追踪)、Serverless,并梳理主流云厂商服务地图和学习路线,完成整个知识体系的最后一块拼图。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_65272847/article/details/169166204

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--