在没有 Deployment 或 Service 的情况下创建 Pods:裸金属 Kubernetes 体验
Source: Dev.to
介绍
在 Kubernetes 中,虽然 Deployment 和 Service 是管理应用的推荐方式,但在某些合理的场景下,你可能希望直接创建一个 Pod,而不使用这些抽象层。这种 “裸金属” 方法可以让你获得最大的控制权,但也伴随重要的权衡。下面我们将探讨何时、为何以及如何使用独立的 Pod。
创建独立 Pod:基础示例
示例 1:最简 Pod 定义
# simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: standalone-nginx
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
创建并验证 Pod:
kubectl apply -f simple-pod.yaml
kubectl get pods
kubectl describe pod standalone-nginx
示例 2:批处理作业 Pod(不使用 Job 控制器)
# batch-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: data-processor
spec:
restartPolicy: OnFailure # 注意:不是 "Always"
containers:
- name: processor
image: busybox
command: ["/bin/sh"]
args: ["-c", "echo 'Processing data...'; sleep 30; echo 'Done!'"]
创建并验证 Pod:
kubectl apply -f batch-pod.yaml
kubectl get pods
kubectl describe pod data-processor
为什么要在没有 Deployment 或 Service 的情况下创建 Pod?
1. 一次性任务和短暂工作负载
# cleanup-job.yaml
apiVersion: v1
kind: Pod
metadata:
name: temp-cleanup
spec:
restartPolicy: Never # 我们不希望它重启
containers:
- name: cleaner
image: busybox
command: ["/bin/sh"]
args: ["-c", "rm -rf /tmp/old-files/*"]
使用场景:清理临时文件、运行数据库迁移,或执行单次批处理操作——此时自动重启会带来负面影响。
2. 调试和故障排查
# network-debug-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: network-tester
spec:
containers:
- name: tester
image: nicolaka/netshoot # 常用的网络故障排查镜像
command: ["sleep", "infinity"]
创建并调试:
kubectl apply -f network-debug-pod.yaml
kubectl exec -it network-tester -- bash
现在你可以运行 curl、dig、ping、tcpdump 等命令。
优势:快速启动,无需 Deployment 的额外开销;非常适合作为临时诊断工具。
3. Init 容器(在 Pod 内)
# init-container-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
containers:
- name: main-app
image: myapp:latest
ports:
- containerPort: 8080
initContainers:
- name: init-db
image: busybox
command: ['sh', '-c', 'until nslookup database-service; do echo waiting for database; sleep 2; done;']
注意:Init 容器是 Pod 规范的一部分,而不是独立的资源。
4. 学习和实验
# learning-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: learning-experiment
spec:
containers:
- name: experiment
image: nginx
env:
- name: LEARNING_MODE
value: "true"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
收益:直接接触 Pod 生命周期,无需控制器抽象。
5. 专用节点操作
# node-specific-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: node-maintenance
spec:
nodeName: node-01 # 直接指定节点
containers:
- name: maintenance
image: ubuntu
command: ["/bin/bash"]
args: ["-c", "apt-get update && apt-get upgrade -y"]
使用场景:需要针对特定节点执行的维护任务。
独立 Pod 的优势
- 简洁明了 – YAML 极少,无额外控制器。
- 直接控制 – 完全掌握 Pod 规范和生命周期。
- 快速迭代 – 创建、修改、删除更迅速。
- 显式的失败处理 – 由你自行决定失败时的处理方式。
资源效率
- 没有 Deployment 控制器的开销。
- 没有调和循环或状态追踪。
- 减少 etcd 流量。
劣势与生产环境的顾虑
- 没有自愈能力。
- 没有滚动更新。
- 没有扩缩容功能。
- 与 Service 的集成受限。
- 需要手动管理生命周期。
何时使用(以及何时不该使用)
适合使用独立 Pod 的场景
- 临时调试或故障排查。
- 一次性批处理作业(虽然
Job资源可能更合适)。 - 学习和实验。
- 作为其他 Pod 的 Init 容器。
- 简单、无状态的工具且不需要高可用。
- 需要直接指定节点的操作。
应避免使用独立 Pod 的场景
- 需要高可用的生产应用。
- 需要负载均衡的 Service。
- 需要零停机时间更新的应用。
- 需要自动扩缩容的工作负载。
- 有状态应用(请使用
StatefulSet)。 - 长期运行且被其他 Pod 访问的服务。
结论
独立 Pod 在 Kubernetes 中填补了一个重要的细分领域,提供了对容器执行的原始、未抽象的访问,这对调试、一次性任务和学习尤为关键。然而,它们缺乏使 Kubernetes 在生产环境中强大的鲁棒性和自动化特性。
关键要点
- 有针对性地使用独立 Pod,以满足其特定用途。
- 理解控制权与自动化之间的权衡。
- 当需要高可用、扩缩容或滚动更新时,迁移到 Deployment 与 Service。
- 始终清理临时的独立 Pod。
- 为每个独立 Pod 记录用途,以便团队成员了解其目的。
记住:Kubernetes 的核心是抽象和自动化。虽然独立 Pod 为你提供了逃离这些抽象的后门,但在一个良好构建的 Kubernetes 环境中,它们应当是例外而非常规做法。