Kubernetes 怎么入门:从一个 Pod 到可验证部署
第一次看 Kubernetes 文档,很容易在 Pod、Deployment、Service、Ingress 和一堆 YAML 字段之间迷路。每个词都能查到解释,合在一起却不知道一次部署究竟发生了什么。
入门阶段不用先背完整对象表,先抓住一条主线:你提交期望状态,控制器负责让实际状态不断向它靠近。
- Pod 是运行单元,但日常部署通常从 Deployment 开始,不要手工维护孤立 Pod。
- Service 解决稳定访问,ConfigMap 和 Secret 解决配置分离,它们各自只负责一件事。
- 排障先看
get、describe、事件和日志,再考虑直接登录节点。 - 能启动不等于能上线;探针、资源、滚动发布和回滚验证要一起补齐。
你提交期望状态 → API Server 保存对象 → Controller 发现实际状态不一致 → Scheduler 选择节点 → Kubelet 启动 Pod → Service 为 Pod 提供稳定访问入口集群由什么组成
Section titled “集群由什么组成”一个集群由控制平面和工作节点组成。
| 组件 | 职责 |
|---|---|
kube-apiserver | Kubernetes API 入口,所有对象操作都经过它 |
etcd | 保存集群状态 |
kube-scheduler | 为尚未分配节点的 Pod 选择 Node |
kube-controller-manager | 运行控制器,持续把实际状态拉回期望状态 |
| 组件 | 职责 |
|---|---|
kubelet | 确保分配到本节点的 Pod 正常运行 |
| 容器运行时 | 拉取镜像并运行容器 |
kube-proxy 或等价实现 | 支撑 Service 网络转发 |
官方架构说明见 Kubernetes Components。
对象模型:spec 和 status
Section titled “对象模型:spec 和 status”Kubernetes 对象是“期望状态的记录”:
spec:你希望系统变成什么样;status:系统当前实际上是什么样;- Controller:持续比较两者并执行修正。
一个对象通常包含四个必填部分:
apiVersion: apps/v1kind: Deploymentmetadata: name: demo-apispec: # 不同 kind 在这里有不同字段不要手写 status、uid、resourceVersion、managedFields 等由系统维护的字段。对象模型详见 Objects in Kubernetes。
部署一个最小应用
Section titled “部署一个最小应用”Namespace
Section titled “Namespace”apiVersion: v1kind: Namespacemetadata: name: demoNamespace 用来隔离一组资源,不是安全边界的全部。生产环境还需要配合 RBAC、NetworkPolicy 和 ResourceQuota。
Deployment
Section titled “Deployment”apiVersion: apps/v1kind: Deploymentmetadata: name: demo-api namespace: demo labels: app: demo-apispec: replicas: 2 selector: matchLabels: app: demo-api template: metadata: labels: app: demo-api spec: containers: - name: api image: nginx:1.27-alpine ports: - name: http containerPort: 80 resources: requests: cpu: 50m memory: 64Mi limits: cpu: 500m memory: 256Mi readinessProbe: httpGet: path: / port: http initialDelaySeconds: 2 periodSeconds: 5 livenessProbe: httpGet: path: / port: http initialDelaySeconds: 10 periodSeconds: 10selector.matchLabels 必须和 Pod 模板的 labels 对得上。Deployment 管理 ReplicaSet,ReplicaSet 再维护 Pod 数量。
Service
Section titled “Service”Pod 会重建,IP 也会变化。Service 用标签选择一组 Pod,提供稳定的虚拟地址:
apiVersion: v1kind: Servicemetadata: name: demo-api namespace: demospec: selector: app: demo-api ports: - name: http port: 80 targetPort: http type: ClusterIP同一 Namespace 内可以通过 http://demo-api 访问;跨 Namespace 可以使用 demo-api.demo.svc.cluster.local。
配置和 Secret
Section titled “配置和 Secret”ConfigMap
Section titled “ConfigMap”apiVersion: v1kind: ConfigMapmetadata: name: demo-api-config namespace: demodata: LOG_LEVEL: info应用 Secret
Section titled “应用 Secret”apiVersion: v1kind: Secretmetadata: name: demo-api-secret namespace: demotype: OpaquestringData: API_TOKEN: replace-me在 Deployment 中引用:
envFrom: - configMapRef: name: demo-api-config - secretRef: name: demo-api-secretSecret 的 Base64 只是编码,不是加密。不要把生产凭证明文提交到 Git;应使用云厂商 Secret Manager、External Secrets 或密钥加密方案。
私有镜像 imagePullSecrets
Section titled “私有镜像 imagePullSecrets”创建镜像仓库凭证:
kubectl -n demo create secret docker-registry registry-credentials \ --docker-server=registry.example.com \ --docker-username="$REGISTRY_USERNAME" \ --docker-password="$REGISTRY_PASSWORD"在 Pod 模板中引用:
spec: imagePullSecrets: - name: registry-credentials containers: - name: api image: registry.example.com/team/demo-api:1.0.0凭证 Secret 和使用它的 Pod 必须位于同一个 Namespace。
为什么 requests、limits 和探针不能省
Section titled “为什么 requests、limits 和探针不能省”requests
Section titled “requests”Scheduler 使用 requests 判断节点是否容得下 Pod。没有 requests,调度和容量规划都会失真。
limits
Section titled “limits”- CPU limit 会产生节流;
- 超出 memory limit 通常会触发 OOMKill;
- limit 不是性能目标,只是资源上界。
readinessProbe
Section titled “readinessProbe”readiness 失败时,Pod 暂时从 Service 端点中移除,但容器不一定重启。
livenessProbe
Section titled “livenessProbe”liveness 失败会触发容器重启。不要把依赖服务偶发不可用直接当成 liveness 失败,否则容易形成重启风暴。
如果应用启动很慢,再增加 startupProbe,避免 liveness 过早介入。
假设三个对象保存在 k8s/:
kubectl apply -f k8s/kubectl -n demo rollout status deployment/demo-apikubectl -n demo get deployment,pod,servicekubectl -n demo port-forward service/demo-api 8080:80curl -i http://127.0.0.1:8080/一次完整验证至少包括:
- Deployment rollout 成功;
- 期望数量的 Pod Ready;
- Service 有 Endpoints;
- 真实请求返回预期结果。
kubectl apply 成功只证明 API 接受了对象,不证明应用可用。
常用排障路径
Section titled “常用排障路径”Pod 一直 Pending
Section titled “Pod 一直 Pending”kubectl -n demo describe pod <pod-name>kubectl get events -A --sort-by=.lastTimestamp重点看资源不足、节点选择器、污点和 PVC。
ImagePullBackOff
Section titled “ImagePullBackOff”kubectl -n demo describe pod <pod-name>kubectl -n demo get secret registry-credentials检查镜像名称、tag、Secret 名称、Namespace 和仓库权限。
CrashLoopBackOff
Section titled “CrashLoopBackOff”kubectl -n demo logs <pod-name> --previouskubectl -n demo describe pod <pod-name>--previous 用来读取上一个已崩溃容器的日志。
Service 访问不到
Section titled “Service 访问不到”kubectl -n demo get service demo-apikubectl -n demo get endpointslice -l kubernetes.io/service-name=demo-apikubectl -n demo get pod -l app=demo-api --show-labels优先确认 Service selector 是否选中了 Ready Pod。
- 镜像使用不可变 tag 或 digest;
- 配置与凭证分离;
- requests、limits 和探针齐全;
- 至少配置 PodDisruptionBudget 或明确可接受的中断策略;
- 使用滚动发布并验证回滚;
- 权限遵循最小化原则;
- 日志、指标和事件可以被采集;
- 数据卷、备份和恢复方案经过验证;
- 不依赖手工修改线上对象;
- manifest 能通过 CI 校验和测试。
Kubernetes 的核心不是记字段,而是理解控制循环:声明期望状态,观察实际状态,用可重复的配置让系统自动收敛。
下一步: