Kubernetes 零基础入门:从认识概念到部署第一个网站
这篇教程面向第一次接触 Kubernetes 的读者。你不需要先记住所有缩写,先弄懂它解决什么问题,再跟着练习部署一个网站。
一、什么是 K8s?
Kubernetes 是一个用于自动化部署、扩缩容和管理容器化应用的开源平台。
它的名字比较长,通常缩写为K8s:字母 K 和 s 中间有 8 个字母。
Google 在 2014 年开源了 Kubernetes。后来,它成为 CNCF(Cloud Native Computing Foundation,云原生计算基金会)旗下的项目,由开源社区共同开发和维护。CNCF 是支持相关开源技术发展的基金会。项目历史
用最简单的话说:K8s 是管理一群服务器和容器应用的“大管家”。
比如,你有一个网站,希望它始终运行 3 份。你告诉 K8s 这个要求,它就会持续检查实际情况,并尽量让网站保持 3 份运行实例。
这里的“实例”,就是同一个程序实际运行起来的一份。
1. 先分清程序、镜像和容器
假设你写了一个网站,它需要代码、运行环境和一些依赖库才能运行。
| 名称 | 通俗解释 | 网站例子 |
|---|---|---|
| 应用程序 | 完成某项功能的软件 | 你写的网站 |
| 依赖 | 程序运行时需要的其他软件或代码库 | Python、第三方库等 |
| 镜像 Image | 打包好的程序及其所需文件,可以反复用来创建容器 | 网站的“安装模板” |
| 容器 Container | 根据镜像启动的一份运行环境和程序 | 正在运行的一份网站 |
| 镜像仓库 Registry | 存放、下载和分发镜像的地方 | Docker Hub、公司内部镜像仓库 |
可以把镜像想成“蛋糕模具”,容器想成“用模具做出来的蛋糕”。同一个镜像可以启动多个容器。
镜像提高了运行环境的一致性,但仍需要匹配的操作系统、处理器架构等条件,不能理解成“任何机器都能直接运行”。
2. Docker 和 K8s 是什么关系?
Docker 是一套构建、分发和运行容器的工具;K8s 负责协调大量容器应用的部署和运行。
继续用港口作比喻:
- Docker 帮你准备和运行“集装箱”。
- K8s 像港口的调度系统,安排这些集装箱放在哪里、运行多少份、出故障后怎么补上。
现代 K8s 节点常用containerd或CRI-O运行容器。它们叫“容器运行时”,就是实际启动、停止容器的底层软件。
K8s 从 1.24 起移除了内置的 Docker Engine 适配层 dockershim,但 Docker 构建的兼容镜像仍然可以使用。这不等于“学 K8s 就不能用 Docker”。官方说明
3. K8s 能帮你做什么?
| 能力 | 用小白能理解的话解释 |
|---|---|
| 部署和调度 | 根据资源需求与规则,选择合适的机器来运行程序 |
| 故障恢复 | 按策略重启失败的容器;由控制器为受管理的应用补建 Pod |
| 扩缩容 | 增加或减少应用运行的份数;配置自动扩缩容后,可以按指标自动调整 |
| 服务发现和负载均衡 | 用稳定的服务名称找到应用,并把连接分配给多个可用实例 |
| 滚动更新 | 分批替换应用实例,降低发布时的中断风险 |
| 配置和存储管理 | 给应用提供配置、敏感信息以及存储接入方式 |
“负载均衡”就是把访问请求或连接分配给多个实例,避免所有访问都压在同一个实例上。Kubernetes 概览
这些能力都有前提。例如,服务器坏了,需要其他机器还有可用资源;升级时想持续提供服务,需要合理的副本数量、健康检查和应用设计。K8s 不会自动修复程序里的代码错误,也不会凭空增加硬件资源。
4. 什么时候需要 K8s?
只有一两个小程序、运行在一台服务器上时,Docker 或 Docker Compose 往往就能满足需求。Docker Compose 是用一份配置文件管理一组容器的工具。
当应用越来越多,需要统一发布、经常扩缩容、跨多台机器运行,或者希望部分机器故障时仍能提供服务,就可以考虑 K8s。
这并不取决于是否达到“几十台服务器”。关键是你的管理需求是否值得承担 K8s 带来的学习和维护成本。
二、先掌握这几个基础概念
1. Cluster、Node 和 Pod
| 名称 | 中文 | 你可以这样理解 |
|---|---|---|
| Cluster | 集群 | 一组由 K8s 统一管理的机器及相关组件;学习环境也可以只有一台机器 |
| Node | 节点 | 集群中的一台机器,可以是物理服务器,也可以是虚拟机 |
| Pod | 最小部署单元 | K8s 安排到节点上运行的“小包裹”,里面装着一个或多个容器 |
初学时,先按“一个 Pod 里运行一个主要容器”理解即可。多个网站副本,通常对应多个 Pod,而不是把所有副本塞进同一个 Pod。
同一个 Pod 中的容器共享网络,可以通过localhost(当前本地网络环境)互相访问;它们也可以挂载同一份 Volume(存储卷)来共享文件。它们不会自动共享各自容器里的全部文件。Pod 官方说明
2. Deployment:替你管理应用副本
Deployment 是管理一组应用 Pod 的资源对象。“资源对象”就是 K8s 能识别、记录和管理的一类配置。
例如,创建一个 Deployment,并声明replicas: 3,就是告诉 K8s:“请保持 3 个 Pod 副本。”
Deployment 通过ReplicaSet(副本集)管理 Pod。ReplicaSet 负责维持期望的 Pod 数量,Deployment 在它之上管理发布更新等过程。
关系可以这样记:
Deployment:管理应用发布和版本 ↓ ReplicaSet:维持指定数量的 Pod ↓ Pod:承载容器 ↓ Container:实际运行程序如果一个受 Deployment 管理的 Pod 被删除,控制器会补建新的 Pod。如果你只单独创建一个 Pod,没有这类控制器管理,删掉后通常不会自动补回来。Deployment 官方说明
3. Service:给应用一个稳定入口
Pod 重建后,名字、IP 地址可能改变。IP 地址可以理解为网络中用来找到一个设备或服务的地址。
Service 为一组 Pod 提供稳定的访问方式。调用方通过服务名称访问应用,不用逐个记住 Pod IP。
Service 通常通过Label(标签)和Selector(选择器)找到后端 Pod:
- Label:给 Pod 贴标签,例如
app: web,表示“这个 Pod 属于 web 应用”。 - Selector:按标签筛选,例如“找到所有带
app: web标签的 Pod”。
这里的 Service 是 K8s 中一种明确的资源类型,和口语里的“网站服务”不是完全相同的概念。Service 官方说明
4. Namespace:给资源分组
Namespace(命名空间)可以理解为集群里的项目文件夹。
例如,用dev放开发环境资源,用test放测试环境资源。不同 Namespace 中可以存在同名的 Deployment。
它主要提供资源名称与管理范围的划分,不会自动阻止不同 Namespace 的应用相互访问。网络隔离还需要 NetworkPolicy(网络策略)及支持它的网络插件;权限也需要另外配置。Node、PV 等部分资源不属于某个 Namespace。命名空间、网络策略
5. kubectl、YAML 和声明式管理
kubectl是操作 Kubernetes 的命令行工具。你输入命令,它把请求发送给集群。
YAML是一种文本配置格式,通常保存为.yaml文件。它通过缩进表示层级,例如:
spec: replicas: 3这里表达的是“期望副本数为 3”。写 YAML 时使用空格缩进,不要用 Tab。
声明式管理,就是描述你想要的结果,让系统持续尝试实现它。
- 期望状态:我希望有 3 个 Pod。
- 实际状态:现在只有 2 个 Pod。
- 调整动作:控制器创建一个新的 Pod。
你负责说清楚“想要什么”,K8s 负责持续协调。实际状态不一定能立刻达到期望状态,例如资源不足时,新 Pod 可能一直在等待。
三、安装一个用来学习的 K8s 集群
本教程使用Docker + minikube + kubectl,在自己的电脑上完成练习。
| 工具 | 在本教程中的作用 |
|---|---|
| Docker | 提供运行 minikube 节点的环境 |
| minikube | 帮你在本地创建和管理学习用的 Kubernetes 集群 |
| kubectl | 操作集群里的应用和资源 |
minikube 支持单节点和多节点;本教程创建一个单节点集群。生产环境指“真正向用户提供服务的环境”,它的高可用、存储和运维要求更复杂,不能直接照搬这套本地练习配置。安装工具说明
第 1 步:准备电脑和 Docker
minikube 官方列出的基本条件包括至少 2 个 CPU、2 GB 可用内存和 20 GB 可用磁盘空间。考虑到 Docker、浏览器等也会占资源,做本教程时建议电脑至少有 8 GB 内存,并能给集群分配约 4 GB 内存。minikube 安装说明
按系统安装 Docker:
- macOS:下载 Docker Desktop for Mac。Apple 芯片选择 Apple silicon 版本,Intel 芯片选择 Intel 版本。打开安装包,把 Docker 拖入“应用程序”,然后启动它。
- Windows:按 Docker Desktop for Windows 安装向导完成设置;如果提示配置 WSL 2,按向导完成。WSL 2 是 Windows 提供的 Linux 运行环境。Docker 使用 Linux containers 模式。
- Linux:按你的发行版安装 Docker Engine,例如 Ubuntu 官方安装步骤。安装后按 官方后续配置设置当前用户访问 Docker 的权限;加入 docker 用户组会授予很高的主机权限。
在终端执行:
docker version docker infodocker version应能看到 Client 和 Server 信息:Client 是接收命令的客户端,Server 是实际执行任务的后台引擎。如果只有 Client,或者提示无法连接 Docker,先启动 Docker Desktop 或 Docker 服务。
本教程由 minikube 创建集群,无需开启 Docker Desktop 自带的 Kubernetes 功能。
第 2 步:安装 minikube 和 kubectl
只执行与你的操作系统对应的一组步骤。
macOS
如果已经安装 Homebrew,执行:
brew install minikube kubectlHomebrew 是 macOS 常用的软件包管理器,可以通过命令安装软件。如果终端提示brew: command not found,可先按 Homebrew 官网安装并完成其终端环境设置;也可以直接使用 minikube 下载方式和 kubectl 的 macOS 安装方式。
Windows(PowerShell)
如果已安装 Windows 的软件包管理器 winget,执行:
winget install -e --id Kubernetes.minikube winget install -e --id Kubernetes.kubectl安装完成后关闭并重新打开 PowerShell,让新安装的命令生效。没有 winget 时,使用 minikube 安装包和 kubectl 的 Windows 安装步骤。
Linux(以下以 x86-64 / amd64 架构为例)
先用uname -m查看处理器架构。输出x86_64可以使用下面的命令;输出aarch64或arm64时,应把下载地址中的amd64改成arm64。
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectlcurl用于下载文件;sudo表示以管理员权限执行;install把下载好的程序放到终端能找到的位置。如果缺少 curl,先通过本机的软件包管理器安装。以上方式来自 minikube和 kubectl Linux 安装文档。
安装后,所有系统都检查一次:
minikube version kubectl version --client看到版本号说明工具已安装;这时还没有创建集群。
kubectl 和集群的 Kubernetes 版本不要相差太远,官方支持相差不超过一个次版本。如果以后遇到版本兼容问题,可以使用minikube kubectl -- get nodes这类写法,调用 minikube 提供的对应版本工具。kubectl 安装要求、minikube 内置 kubectl
第 3 步:启动集群
确认 Docker 正在运行,然后执行:
minikube start --driver=docker --container-runtime=containerd --cpus=2 --memory=4096参数说明:
--driver=docker:通过 Docker 运行 minikube 节点。--container-runtime=containerd:节点内部使用 containerd 运行应用容器。--cpus=2:给学习集群配置 2 个 CPU。--memory=4096:给学习集群配置约 4 GB 内存。
电脑资源不够时,可以先使用minikube start --driver=docker --container-runtime=containerd,让工具使用默认资源配置。macOS 和 Windows 还要保证 Docker 后端分配到的资源足够。Docker 驱动说明
首次启动需要下载 Kubernetes 组件和镜像,可能需要几分钟。这里 Docker 负责提供节点环境,containerd 负责节点内部的容器运行,两者分工不同。
第 4 步:确认集群可用
minikube status kubectl config current-context kubectl get nodes你通常会看到当前 context 为minikube,节点状态为Ready。
Context(上下文)是一组连接设置,告诉 kubectl 要操作哪个集群、使用什么身份以及默认命名空间。它通常保存在kubeconfig配置文件里。
如果当前 context 不是minikube,先切换:
kubectl config use-context minikube节点输出示意如下,实际版本号和运行时间会不同:
NAME STATUS ROLES AGE VERSION minikube Ready control-plane 2m v1.x.y单节点学习集群中的这台节点,同时承担控制平面和运行应用的职责。官方入门示例
四、实战:部署一个 Nginx 网站
Nginx是一种常见的 Web 服务器,可以接收浏览器请求并返回网页。我们直接使用它的官方镜像,不需要自己编写网站代码。
本节会创建两个网站 Pod,通过一个 Service 找到它们,再把网站临时转发到本机浏览器。
第 1 步:创建练习用 Namespace
kubectl create namespace k8s-demok8s-demo是本教程使用的名字。如果提示AlreadyExists,表示已经创建过,可以继续。
第 2 步:准备 YAML 文件
在电脑上创建一个练习文件夹,用文本编辑器新建文件,命名为nginx-demo.yaml,填入下面内容。
apiVersion: apps/v1 kind: Deployment metadata: name: web namespace: k8s-demo spec: replicas: 2 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginx:stable-alpine ports: - containerPort: 80 resources: requests: cpu: 100m memory: 64Mi limits: cpu: 500m memory: 128Mi readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: web namespace: k8s-demo spec: type: ClusterIP selector: app: web ports: - port: 80 targetPort: 80不需要一次记住全部字段,先看这些关键位置:
| 字段 | 这份配置里是什么意思 |
|---|---|
apiVersion | 这个资源使用哪一组 API 规则;API 是程序之间交互的接口 |
kind | 资源类型,这里分别是 Deployment 和 Service |
metadata | 资源的名字、命名空间、标签等身份信息 |
spec | 你期望这个资源具备的配置 |
replicas: 2 | 期望运行 2 个 Pod 副本 |
template | 创建每个 Pod 时使用的模板 |
image | 用哪个容器镜像;冒号后面是镜像标签,用来标记版本或变体 |
containerPort: 80 | 声明应用使用的容器端口;它不会自动把端口开放到电脑外部 |
requests | 调度时声明所需的 CPU 和内存资源 |
limits | 容器的资源使用上限 |
readinessProbe | 就绪检查,确认应用能够接收访问 |
Service 的selector | 找到带有app: web标签的 Pod |
port: 80 | Service 对集群内调用方提供的端口 |
targetPort: 80 | Service 把流量转到后端 Pod 的哪个端口 |
--- | 在一个 YAML 文件里分隔两个资源对象 |
“端口”可以想成同一地址里的不同窗口:同一台机器能通过不同端口提供不同服务。
CPU 的100m表示 0.1 个 CPU,500m表示 0.5 个 CPU;Mi是内存容量单位,64 MiB 为 64 × 1024 × 1024 字节。CPU 超过限制一般会被限速,内存超限则可能导致进程被终止。资源配置说明
本例的就绪检查会在容器启动约 3 秒后开始,每隔 5 秒请求一次/路径;达到失败条件后,Pod 会被标记为未就绪,通常不再接收 Service 的新流量。就绪探针说明
第 3 步:提交配置并观察结果
在终端中进入保存 YAML 的文件夹。进入文件夹的命令是cd,例如cd "/你的练习文件夹路径",请把路径替换成实际位置。
执行:
kubectl apply -f nginx-demo.yaml kubectl get deployments -n k8s-demo kubectl get pods -n k8s-demo kubectl get services -n k8s-demoapply:把配置提交给集群,创建或更新对象。-f:后面跟配置文件路径。get:查看资源列表。-n k8s-demo:只操作k8s-demo命名空间。
也可以等待部署完成:
kubectl rollout status deployment/web -n k8s-demo --timeout=180srollout status用来查看发布进度。下载顺利且资源足够时,最终应看到两个 Pod 都是Running,各自READY为1/1。
Running表示 Pod 处于运行阶段;READY 1/1表示这个 Pod 的一个容器已经就绪。仅看到 Running,不一定代表应用已经可以接收访问。
第 4 步:在浏览器访问网站
执行:
kubectl port-forward service/web 8080:80 -n k8s-demo然后打开浏览器,访问:http://localhost:8080。
看到 Nginx 欢迎页,就说明网站已经运行起来。
port-forward的意思是“端口转发”。8080:80表示把你电脑的 8080 端口连接到所选后端的 80 端口。这个命令通过 Service 选择一个 Pod 建立临时通道,不会让浏览器请求在两个 Pod 之间自动轮流分配。
保持这个终端窗口运行。要继续输入其他命令,请另开一个终端。结束访问时按Ctrl+C;如果对应 Pod 被替换,通道也可能断开,重新运行命令即可。
这是本地调试访问方式,不是网站的正式公网入口。kubectl 命令参考
第 5 步:手动扩容和缩容
扩容为 3 个 Pod:
kubectl scale deployment/web --replicas=3 -n k8s-demo kubectl get pods -n k8s-demo缩容回 2 个 Pod:
kubectl scale deployment/web --replicas=2 -n k8s-demo这是手动扩缩容,因为副本数量由你指定。
注意:scale修改的是集群中的配置,不会自动修改电脑里的 YAML。如果文件仍写着replicas: 2,之后再次apply该文件,副本数会被设回 2。正式管理时,应让配置文件与期望状态保持一致。
第 6 步:观察 Pod 被删除后如何补建
先查看 Pod 名字:
kubectl get pods -n k8s-demo复制其中一个 Pod 的完整名字,把下面的POD_NAME替换掉再执行:
kubectl delete pod POD_NAME -n k8s-demo kubectl get pods -n k8s-demo -wPOD_NAME是占位符,不能原样执行;-w表示持续观察变化,按Ctrl+C结束观察。
你会看到一个新的 Pod 被创建。这是因为 ReplicaSet 发现副本数不足,要补回 Deployment 要求的数量。
这里发生的是创建新的 Pod,并不是让原来的 Pod“原地复活”。新 Pod 的名字和 IP 可能不同。若整个节点出故障,其他节点上的重建还需要等待故障处理,并满足资源、调度和存储条件。
第 7 步:体验滚动更新和回滚
为了观察更新过程,把镜像从nginx:stable-alpine切换为nginx:stable:
kubectl set image deployment/web nginx=nginx:stable -n k8s-demo kubectl rollout status deployment/web -n k8s-demo --timeout=180s这里nginx=左侧是 YAML 中的容器名称,右侧是新镜像。
这个练习切换的是镜像变体,用来演示发布流程;真实项目通常会把业务镜像从一个明确版本切换到另一个版本。stable这类标签指向的镜像可能随时间变化,需要可复现的发布时应固定镜像版本或 digest(镜像内容的唯一摘要)。
查看发布历史:
kubectl rollout history deployment/web -n k8s-demo回滚到前一个记录的版本:
kubectl rollout undo deployment/web -n k8s-demo kubectl rollout status deployment/web -n k8s-demo --timeout=180s回滚就是恢复到之前保留的 Pod 模板配置。它不会自动撤销数据库数据变化,也不会把电脑里的 YAML 文件改回去。Deployment 遇到发布问题时,也不会默认自动执行这条回滚命令。Deployment 更新与回滚
第 8 步:查看日志和进入容器
日志是程序运行时输出的信息,排查问题时通常先看它。
kubectl logs deployment/web -n k8s-demo有多个 Pod 时,这条命令会选取其中一个 Pod 的日志。查看全部匹配 Pod 的最近日志,可以使用:
kubectl logs -l app=web --all-containers=true --prefix=true --tail=50 -n k8s-demo进入一个应用容器:
kubectl exec -it deployment/web -n k8s-demo -- shexec表示在容器内执行命令;-it用于交互式终端;--后面的sh是容器里要执行的命令。sh 是一种接收和执行命令的程序,通常称为 Shell。
输入exit可以退出。不是所有镜像都带 Shell,但本教程使用的 Nginx 镜像可以进行这项练习。
五、常用命令速查
基本结构是:
kubectl 动作 资源类型 资源名称 参数例如,kubectl describe pod POD_NAME -n k8s-demo的意思是“查看 k8s-demo 中某个 Pod 的详细情况”。下表中的POD_NAME都需要替换成实际名字。
| 目的 | 命令 |
|---|---|
| 查看当前连接设置 | kubectl config current-context |
| 列出可用 context | kubectl config get-contexts |
| 切换到本地学习集群 | kubectl config use-context minikube |
| 查看集群连接信息 | kubectl cluster-info |
| 查看节点 | kubectl get nodes |
| 查看命名空间 | kubectl get namespaces |
| 查看练习环境的 Pod | kubectl get pods -n k8s-demo |
| 查看所有命名空间的 Pod | kubectl get pods -A |
| 同时显示 Pod IP 和所在节点 | kubectl get pods -o wide -n k8s-demo |
| 查看 Deployment、ReplicaSet 和 Service | kubectl get deploy,rs,svc -n k8s-demo |
| 查看 Pod 详情和相关事件 | kubectl describe pod POD_NAME -n k8s-demo |
| 查看最近的事件 | kubectl get events -n k8s-demo --sort-by=.metadata.creationTimestamp |
| 查看指定 Pod 的日志 | kubectl logs POD_NAME -n k8s-demo |
| 持续查看日志 | kubectl logs -f POD_NAME -n k8s-demo |
| 查看容器上一次运行的日志 | kubectl logs POD_NAME --previous -n k8s-demo |
| 查看集群里对象的 YAML | kubectl get deployment web -o yaml -n k8s-demo |
| 提交配置 | kubectl apply -f nginx-demo.yaml |
| 查看字段含义 | kubectl explain deployment.spec.replicas |
| 查看命令帮助 | kubectl logs --help |
这里有两个容易混淆的-f:apply -f表示读取文件,logs -f表示持续跟踪日志。参数含义要结合命令看。
常见缩写有:po= Pod、deploy= Deployment、rs= ReplicaSet、svc= Service、ns= Namespace。-A表示所有命名空间,-o用来指定输出格式。
kubectl get all只会列出一部分常见资源,不等于集群中的所有资源。需要查看 PVC、Secret 等时,要明确写出资源类型。官方命令速查表
六、K8s 内部是怎么分工的?
先分清两类职责:
- Control Plane(控制平面):集群的管理中枢,保存配置、协调调度和控制过程。旧资料里常写 Master。
- Worker Node(工作节点):运行应用 Pod 的机器。学习环境中,同一台节点也可以承担控制平面的职责。
| 组件 | 位于哪里 | 通俗解释 |
|---|---|---|
| kube-apiserver | 控制平面 | 集群管理 API 的入口,接收 kubectl 等客户端的请求 |
| etcd | 控制平面相关基础设施 | 保存集群配置和状态的键值数据库,可以理解为“管理账本” |
| kube-scheduler | 控制平面 | 为尚未分配节点的 Pod 选择合适的机器 |
| kube-controller-manager | 控制平面 | 运行多个控制器,持续协调实际状态与期望状态 |
| kubelet | 每个节点 | 与控制平面沟通,调用运行时并检查本节点容器的运行情况 |
| 容器运行时 | 每个节点 | 实际启动和停止容器,例如 containerd、CRI-O |
| kube-proxy | 常见的节点网络组件 | 配置 Service 相关转发规则;某些网络方案会替代它 |
| CNI 网络插件 | 集群网络基础设施 | CNI 是容器网络接口,相关插件负责实现 Pod 网络连接等能力 |
| CoreDNS | 常见的集群插件 | 把 Service 名称解析成可访问的地址,相当于集群里的“通讯录” |
注意:用户访问你的网站时,流量并不是通常都先经过 kube-apiserver。它主要是管理集群的入口。etcd 也不是让你存订单、用户等业务数据的数据库。Kubernetes 组件
七、其他常见对象和术语
这一节是查询用的词典,第一遍不用全部背下来。
1. 不同类型的应用,交给不同控制器
| 对象 | 用来做什么 | 例子或注意点 |
|---|---|---|
| Deployment | 管理通常可相互替换的应用副本 | 网站、业务接口等无状态应用 |
| ReplicaSet | 维持指定数量的 Pod | 通常由 Deployment 创建和管理 |
| StatefulSet | 为 Pod 提供稳定身份,并支持稳定的存储关联 | 需要固定身份和持久存储的应用;如db-0、db-1 |
| DaemonSet | 在每个符合条件的节点上运行一个 Pod | 日志采集、节点监控代理 |
| Job | 管理执行到完成的任务 | 一次数据导入、一次计算任务;失败时可能重试 |
| CronJob | 按时间安排创建 Job | 每晚生成报表;任务可能重试或重复触发,应避免重复处理造成问题 |
无状态不是“没有数据”,而是单个实例通常不保留必须依赖它才能访问的业务状态。例如,网站 Pod 把订单保存到外部数据库,自己就可以比较容易地被替换。
有状态意味着实例身份、持久数据等会影响工作。StatefulSet 默认按顺序管理 Pod,但这个行为可以配置;独立持久卷也需要配置存储模板。它不会自动完成 MySQL 主从复制、Redis 数据同步或数据库备份。工作负载管理、StatefulSet
2. 应用如何被访问?
| 对象或类型 | 通俗解释 |
|---|---|
| ClusterIP | Service 的默认类型,提供主要用于集群内部访问的虚拟 IP;本教程使用它 |
| NodePort | 通过节点地址上的一个端口访问 Service;能否从外部访问还取决于网络和防火墙 |
| LoadBalancer | 请求受支持的负载均衡实现提供入口,常见于云平台,也可以由自建方案实现 |
| Headless Service | 设置clusterIP: None,不分配普通 ClusterIP;常用于通过 DNS 发现后端 Pod 地址 |
| Ingress | 描述 HTTP/HTTPS 入口路由规则,例如把不同域名或路径交给不同 Service |
| Ingress Controller | 实际读取并执行 Ingress 规则的软件;仅创建 Ingress 对象不会自动产生入口 |
| Gateway API | 更丰富的一组网关和路由 API,也需要安装相应的实现来工作 |
HTTP 是浏览器与网站常用的通信协议,HTTPS 是使用加密保护的 HTTP 通信。
Headless Service 是 Service 的特殊配置,并不是与 ClusterIP、NodePort 并列的type值。它常配合 StatefulSet,让应用发现具有稳定身份的同伴。Service 类型与无头服务
Ingress API 已冻结,意思是保留使用但不再增加新功能。官方建议新需求考虑 Gateway API;学习现有系统时,仍然需要认识 Ingress。Ingress 官方说明
3. 配置和敏感信息
| 对象 | 保存什么 | 例子 |
|---|---|---|
| ConfigMap | 不敏感的配置 | 日志级别、应用配置文件 |
| Secret | 敏感信息 | 密码、Token、证书 |
环境变量是程序启动后可以读取的一组键值,例如LOG_LEVEL=info。ConfigMap 和 Secret 可以通过环境变量或挂载文件等方式提供给容器,程序需要按对应方式读取。
Token(令牌)可以理解为证明身份或授权访问的一串凭据。
Secret 中常见的 Base64 只是编码方式,不是加密;有读取权限的人通常可以还原内容。集群是否对 Secret 做存储加密,需要看实际配置,不能因为名字叫 Secret 就认为它天然安全。Secret 官方说明
4. 存储:Pod 换了,数据怎么办?
持久化是指数据能在程序重启、实例替换后继续保留。重要数据不能只依赖容器自身的临时文件层。
| 名称 | 通俗解释 | 需要记住的区别 |
|---|---|---|
| Volume | 给容器挂载的存储,可以是目录、磁盘或其他数据来源 | 是总称,并不保证一定持久化 |
| emptyDir | 为一个 Pod 提供的临时目录 | 同一 Pod 内容器重启时通常还在;Pod 被移除后删除 |
| hostPath | 挂载节点上的文件或目录 | 数据在那台节点上;换节点不会自动带走原数据,也可能涉及主机访问权限 |
| NFS | Network File System,网络文件系统 | 通过网络访问共享文件;是否可同时读写还取决于服务端和挂载配置 |
| PV | PersistentVolume,持久卷 | K8s 对一份存储资源的描述,可以由管理员或动态供应组件创建 |
| PVC | PersistentVolumeClaim,持久卷声明 | 应用提交的存储需求,例如“我要 10 GiB 存储” |
| StorageClass | 存储类 | 描述存储类型及供应方式,配合存储驱动按需创建存储 |
| CSI 驱动 | Container Storage Interface,容器存储接口的实现 | 帮 K8s 对接云盘、存储设备等后端 |
例如,你提交一份 PVC,声明需要 10 GiB 存储。集群可以把它绑定到合适的 PV;配置好 StorageClass 和供应组件时,也可以按需创建新的存储资源。存储卷、持久卷、动态供应
“持久化”不等于“备份”。删除 PVC 后,实际数据是否保留取决于回收策略;底层磁盘损坏也需要其他保护措施。Pod 能否换节点继续访问原数据,还取决于存储后端和挂载限制。
5. 健康检查:程序活着,和能接请求是两件事
Probe(探针)就是 K8s 对容器进行的健康检查。
| 探针 | 检查什么 | 达到失败条件后会怎样 |
|---|---|---|
| livenessProbe | 程序是否还健康地运行,例如有没有卡死 | 触发容器重启处理,具体行为受重启策略影响 |
| readinessProbe | 程序现在能否接收请求 | 标记为未就绪,通常不再接收 Service 的新流量;不会仅因此重启容器 |
| startupProbe | 程序是否已经完成启动 | 启动期间暂缓其他两种探针;持续失败达到阈值后触发重启处理 |
阈值就是触发处理的条件,例如连续失败 3 次;不是每次检查失败都会马上重启。
可以把它们记成:存活看“有没有出问题”,就绪看“能不能接客”,启动看“开门准备做好没有”。探针说明
Init Container(初始化容器)用于主应用启动前的准备工作,例如生成配置。普通 Init 容器按顺序运行,前一个成功完成后再运行下一个,全部完成后才启动主应用容器。初始化容器说明
6. 调度:Pod 应该放在哪台机器?
| 名称 | 通俗解释 |
|---|---|
| nodeSelector | 按节点标签筛选,例如只放到标记为有 SSD 的节点 |
| nodeName | 直接指定节点名称,绕过正常调度器选择;初学时通常不需要使用 |
| Affinity,亲和性 | 描述希望或必须满足的靠近关系,比如倾向同一区域的节点或 Pod |
| Anti-Affinity,反亲和性 | 描述希望或必须避免的靠近关系,比如同一应用的副本尽量分散到不同节点 |
| Taint,污点 | 节点对 Pod 设置的排斥条件,效果可以是尽量不调度、禁止新调度或驱逐 |
| Toleration,容忍 | Pod 表示自己可以容忍某种污点 |
容忍只是允许通过某项筛选,不保证一定调度到那个节点。调度器还会考虑资源、标签和其他规则。nodeSelector 也是筛选符合标签的节点,不等于直接指定唯一一台机器。节点选择、污点与容忍
7. 安全身份和工具
| 名称 | 通俗解释 |
|---|---|
| RBAC | Role-Based Access Control,基于角色的权限控制;规定谁能对哪些资源做哪些操作 |
| Role / ClusterRole | 定义权限规则;Role 属于某个命名空间,ClusterRole 可定义集群级规则 |
| RoleBinding / ClusterRoleBinding | 把权限规则授予具体用户、用户组或 ServiceAccount |
| ServiceAccount | K8s 管理的服务账号,常用于应用访问集群 API 时的身份 |
| 普通用户身份 | 人通过 kubectl 等工具访问集群时使用的身份,通常由证书或外部身份系统提供 |
| Helm | K8s 的软件包管理器,用来安装、更新和管理成套资源 |
| Chart | Helm 的软件包,包含模板、默认配置等内容 |
| Release | 一个 Chart 安装后产生的一次具体实例 |
“UserAccount”常被用作解释人的身份,但 K8s 并没有与 ServiceAccount 对应的内置 UserAccount 资源。身份回答“你是谁”,权限回答“你能做什么”。身份认证、RBAC
例如,把同一个网站 Chart 分别安装成website-test和website-prod,就可以得到两个分别管理的 Release。Helm 基本概念
八、选做:开启自动扩缩容
前面使用kubectl scale是手动修改数量。如果希望根据 CPU 使用情况自动调整,可以配置HPA(Horizontal Pod Autoscaler,Pod 水平自动扩缩容器)。
“水平”指增加或减少实例数量;给单个实例更多 CPU、内存,则是“垂直”调整。
本例需要Metrics Server(资源指标服务),它提供 CPU、内存等使用数据。先执行:
minikube addons enable metrics-server kubectl top pods -n k8s-demoaddons指扩展插件。指标需要一些时间才能采集到,暂时没有数据时稍后重试。
本教程的 Deployment 已经设置requests.cpu: 100m。这是按 CPU 利用率自动扩缩容时的重要前提。HPA 工作方式
创建web-hpa.yaml,内容如下;
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web namespace: k8s-demo spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web minReplicas: 2 maxReplicas: 5 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50提交并查看:
kubectl apply -f web-hpa.yaml kubectl get hpa -n k8s-demo它会尝试把平均 CPU 使用率维持在声明请求量的 50% 左右,并把副本数限制在 2~5 个之间。本例每个容器请求 100m CPU,50% 对应约 50m,不是整台机器 CPU 的 50%。
没有足够访问负载时,不会因为配置了 HPA 就立即扩容;调整还受到采样周期和稳定窗口等规则影响。HPA 增加的是 Pod,不会自动给电脑加内存,也不会自动增加集群节点。HPA 配置示例
HPA 开启后,副本数由它调整。练习期间不要反复使用scale或重新应用带固定replicas的 Deployment 与它争抢控制。实际配置管理中通常让 HPA 接管副本数字段。
结束这个选做练习时,可以删除 HPA 并恢复 2 个副本:
kubectl delete hpa web -n k8s-demo kubectl scale deployment/web --replicas=2 -n k8s-demo九、初学者常见问题
| 现象 | 常见原因 | 先做什么 |
|---|---|---|
command not found或“不识别该命令” | 工具没装好,或终端还没找到安装位置 | 确认安装完成,重新打开终端,检查安装步骤要求的 PATH 设置 |
| 无法连接 Docker | Docker 后台引擎没启动,或当前用户无权限 | 先运行docker info,再检查 Docker 启动状态和权限 |
| kubectl 无法连接集群 | 集群没启动,或 context 指向其他集群 | 查看minikube status和当前 context |
| minikube 下载超时 | 网络、代理、DNS 或镜像来源不可达 | 查看错误中的下载地址,检查对应网络;DNS 是把域名转换为 IP 的服务 |
Pod 一直Pending | 资源不足、节点条件不满足,或存储尚未准备好 | 用kubectl describe pod查看底部 Events |
ImagePullBackOff | 镜像下载失败,可能是网络、镜像标签或仓库权限问题 | 查看 Events 里的具体下载错误 |
CrashLoopBackOff | 容器反复退出,K8s 在延迟重试 | 查看kubectl logs,必要时加--previous |
Pod 为 Running,但 READY 是0/1 | 容器在运行,但尚未就绪,可能是探针不通过 | 查看日志和 Pod 详情中的探针事件 |
OOMKilled | 进程因内存不足被终止,常见于超过内存限制 | 检查程序内存使用与资源配置 |
| 网站打不开 | port-forward 已结束,或应用未就绪 | 确认转发终端仍在运行,以及 Pod 为就绪状态 |
| 8080 端口被占用 | 电脑上的其他程序使用了这个端口 | 改用kubectl port-forward service/web 8081:80 -n k8s-demo,浏览器访问 8081 |
| 找不到 YAML 文件 | 当前终端不在文件所在目录 | 进入正确目录,或给-f传入文件的完整路径 |
| 找不到应用资源 | 命名空间或 context 不对 | 确认使用 minikube,并加上-n k8s-demo |
LoadBalancer 的地址一直是<pending> | 没有可用的外部负载均衡实现 | 本地练习先用 port-forward;minikube 的 LoadBalancer 访问还可以按文档使用 tunnel |
PATH 是终端寻找可执行程序的目录列表;Events 是 K8s 记录的近期事件,例如调度失败、镜像拉取失败等。
排查 Pod 问题时,先看这三处最有帮助:资源状态、describe 里的 Events、容器日志。官方调试入口
如果国内网络下载失败,minikube 官方提供了--image-mirror-country=cn选项,例如首次创建时加入:
minikube start --driver=docker --container-runtime=containerd --image-mirror-country=cn该选项只是调整部分集群镜像的获取方式,不保证所有下载都成功,也不会自动替换nginx等应用镜像的来源。minikube 网络下载说明
十、结束练习:停止和清理
只想暂时不用,保留练习环境:
minikube stop下次通过minikube start启动,通常可继续使用已有环境。
想删除本教程创建的网站资源,但保留集群:
kubectl delete -f nginx-demo.yaml如果选做的 HPA 尚未删除,也删除它:
kubectl delete -f web-hpa.yaml --ignore-not-found删除 Deployment 会连同它管理的 ReplicaSet 和 Pod 一起清理;删除 Service 则移除对应的服务入口。
想删除整个练习命名空间及其中资源:
kubectl delete namespace k8s-demo想彻底删除本地 minikube 集群及其本地集群数据:
minikube delete这些是不同范围的清理方式,按需要选择即可,不必全部执行。stop是停止,delete是删除,后者不能当作“暂停”使用。minikube 入门与清理
第一次学习,先掌握Pod、Deployment、Service、Namespace、kubectl,再独立完成一次“部署 → 访问 → 扩容 → 查看日志 → 更新 → 清理”。其余术语可以在实际遇到时回来查。