核心思想:Docker 解决了”如何打包和运送容器”,Kubernetes 解决”如何调度和运维海量容器”。它通过声明式 API 管理 Pod、Service、Deployment 等资源,实现自动调度、自愈、扩缩容、服务发现和滚动更新。

Pod

K8s 的最小调度单位。一个 Pod 可以包含一个或多个紧密协作的容器(共享网络栈和存储卷)。容器对 K8s 不可见——K8s 只调度 Pod。

Deployment

Deployment 用来声明式地管理无状态应用:定义”期望状态”(如 3 个副本、镜像版本 v1),K8s 持续把当前状态向期望状态对齐。

Deployment 示意

Rolling Update

在 Deployment 资源定义中,spec.strategy.type 有两种选择:

  • RollingUpdate:逐渐增加新版本的 Pod,逐渐减少旧版本的 Pod
  • Recreate:先把所有旧版本 Pod 删除,再创建新版本

大多数情况下采用 RollingUpdate 滚动更新。滚动更新可以通过 maxSurge 和 maxUnavailable 控制升级速率:

  • maxSurge:最大峰值,可以创建的超出期望 Pod 个数的 Pod 数量
  • maxUnavailable:最大不可用,更新过程中不可用 Pod 的个数上限

详见 官方文档。

Rolling update 流程

LivenessProbe 存活探针

存活探测器用来确定什么时候要重启容器。例如应用死锁(程序在运行但无法继续执行)时,重启容器可以恢复服务。

生产中应用可能因 bug 死锁或线程耗尽,无法继续提供服务。如果没有自动监控手段,可能很长时间无人发现。kubelet 通过 livenessProbe 周期性检测容器健康,失败则触发重启。

参考:LivenessProbe

ReadinessProbe 就绪探针

就绪探测器用来知道容器何时准备好接受请求流量。当一个 Pod 内的所有容器都就绪时,才认为该 Pod 就绪。

未就绪的 Pod 会被从 Service 的负载均衡器中剔除。这个机制的关键应用场景是升级保护:当发布的新版本存在问题、健康检查不过,新 Pod 不就绪,配合 RollingUpdate,K8s 会暂停升级,避免”全量升级后所有服务不可用”的灾难。

参考:ReadinessProbe

Service

直接访问 Pod 有几个痛点:

  • Pod 不就绪(Ready)时,K8s 不会把流量重定向到该 Pod——但你怎么知道?怎么做?
  • 通过 port-forward 把 Pod 端口暴露到本地需要写对 Pod 名字,一旦 Deployment 重新创建 Pod,名字和 IP 都会变
  • 如果一个 Deployment 部署了多个副本,如何做负载均衡?

K8s 用 Service 资源解决这些问题。Service 位于 Pod 之前,给 Pod 提供一个稳定的 Endpoint:

  • 接收请求,转发给后端的 Pod
  • Pod 集合变化时,Endpoints 自动更新,请求自然导向最新的 Pod
  • 内置负载均衡

Service 有四种类型:

Type 说明
ClusterIP(默认) 通过集群内部 IP 暴露,只能集群内部访问
NodePort 通过每个 Node 的 IP + 静态端口暴露,外部可访问
LoadBalancer 使用云提供商的负载均衡器对外暴露服务
ExternalName 通过返回 CNAME 把服务映射到外部域名(如 foo.bar.example.com),无需创建代理

ClusterIP

集群内部访问,默认类型。

ClusterIP 示意

NodePort

K8s 集群不是单机,由多个 Node 组成。NodePort 通过每个节点上的 IP 和静态端口暴露服务。

如下图,集群有两台 Node 都运行着 hellok8s:v3。创建一个 NodePort 类型的 Service,把 hellok8s:v3 的 3000 端口映射到 Node 机器的 30000 端口(在 30000-32767 范围内)。这样可以通过 http://node1-ip:30000 或 http://node2-ip:30000 访问到服务。

NodePort 示意

LoadBalancer

LoadBalancer 使用云提供商的负载均衡器向外部暴露服务。外部 LB 可以把流量路由到自动创建的 NodePort 和 ClusterIP 服务上。

例如在 AWS EKS 集群上创建 LoadBalancer 类型的 Service,会自动创建一个 ELB(Elastic Load Balancer),并可以根据 IP 池分配一个独立 IP 地址供外部访问。

LoadBalancer 示意

Ingress

Ingress 是集群对外的 HTTP / HTTPS 入口。可以理解为服务的网关 Gateway。

Ingress 资源上定义路由规则,控制流量去向。Ingress 能为 Service 提供:

  • 外部可访问的 URL
  • 负载均衡
  • SSL / TLS
  • 基于名称的虚拟托管

⚠️ Ingress 资源本身没有效果——还需要一个 Ingress 控制器(通常通过负载均衡器实现 Ingress 路由)。

Ingress 示意

Namespace

实际开发中需要不同环境(dev / test / uat / prod)做开发和测试。K8s 通过 Namespace 把同一集群的资源划分为相互隔离的组:

  • 同一 Namespace 内资源名称必须唯一,跨 Namespace 没有这个要求
  • Namespace 作用域仅针对带命名空间的对象(如 Deployment、Service 等),集群级资源(如 Node、PersistentVolume)不受影响

ConfigMap

不同环境的配置(如数据库地址)往往不一样。把配置硬编码进代码会出大问题。

ConfigMap 把配置数据和应用代码分开,以键值对保存非机密数据。

⚠️ ConfigMap 不是用来保存大量数据的——单个 ConfigMap 最大 1 MiB。需要保存更大的数据请考虑挂载存储卷。

Secret

ConfigMap 适合非机密配置,但密码、API key 之类的敏感数据应该用 Secret。

Secret 的资源定义和 ConfigMap 结构基本一致,区别是:

  • kind: Secret
  • value 需要 Base64 编码(也可以用 stringData 字段绕过编码)

⚠️ Base64 不是加密,只是编码。生产环境应该通过 pipeline 或专业的 KMS 服务(如 AWS KMS)做密钥管理。

默认情况下,Secret 在 API Server 的底层数据存储(etcd)中是未加密存储的。任何拥有 API 访问权限或 etcd 访问权限的人都可以检索或修改 Secret。

安全使用 Secret 的步骤

  1. 为 Secret 启用静态加密
  2. 启用并配置 RBAC 规则 限制读取和写入 Secret 的权限(包括间接访问——能创建 Deployment 的人也能间接读 Secret)
  3. 用 RBAC 限制谁可以创建新 Secret 或替换现有 Secret

Job

之前的资源都用于”长期运行”的服务。但还有一类是一次性任务(如批处理、数据计算)——只需算完得出结果即可,无需常驻。这就是 Job 的用武之地。

Job 的行为:

  • 创建一个或多个 Pod,重试直到指定数量的 Pod 成功终止
  • 记录成功完成的 Pod 个数
  • 当达到指定的成功阈值时,Job 标记完成
  • 删除 Job 时清除其创建的所有 Pod

关键字段:

  • completions:要完成的 Pod 总数
  • parallelism:并发执行最大数量(例如设 3,先创建 3 个 Pod 并发执行;某个完成就创建新的,直到 completions 总数达到)
  • restartPolicy: OnFailure:Pod 因非零退出码或内存超限被杀时,留在节点上重新运行(vs. Never — 不重启)

💡 Job 完成时不会再创建新 Pod,但已有的 Pod 不会自动删除——保留 Pod 日志方便排查。要清理用 kubectl delete -f hello-job.yaml。

CronJob

CronJob 可以理解为定时任务——基于 Cron 时间调度的 Job。

适合周期性的工作:备份、报告生成、清理过期数据等。配置为每天/每周/每月一次。

Helm

操作系统装应用用 apt 或 brew,不需要关心依赖和配置细节。Kubernetes 装应用也希望一条命令搞定——这就是 CNCF 毕业项目 Helm 的工作。

Helm 是 Kubernetes 的包管理器,类比 apt 之于 Ubuntu。

Helm 的核心价值:

  • 复杂性管理:再复杂的应用,Helm Chart 也能描述并提供可重复安装
  • 易于升级:随时升级和自定义钩子,消除升级痛苦
  • 简单分发:Chart 容易在公共/私有仓库发版分发
  • 回滚:helm rollback 一键回到之前版本

安装(macOS):

brew install helm

更多安装方式见 官方文档。

工作模型:

  • Chart:Helm 的”包”,描述一个应用的所有 K8s 资源
  • Release:一次安装的实例(同一 Chart 可以在集群里装多次得到多个 Release)
  • Repository:Chart 仓库,可以从公共仓库或自建仓库拉取 Chart

Dashboard

Kubernetes Dashboard 是官方的网页 UI。功能:

  • 把容器应用部署到 K8s 集群
  • 对容器应用排错
  • 管理集群资源
  • 对 Deployment 弹性伸缩、滚动升级、重启 Pod
  • 通过向导创建新应用

本地 minikube 开启 Dashboard:

minikube dashboard

K9s

K9s 是基于 Terminal 的轻量级 UI,比网页 Dashboard 更适合运维场景。安装后直接 k9s 开启 Terminal Dashboard——可以观察和管理已部署的 K8s 资源,键盘驱动效率更高。

参考资料