Kubernetes 的核心价值不是“运行容器”,而是持续把集群的实际状态调整为你声明的期望状态:你声明要两个 API 副本、一个稳定访问入口和一套健康检查,控制器负责创建、替换和更新 Pod。
K3s 是 Kubernetes 的轻量级发行版,降低了安装和运行资源成本,并为小规模、边缘和本地环境提供了更易用的默认选择。对应用开发者而言,K3s 使用的核心 Kubernetes API、kubectl 工作流和工作负载对象与其他 Kubernetes 发行版基本一致。
本文只讲部署一个无状态服务时最需要掌握的内容。存储、HPA、StatefulSet、亲和性和集群运维应作为后续专题学习。
1. 最重要的心智模型:声明期望状态
使用 Kubernetes 时,通常不需要手动创建和重启每个容器。你向 API 提交 YAML,描述期望状态;控制器持续比较期望状态与实际状态,并尝试消除差异。
例如,当一个 Deployment 期望 replicas: 2,某个 Pod 异常退出时,控制器会创建替代 Pod。发布新镜像时,Deployment 会按更新策略逐步替换旧 Pod,而不是让你逐台机器执行命令。
应用需要配合这个模型:进程应无状态、可重复启动、能输出日志、能优雅停止,并通过健康检查告诉平台何时可以接流量。
2. 无状态服务最常见的对象
| 对象 | 作用 | 何时需要 |
|---|---|---|
| Namespace | 资源隔离范围 | 区分应用、团队或环境。 |
| Pod | 最小调度单元,可包含一个或多个紧密协作的容器 | 通常由 Deployment 创建,不直接手写单个 Pod。 |
| Deployment | 声明副本数、镜像和滚动更新策略 | 大多数无状态 API、Web 服务和消费者。 |
| Service | 为一组 Pod 提供稳定 DNS 和虚拟访问地址 | 让集群内调用方不依赖 Pod IP。 |
| ConfigMap | 非敏感配置 | 注入环境变量或配置文件。 |
| Secret | 敏感配置引用 | 仅是编码,不等于加密或密钥治理。 |
| Ingress | HTTP/HTTPS 路由规则 | 需要通过域名或路径从集群外访问时。 |
Pod 是 Kubernetes 调度的单位,容器只是 Pod 中的运行进程。一个 API 通常是“一 Pod 一业务容器”;日志收集、网络代理等确实需要共享生命周期和网络命名空间时,才考虑 sidecar。
3. 部署一个无状态 API
下面的 app.yaml 创建 Namespace、ConfigMap、两副本 API 和集群内 Service。将镜像地址替换为可被你的 K3s/Kubernetes 集群拉取的实际镜像。
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: demo
data:
APP_ENV: development
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: registry.example.com/demo/api:1.0.0
ports:
- name: http
containerPort: 8080
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: api-config
key: APP_ENV
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 10
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: api
namespace: demo
spec:
selector:
app: api
ports:
- name: http
port: 80
targetPort: http
这份 YAML 的关键关系是:Deployment 根据 app: api 标签管理 Pod;Service 用同一标签选择后端 Pod,并为它们提供稳定的 api.demo.svc.cluster.local DNS 名称。Pod 重建后 IP 会变化,调用方应访问 Service,而不是记录 Pod IP。
4. 健康检查和资源请求是基础能力
readinessProbe 决定 Pod 是否加入 Service 的可用后端。应用尚未完成初始化、无法处理请求时,应让 readiness 失败,以避免新流量进入。
livenessProbe 用于发现进程失去工作能力后是否应重启。不要把依赖数据库或远程服务的深度检查直接作为 liveness 条件,否则下游短暂故障可能造成应用集体重启。应用启动很慢时,还应评估 startupProbe。
resources.requests 是调度器分配资源时的依据;limits 用于限制单个容器可使用的资源。数值必须来自压测和运行指标,不应照抄示例。缺少 requests 会让容量规划、调度和后续自动扩缩容都失去可靠基础。
5. 发布、观察与本地访问
# 提交期望状态
kubectl apply -f app.yaml
# 查看 Deployment、Pod 和 Service
kubectl -n demo get deployment,pods,service
# 等待本次发布完成
kubectl -n demo rollout status deployment/api
# 查看应用日志和某个 Pod 的详细事件
kubectl -n demo logs deployment/api --follow
kubectl -n demo describe pod <pod-name>
# 本地临时访问集群内 Service
kubectl -n demo port-forward service/api 8080:80
port-forward 适合开发和排障,不是生产暴露方式。生产 HTTP 流量通常通过已安装的 Ingress Controller 加上 Ingress 规则进入集群;Ingress 本身只是规则资源,没有 Controller 就不会生效。云环境的 LoadBalancer Service 是否可用也取决于云提供商或集群的负载均衡实现。
6. 更新和回滚
当镜像有新版本时,更新 Deployment 并观察滚动发布:
kubectl -n demo set image deployment/api \
api=registry.example.com/demo/api:1.0.1
kubectl -n demo rollout status deployment/api
kubectl -n demo rollout history deployment/api
如果新版本异常:
kubectl -n demo rollout undo deployment/api
滚动更新能否真正做到低中断,取决于 readiness、优雅终止、足够的资源余量和正确的更新策略。它不是替代应用兼容性、数据库迁移和灰度验证的魔法。
7. 配置、密钥与状态数据的边界
ConfigMap 适合非敏感配置。Secret 可以让工作负载引用敏感值,但其默认 Base64 只是编码;生产环境还应考虑静态加密、访问控制、审计以及外部密钥系统。
数据库、消息队列等有状态组件涉及存储类型、备份、恢复和故障转移。Kubernetes 使用 PV、PVC 和 StorageClass 描述持久化存储,但不要在理解 Deployment 之前就试图掌握全部存储细节。对关键数据,先确认存储和备份方案,再决定是否放入集群。
8. 哪些内容应单独学习
以下内容很重要,但不应挤进基础部署流程:
- StatefulSet、PV/PVC、StorageClass:有状态服务与数据恢复。
- HPA 与 Cluster Autoscaler:指标、容量和自动扩缩容。
- DaemonSet、节点亲和性、污点与容忍:节点级工作负载与调度约束。
- NetworkPolicy、Ingress Controller、Service Mesh:网络隔离和流量治理。
- 控制平面、etcd、高可用和升级:集群运维。
先能稳定地发布、观察和回滚一个无状态服务,再进入这些专题,学习路径会更清晰。
9. 上线检查清单
- 镜像可被目标集群拉取,且标签或 digest 可追溯。
- Deployment、Service 的标签选择器一致。
- readiness、liveness 和必要的 startup 探针反映真实服务状态。
- 已根据压测设置 CPU/内存 requests 和 limits。
- 配置与密钥不写进镜像,Secret 不被误当作加密存储。
- 已验证
rollout status、日志、事件查看和回滚流程。 - 已明确外部流量由 Ingress、LoadBalancer 或其他网关方案承接。
掌握这一条从 YAML 到发布、观察和回滚的链路,就已经拥有使用 K3s/Kubernetes 部署无状态服务的核心能力。