在没有 Deployment 或 Service 的情况下创建 Pods:裸金属 Kubernetes 体验

发布: (2025年12月7日 GMT+8 01:26)
6 min read
原文: Dev.to

Source: Dev.to

介绍

在 Kubernetes 中,虽然 DeploymentService 是管理应用的推荐方式,但在某些合理的场景下,你可能希望直接创建一个 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

现在你可以运行 curldigpingtcpdump 等命令。
优势:快速启动,无需 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 环境中,它们应当是例外而非常规做法。

Back to Blog

相关文章

阅读更多 »

第4天:kube scheduler

概述 Kubernetes 调度器决定每个 pod 应该运行在哪个节点上。它本身并不直接放置 pod;相反,它为每个 pod 记录目标节点。

Dockerfile:CMD 与 ENTRYPOINT

Ubuntu 镜像中的默认 CMD 官方 Ubuntu 镜像定义了一个默认命令:Dockerfile 中的 CMD '/bin/bash' 当你运行容器并提供参数时,...