Creating Pods Without Deployment or Service: The Bare-Metal Kubernetes Experience

Published: (December 6, 2025 at 12:26 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

Introduction

In Kubernetes, while Deployments and Services are the recommended approach for managing applications, there are legitimate scenarios where you might want to create a Pod directly without these abstractions. This “bare‑metal” approach gives you maximum control but comes with important trade‑offs. Below we explore when, why, and how to use standalone Pods.

Creating a Standalone Pod: Basic Examples

Example 1: The Simplest Pod Definition

# 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

Create and verify the pod:

kubectl apply -f simple-pod.yaml
kubectl get pods
kubectl describe pod standalone-nginx

Example 2: A Batch Job Pod (Without Job Controller)

# batch-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: data-processor
spec:
  restartPolicy: OnFailure  # Note: Not "Always"
  containers:
  - name: processor
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "echo 'Processing data...'; sleep 30; echo 'Done!'"]

Create and verify the pod:

kubectl apply -f batch-pod.yaml
kubectl get pods
kubectl describe pod data-processor

Why Create Pods Without Deployments or Services?

1. One‑Off Tasks and Ephemeral Workloads

# cleanup-job.yaml
apiVersion: v1
kind: Pod
metadata:
  name: temp-cleanup
spec:
  restartPolicy: Never  # We don't want this to restart
  containers:
  - name: cleaner
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "rm -rf /tmp/old-files/*"]

Use case: Cleaning up temporary files, running database migrations, or executing a single batch operation where automatic restart would be harmful.

2. Debugging and Troubleshooting

# network-debug-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: network-tester
spec:
  containers:
  - name: tester
    image: nicolaka/netshoot  # Popular network troubleshooting image
    command: ["sleep", "infinity"]

Create and debug:

kubectl apply -f network-debug-pod.yaml
kubectl exec -it network-tester -- bash

Now you can run curl, dig, ping, tcpdump, etc.
Advantage: Quick spin‑up without deployment overhead; perfect for temporary diagnostic tools.

3. Init Containers (Within Pods)

# 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;']

Note: Init containers are part of the Pod spec, not separate resources.

4. Learning and Experimentation

# 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"

Benefit: Direct exposure to the Pod lifecycle without controller abstractions.

5. Specialized Node Operations

# node-specific-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: node-maintenance
spec:
  nodeName: node-01  # Direct node assignment
  containers:
  - name: maintenance
    image: ubuntu
    command: ["/bin/bash"]
    args: ["-c", "apt-get update && apt-get upgrade -y"]

Use case: Node‑specific maintenance tasks where you need to target a particular node.

Advantages of Standalone Pods

  • Simplicity and Clarity – Minimal YAML, no extra controllers.
  • Direct Control – Full authority over Pod spec and lifecycle.
  • Quick Iteration – Faster to create, modify, and delete.
  • Explicit Failure Handling – You decide what to do on failure.

Resource Efficiency

  • No deployment controller overhead.
  • No reconciliation loops or status tracking.
  • Reduced etcd traffic.

Disadvantages and Production Concerns

  • No self‑healing.
  • No rolling updates.
  • No scaling capabilities.
  • Limited service integration.
  • Manual lifecycle management.

When to Use (and When Not to Use)

Use Standalone Pods When

  • Temporary debugging or troubleshooting.
  • One‑off batch jobs (though a Job resource may be preferable).
  • Learning and experimentation.
  • Init containers within other Pods.
  • Simple, stateless utilities with no HA requirements.
  • Node‑specific operations requiring direct assignment.

Avoid Standalone Pods When

  • Production applications requiring high availability.
  • Services needing load balancing.
  • Applications requiring zero‑downtime updates.
  • Workloads that need automatic scaling.
  • Stateful applications (use a StatefulSet).
  • Long‑running services accessed by other Pods.

Conclusion

Standalone Pods in Kubernetes fill an important niche, providing raw, unabstracted access to container execution that is essential for debugging, one‑off tasks, and learning. However, they lack the robustness and automation features that make Kubernetes powerful for production workloads.

Key Takeaways

  • Use standalone Pods strategically for their intended purposes.
  • Understand the trade‑offs between control and automation.
  • Graduate to Deployments and Services when you need HA, scaling, or rolling updates.
  • Always clean up temporary standalone Pods.
  • Document the purpose of each standalone Pod for team clarity.

Remember: Kubernetes is about abstraction and automation. While standalone Pods give you escape hatches from these abstractions, they should be the exception rather than the rule in a well‑architected Kubernetes environment.

Back to Blog

Related posts

Read more »

day4: kube scheduler

Overview The Kubernetes scheduler decides which node each pod should run on. It does not place the pods itself; instead, it records the target node for each po...

Dockerfile: CMD vs ENTRYPOINT

Default CMD in the Ubuntu Image The official Ubuntu image defines a default command: dockerfile CMD '/bin/bash' When you run a container and provide arguments,...