DEV Community

janak0ff
janak0ff

Posted on

Set Up Time Check Pod in Kubernetes

The Nautilus DevOps team needs a time check pod created in a specific Kubernetes namespace for logging purposes. Initially, it's for testing, but it may be integrated into an existing cluster later. Here's what's required:

  1. Create a pod called time-check in the devops namespace. The pod should contain a container named time-check, utilizing the busybox image with the latest tag (specify as busybox:latest).

  2. Create a config map named time-config with the data TIME_FREQ=12 in the same namespace.

  3. Configure the time-check container to execute the command: while true; do date; sleep $TIME_FREQ;done. Ensure the result is written /opt/data/time/time-check.log. Also, add an environmental variable TIME_FREQ in the container, fetching its value from the config map TIME_FREQ key.

  4. Create a volume log-volume and mount it at /opt/data/time within the container.


Introduction

In the world of Kubernetes, managing configuration data and persistent storage are two of the most common challenges developers face. How do you keep your application configuration separate from your code? How do you ensure your data persists even if your pod restarts?

In this comprehensive guide, we'll walk through a real-world scenario where we combine ConfigMaps, environment variables, and volumes to create a time-check logging pod. By the end, you'll understand how to manage configuration and storage in Kubernetes like a pro.


What You'll Learn

  • What ConfigMaps are and how to use them
  • How to inject configuration as environment variables
  • How to create and use volumes in Kubernetes
  • How to combine multiple Kubernetes concepts in one solution
  • Best practices for configuration management

Table of Contents

  1. The Challenge: Time-Check Logging Pod
  2. Understanding ConfigMaps
  3. Understanding Volumes
  4. Understanding Environment Variables
  5. Step-by-Step Implementation
  6. How It All Works Together
  7. Monitoring and Verification
  8. Troubleshooting Common Issues
  9. Advanced Configuration
  10. Best Practices
  11. Conclusion

The Challenge: Time-Check Logging Pod

The Nautilus DevOps team needs a simple logging solution: a pod that writes the current date and time to a log file at regular intervals. While it sounds simple, it combines several essential Kubernetes concepts:

Requirements

  • Namespace: devops - Isolate resources
  • Pod: time-check - The main application
  • Container: time-check - Using busybox:latest
  • ConfigMap: time-config - Store configuration separately
  • Configuration: TIME_FREQ=12 - Log every 12 seconds
  • Environment Variable: TIME_FREQ - Injected from ConfigMap
  • Command: while true; do date; sleep $TIME_FREQ; done
  • Log File: /opt/data/time/time-check.log
  • Volume: log-volume - Mounted at /opt/data/time

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                     devops Namespace                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │              ConfigMap: time-config                   │ │
│  │              TIME_FREQ: "12"                         │ │
│  └───────────────────┬───────────────────────────────────┘ │
│                      │                                     │
│                      │ (Environment Variable)              │
│                      ▼                                     │
│  ┌───────────────────────────────────────────────────────┐ │
│  │              Pod: time-check                         │ │
│  │  ┌─────────────────────────────────────────────────┐ │ │
│  │  │  Container: time-check                         │ │ │
│  │  │  Image: busybox:latest                         │ │ │
│  │  │  ENV: TIME_FREQ=12                             │ │ │
│  │  │                                               │ │ │
│  │  │  Command:                                      │ │ │
│  │  │  while true; do                                │ │ │
│  │  │    date                                        │ │ │
│  │  │    sleep $TIME_FREQ                            │ │ │
│  │  │  done > /opt/data/time/time-check.log          │ │ │
│  │  └────────────────┬────────────────────────────────┘ │ │
│  │                   │                                   │ │
│  │                   │ (Writes to volume)                │ │
│  │                   ▼                                   │ │
│  │  ┌─────────────────────────────────────────────────┐ │ │
│  │  │  Volume: log-volume (emptyDir)                 │ │ │
│  │  │  /opt/data/time/                               │ │ │
│  │  │  └── time-check.log                            │ │ │
│  │  │      Mon Aug 14 10:00:02 UTC 2026             │ │ │
│  │  │      Mon Aug 14 10:00:14 UTC 2026             │ │ │
│  │  │      Mon Aug 14 10:00:26 UTC 2026             │ │ │
│  │  └─────────────────────────────────────────────────┘ │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Understanding ConfigMaps

What is a ConfigMap?

A ConfigMap is a Kubernetes API object used to store non-confidential configuration data in key-value pairs. Think of it as a separate configuration file that your application can read.

Why Use ConfigMaps?

Benefit Description
Separation of Concerns Keep configuration separate from application code
Environment Specific Different configs for dev, staging, production
Easy Updates Update config without rebuilding images
Reusable Same ConfigMap can be used by multiple pods
Centralized Manage configuration from one place

ConfigMap Syntax

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-config
  namespace: devops
data:
  TIME_FREQ: "12"
  LOG_LEVEL: "debug"
  ENVIRONMENT: "production"
Enter fullscreen mode Exit fullscreen mode

Creating ConfigMaps

Method 1: From Literal Values

kubectl create configmap time-config \
  --from-literal=TIME_FREQ=12 \
  --namespace=devops
Enter fullscreen mode Exit fullscreen mode

Method 2: From a File

kubectl create configmap app-config \
  --from-file=app.properties \
  --namespace=devops
Enter fullscreen mode Exit fullscreen mode

Method 3: From Environment File

kubectl create configmap app-config \
  --from-env-file=config.env \
  --namespace=devops
Enter fullscreen mode Exit fullscreen mode

Method 4: From YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-config
  namespace: devops
data:
  TIME_FREQ: "12"
Enter fullscreen mode Exit fullscreen mode

Understanding Volumes

What are Volumes in Kubernetes?

A Volume is a directory that is accessible to containers in a pod. It provides persistent storage that exists beyond the lifecycle of individual containers.

Volume Types Comparison

Volume Type Description Persistence Use Case
emptyDir Temporary storage Pod lifecycle Cache, temporary files
hostPath Node filesystem Node lifecycle Node-level storage
PersistentVolumeClaim Persistent storage Beyond pod Database, stateful apps
ConfigMap Config data As long as config exists Configuration files
Secret Sensitive data As long as secret exists Credentials, tokens

Our Volume: emptyDir

volumes:
- name: log-volume
  emptyDir: {}
Enter fullscreen mode Exit fullscreen mode

Characteristics:

  • Created when pod is scheduled
  • Lives as long as the pod exists
  • Shared between containers in the same pod
  • Useful for temporary storage

Volume Mounts

volumeMounts:
- name: log-volume
  mountPath: /opt/data/time
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • name must match the volume name
  • mountPath is where it appears in the container
  • Multiple containers can mount the same volume
  • Data is shared between containers

Understanding Environment Variables

Why Use Environment Variables?

Environment variables provide a way to pass configuration to your application without hardcoding values.

How to Set Environment Variables

1. Direct Value

env:
- name: TIME_FREQ
  value: "12"
Enter fullscreen mode Exit fullscreen mode

2. From ConfigMap

env:
- name: TIME_FREQ
  valueFrom:
    configMapKeyRef:
      name: time-config
      key: TIME_FREQ
Enter fullscreen mode Exit fullscreen mode

3. From Secret

env:
- name: PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password
Enter fullscreen mode Exit fullscreen mode

4. From Resource Limits

env:
- name: CPU_LIMIT
  valueFrom:
    resourceFieldRef:
      containerName: time-check
      resource: limits.cpu
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Implementation

Step 1: Create the Namespace

First, create the namespace to isolate our resources:

kubectl create namespace devops
Enter fullscreen mode Exit fullscreen mode

Why namespaces?

  • Organize resources
  • Apply resource quotas
  • Control access with RBAC
  • Isolate environments

Step 2: Create the ConfigMap

Create the ConfigMap with our configuration:

kubectl create configmap time-config \
  --from-literal=TIME_FREQ=12 \
  --namespace=devops
Enter fullscreen mode Exit fullscreen mode

Verify:

kubectl describe configmap time-config -n devops
Enter fullscreen mode Exit fullscreen mode

Output:

Name:         time-config
Namespace:    devops
Labels:       <none>
Annotations:  <none>

Data
====
TIME_FREQ:
----
12
Enter fullscreen mode Exit fullscreen mode

Step 3: Generate the Pod YAML

Generate the base YAML:

kubectl run time-check \
  --image=busybox:latest \
  --namespace=devops \
  --restart=Never \
  --dry-run=client -o yaml > time-check-pod.yaml
Enter fullscreen mode Exit fullscreen mode

Step 4: Edit the YAML

Open the file and add all requirements:

nano time-check-pod.yaml
Enter fullscreen mode Exit fullscreen mode

Complete YAML:

apiVersion: v1
kind: Pod
metadata:
  name: time-check
  namespace: devops
  labels:
    app: time-check
spec:
  containers:
  - name: time-check
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do date; sleep $TIME_FREQ; done > /opt/data/time/time-check.log"]
    env:
    - name: TIME_FREQ
      valueFrom:
        configMapKeyRef:
          name: time-config
          key: TIME_FREQ
    volumeMounts:
    - name: log-volume
      mountPath: /opt/data/time
  volumes:
  - name: log-volume
    emptyDir: {}
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

Step 5: Apply the Pod

Create the pod:

kubectl apply -f time-check-pod.yaml
Enter fullscreen mode Exit fullscreen mode

Step 6: Verify Everything

# Check pod status
kubectl get pods -n devops

# Check logs
kubectl exec time-check -n devops -- cat /opt/data/time/time-check.log

# Check environment variable
kubectl exec time-check -n devops -- env | grep TIME_FREQ

# Check volume mount
kubectl exec time-check -n devops -- df -h /opt/data/time
Enter fullscreen mode Exit fullscreen mode

How It All Works Together

The Command Explained

Let's break down the command:

while true; do date; sleep $TIME_FREQ; done > /opt/data/time/time-check.log
Enter fullscreen mode Exit fullscreen mode

Components:

Part Description
while true Run indefinitely
do date Get current date/time
sleep $TIME_FREQ Wait 12 seconds (from ConfigMap)
done End of loop
> /opt/data/time/time-check.log Redirect output to log file

The Integration Flow

1. Pod starts in devops namespace
   │
   ├─── ConfigMap: time-config
   │    └─── TIME_FREQ: "12"
   │
   ├─── Container: time-check
   │    ├─── Environment Variable
   │    │    └─── TIME_FREQ = 12 (from ConfigMap)
   │    │
   │    ├─── Command Execution
   │    │    └─── while true; do
   │    │         └─── date              ← Gets timestamp
   │    │         └─── sleep 12          ← Waits 12 seconds
   │    │         └─── (repeat)
   │    │
   │    └─── Volume Mount: /opt/data/time
   │         └─── Writes to: time-check.log
   │
   └─── Volume: log-volume (emptyDir)
        └─── Storage location: /opt/data/time
             └─── File: time-check.log
                  └─── Fri Aug 14 17:00:02 UTC 2026
                  └─── Fri Aug 14 17:00:14 UTC 2026
                  └─── Fri Aug 14 17:00:26 UTC 2026
Enter fullscreen mode Exit fullscreen mode

What Happens Each Second

Timeline (every 12 seconds)
═══════════════════════════════════════════════════════════

0s  ───┐
       │
       ├── 1. Container starts
       ├── 2. Reads TIME_FREQ from ConfigMap
       ├── 3. Creates log file at /opt/data/time/time-check.log
       ├── 4. Writes first timestamp:
       │      Fri Aug 14 17:00:02 UTC 2026
       ├── 5. Sleeps for 12 seconds
       │
12s ───┤
       │
       ├── 6. Wakes up
       ├── 7. Writes second timestamp:
       │      Fri Aug 14 17:00:14 UTC 2026
       ├── 8. Sleeps for 12 seconds
       │
24s ───┤
       │
       ├── 9. Writes third timestamp:
       │      Fri Aug 14 17:00:26 UTC 2026
       └── 10. Continues forever...

═══════════════════════════════════════════════════════════
Enter fullscreen mode Exit fullscreen mode

Monitoring and Verification

1. Check Pod Status

# Basic status
kubectl get pods -n devops

# Detailed status
kubectl describe pod time-check -n devops

# Watch in real-time
kubectl get pods -n devops -w
Enter fullscreen mode Exit fullscreen mode

2. View Logs

# View full log file
kubectl exec time-check -n devops -- cat /opt/data/time/time-check.log

# View last 10 lines
kubectl exec time-check -n devops -- tail -10 /opt/data/time/time-check.log

# Follow in real-time
kubectl exec time-check -n devops -- tail -f /opt/data/time/time-check.log

# Count log entries
kubectl exec time-check -n devops -- wc -l /opt/data/time/time-check.log
Enter fullscreen mode Exit fullscreen mode

3. Check Environment Variables

# View all environment variables
kubectl exec time-check -n devops -- env

# View specific variable
kubectl exec time-check -n devops -- echo $TIME_FREQ

# Check variable source
kubectl get pod time-check -n devops -o yaml | grep -A 5 env
Enter fullscreen mode Exit fullscreen mode

4. Check Volume Mount

# Check mount point
kubectl exec time-check -n devops -- mount | grep /opt/data/time

# Check disk usage
kubectl exec time-check -n devops -- df -h /opt/data/time

# Check directory contents
kubectl exec time-check -n devops -- ls -la /opt/data/time
Enter fullscreen mode Exit fullscreen mode

5. Check ConfigMap

# View ConfigMap details
kubectl describe configmap time-config -n devops

# View ConfigMap YAML
kubectl get configmap time-config -n devops -o yaml

# View ConfigMap data
kubectl get configmap time-config -n devops -o jsonpath='{.data}'
Enter fullscreen mode Exit fullscreen mode

6. Complete Monitoring Script

#!/bin/bash
echo "=== Time Check Monitoring ==="
echo "Time: $(date)"
echo ""

echo "--- Pod Status ---"
kubectl get pod time-check -n devops
echo ""

echo "--- Environment Variable ---"
kubectl exec time-check -n devops -- env | grep TIME_FREQ
echo ""

echo "--- Volume Mount ---"
kubectl exec time-check -n devops -- df -h /opt/data/time | tail -1
echo ""

echo "--- Log File Size ---"
kubectl exec time-check -n devops -- du -h /opt/data/time/time-check.log
echo ""

echo "--- Last 5 Log Entries ---"
kubectl exec time-check -n devops -- tail -5 /opt/data/time/time-check.log
echo ""

echo "--- Pod Events ---"
kubectl describe pod time-check -n devops | grep -A 10 Events
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Common Issues

Issue 1: Pod Stuck in Pending

Symptom: Pod shows Pending status

Solutions:

# Check events
kubectl describe pod time-check -n devops

# Check namespace exists
kubectl get namespace devops

# Check resource constraints
kubectl describe nodes

# Check if image is accessible
kubectl run test --image=busybox:latest -n devops --rm -it -- /bin/sh
Enter fullscreen mode Exit fullscreen mode

Issue 2: Pod Not Running

Symptom: Pod shows Error or CrashLoopBackOff

Solutions:

# Check pod logs
kubectl logs time-check -n devops

# Describe the pod
kubectl describe pod time-check -n devops

# Check the command
kubectl get pod time-check -n devops -o yaml | grep -A 5 command

# Test command manually
kubectl run test --image=busybox:latest -n devops --rm -it -- /bin/sh -c "while true; do date; sleep 5; done"
Enter fullscreen mode Exit fullscreen mode

Issue 3: Log File Not Created

Symptom: Log file doesn't exist or is empty

Solutions:

# Check if directory exists
kubectl exec time-check -n devops -- ls -la /opt/data/time

# Check if process is running
kubectl exec time-check -n devops -- ps aux

# Check command syntax
kubectl exec time-check -n devops -- sh -c "date"

# Check permissions
kubectl exec time-check -n devops -- touch /opt/data/time/test.txt
Enter fullscreen mode Exit fullscreen mode

Issue 4: Environment Variable Not Set

Symptom: TIME_FREQ not available

Solutions:

# Check ConfigMap exists
kubectl get configmap time-config -n devops

# Check ConfigMap content
kubectl describe configmap time-config -n devops

# Check environment variable in pod
kubectl exec time-check -n devops -- env | grep TIME_FREQ

# Check if pod references ConfigMap correctly
kubectl get pod time-check -n devops -o yaml | grep -A 5 configMapKeyRef
Enter fullscreen mode Exit fullscreen mode

Issue 5: Volume Not Mounted

Symptom: /opt/data/time not accessible

Solutions:

# Check mount
kubectl exec time-check -n devops -- mount | grep /opt/data/time

# Check if directory exists
kubectl exec time-check -n devops -- ls -la /opt/data/

# Check volume in pod spec
kubectl get pod time-check -n devops -o yaml | grep -A 10 volumes

# Create directory if needed
kubectl exec time-check -n devops -- mkdir -p /opt/data/time
Enter fullscreen mode Exit fullscreen mode

Issue 6: ConfigMap Updates Not Reflected

Symptom: After updating ConfigMap, pod still uses old value

Solution:

# ConfigMap updates don't automatically restart pods
# You need to restart the pod:

# Delete the pod
kubectl delete pod time-check -n devops

# Recreate it
kubectl apply -f time-check-pod.yaml

# Verify new value
kubectl exec time-check -n devops -- env | grep TIME_FREQ
Enter fullscreen mode Exit fullscreen mode

Advanced Configuration

1. Multiple Environment Variables

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-config
  namespace: devops
data:
  TIME_FREQ: "12"
  LOG_LEVEL: "info"
  ENVIRONMENT: "production"
  LOG_ROTATION: "true"
  MAX_LOG_SIZE: "100"
Enter fullscreen mode Exit fullscreen mode

Pod YAML:

env:
- name: TIME_FREQ
  valueFrom:
    configMapKeyRef:
      name: time-config
      key: TIME_FREQ
- name: LOG_LEVEL
  valueFrom:
    configMapKeyRef:
      name: time-config
      key: LOG_LEVEL
- name: ENVIRONMENT
  valueFrom:
    configMapKeyRef:
      name: time-config
      key: ENVIRONMENT
Enter fullscreen mode Exit fullscreen mode

2. Log Rotation

Add log rotation to prevent unlimited growth:

args: ["-c", "
  while true; do
    date >> /opt/data/time/time-check.log;
    LINES=$(wc -l < /opt/data/time/time-check.log);
    if [ $LINES -gt 100 ]; then
      tail -50 /opt/data/time/time-check.log > /opt/data/time/time-check.log.tmp;
      mv /opt/data/time/time-check.log.tmp /opt/data/time/time-check.log;
    fi;
    sleep $TIME_FREQ;
  done
"]
Enter fullscreen mode Exit fullscreen mode

3. Multiple Volumes

volumes:
- name: log-volume
  emptyDir: {}
- name: config-volume
  configMap:
    name: time-config
- name: data-volume
  persistentVolumeClaim:
    claimName: data-pvc
Enter fullscreen mode Exit fullscreen mode

4. Persistent Storage

Switch from emptyDir to PersistentVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: time-logs-pvc
  namespace: devops
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: time-check
  namespace: devops
spec:
  containers:
  - name: time-check
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do date; sleep $TIME_FREQ; done > /opt/data/time/time-check.log"]
    env:
    - name: TIME_FREQ
      valueFrom:
        configMapKeyRef:
          name: time-config
          key: TIME_FREQ
    volumeMounts:
    - name: log-volume
      mountPath: /opt/data/time
  volumes:
  - name: log-volume
    persistentVolumeClaim:
      claimName: time-logs-pvc
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

5. Mount ConfigMap as Volume

Mount ConfigMap as configuration file:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: devops
data:
  app.properties: |
    TIME_FREQ=12
    LOG_LEVEL=info
    ENVIRONMENT=production
---
apiVersion: v1
kind: Pod
metadata:
  name: time-check
  namespace: devops
spec:
  containers:
  - name: time-check
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "cat /etc/config/app.properties; while true; do date; sleep 12; done"]
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

6. Init Containers for Setup

Use init container to prepare the log directory:

apiVersion: v1
kind: Pod
metadata:
  name: time-check
  namespace: devops
spec:
  initContainers:
  - name: setup
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "mkdir -p /opt/data/time && echo 'Log directory created' > /opt/data/time/setup.log"]
    volumeMounts:
    - name: log-volume
      mountPath: /opt/data/time
  containers:
  - name: time-check
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do date; sleep $TIME_FREQ; done > /opt/data/time/time-check.log"]
    env:
    - name: TIME_FREQ
      valueFrom:
        configMapKeyRef:
          name: time-config
          key: TIME_FREQ
    volumeMounts:
    - name: log-volume
      mountPath: /opt/data/time
  volumes:
  - name: log-volume
    emptyDir: {}
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

Best Practices

✅ DO's

1. Use Namespaces for Organization

metadata:
  namespace: devops
Enter fullscreen mode Exit fullscreen mode

2. Store Configuration in ConfigMaps

# BAD - Hardcoded values
env:
- name: TIME_FREQ
  value: "12"

# GOOD - From ConfigMap
env:
- name: TIME_FREQ
  valueFrom:
    configMapKeyRef:
      name: time-config
      key: TIME_FREQ
Enter fullscreen mode Exit fullscreen mode

3. Use Labels for Identification

metadata:
  labels:
    app: time-check
    environment: production
    team: devops
Enter fullscreen mode Exit fullscreen mode

4. Set Resource Limits

resources:
  requests:
    memory: "32Mi"
    cpu: "50m"
  limits:
    memory: "64Mi"
    cpu: "100m"
Enter fullscreen mode Exit fullscreen mode

5. Use Specific Image Tags

# BAD - Unpredictable
image: busybox:latest

# GOOD - Specific version
image: busybox:1.35.0
Enter fullscreen mode Exit fullscreen mode

6. Document Your Configuration

metadata:
  annotations:
    description: "Time check pod for logging purposes"
    owner: "devops-team"
Enter fullscreen mode Exit fullscreen mode

7. Plan for Log Rotation

# Prevent logs from growing indefinitely
# Use rotation or limit log file size
Enter fullscreen mode Exit fullscreen mode

❌ DON'Ts

1. Don't Store Sensitive Data in ConfigMaps

# BAD - Use Secrets instead
data:
  PASSWORD: "admin123"

# GOOD - Use Secrets
data:
  PASSWORD: <base64-encoded>
Enter fullscreen mode Exit fullscreen mode

2. Don't Use :latest in Production

# BAD - Unpredictable updates
image: busybox:latest

# GOOD - Specific version
image: busybox:1.35.0
Enter fullscreen mode Exit fullscreen mode

3. Don't Forget Resource Limits

# BAD - No limits
resources: {}

# GOOD - With limits
resources:
  requests:
    memory: "32Mi"
    cpu: "50m"
  limits:
    memory: "64Mi"
    cpu: "100m"
Enter fullscreen mode Exit fullscreen mode

4. Don't Ignore Namespace Isolation

# BAD - Default namespace
metadata:
  name: time-check

# GOOD - Specific namespace
metadata:
  name: time-check
  namespace: devops
Enter fullscreen mode Exit fullscreen mode

5. Don't Hardcode Paths

# BAD - Hardcoded path
args: ["-c", "date > /tmp/log.txt"]

# GOOD - Configurable path
args: ["-c", "date > /opt/data/time/time-check.log"]
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases

Use Case 1: Application Logging

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  LOG_INTERVAL: "60"
  LOG_FORMAT: "json"
  LOG_LEVEL: "info"
---
apiVersion: v1
kind: Pod
metadata:
  name: app-logger
  namespace: production
spec:
  containers:
  - name: logger
    image: busybox:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo '{\"timestamp\":\"'$(date -Iseconds)'\",\"level\":\"info\",\"message\":\"Health check OK\"}'; sleep 60; done > /var/log/app/app.log"]
    env:
    - name: LOG_INTERVAL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: LOG_INTERVAL
    volumeMounts:
    - name: log-volume
      mountPath: /var/log/app
  volumes:
  - name: log-volume
    persistentVolumeClaim:
      claimName: app-logs-pvc
  restartPolicy: Always
Enter fullscreen mode Exit fullscreen mode

Use Case 2: Database Backup Status

apiVersion: v1
kind: ConfigMap
metadata:
  name: backup-config
  namespace: production
data:
  BACKUP_INTERVAL: "3600"
  BACKUP_RETENTION: "7"
---
apiVersion: v1
kind: Pod
metadata:
  name: backup-monitor
  namespace: production
spec:
  containers:
  - name: monitor
    image: postgres:13
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo 'Backup completed at '$(date) >> /backup/status.log; sleep $BACKUP_INTERVAL; done"]
    env:
    - name: BACKUP_INTERVAL
      valueFrom:
        configMapKeyRef:
          name: backup-config
          key: BACKUP_INTERVAL
    volumeMounts:
    - name: backup-volume
      mountPath: /backup
  volumes:
  - name: backup-volume
    persistentVolumeClaim:
      claimName: backup-pvc
  restartPolicy: Always
Enter fullscreen mode Exit fullscreen mode

Use Case 3: Health Check Logging

apiVersion: v1
kind: ConfigMap
metadata:
  name: health-config
  namespace: production
data:
  CHECK_INTERVAL: "30"
  SERVICE_URL: "http://app-service/health"
---
apiVersion: v1
kind: Pod
metadata:
  name: health-checker
  namespace: production
spec:
  containers:
  - name: checker
    image: curlimages/curl:7.85.0
    command: ["/bin/sh"]
    args: ["-c", "while true; do curl -s -o /dev/null -w '%{http_code}' $SERVICE_URL >> /health/status.log; date >> /health/status.log; sleep $CHECK_INTERVAL; done"]
    env:
    - name: CHECK_INTERVAL
      valueFrom:
        configMapKeyRef:
          name: health-config
          key: CHECK_INTERVAL
    - name: SERVICE_URL
      valueFrom:
        configMapKeyRef:
          name: health-config
          key: SERVICE_URL
    volumeMounts:
    - name: health-volume
      mountPath: /health
  volumes:
  - name: health-volume
    emptyDir: {}
  restartPolicy: Always
Enter fullscreen mode Exit fullscreen mode

Quick Reference Card

ConfigMap Commands

Command Description
kubectl create configmap NAME --from-literal=KEY=VALUE Create from literal
kubectl get configmaps List ConfigMaps
kubectl describe configmap NAME Get ConfigMap details
kubectl edit configmap NAME Edit ConfigMap
kubectl delete configmap NAME Delete ConfigMap

Pod Commands

Command Description
kubectl run NAME --image=IMAGE Create a pod
kubectl get pods List pods
kubectl describe pod NAME Get pod details
kubectl exec NAME -- COMMAND Execute in pod
kubectl logs NAME View pod logs

Volume Commands

Command Description
kubectl get pv List PersistentVolumes
kubectl get pvc List PersistentVolumeClaims
kubectl describe pvc NAME Get PVC details

Conclusion

You've successfully created a time-check logging pod that combines multiple essential Kubernetes concepts: ConfigMaps, environment variables, volumes, and namespaces. This is exactly the kind of real-world task you'll encounter as a DevOps engineer.

Key Takeaways

  1. ConfigMaps separate configuration from code
  2. Environment Variables inject configuration into containers
  3. Volumes provide persistent storage
  4. Namespaces organize resources
  5. Combining these concepts creates powerful, flexible applications

What You Learned

✅ How to create and use ConfigMaps
✅ How to inject ConfigMaps as environment variables
✅ How to create and mount volumes
✅ How to write a continuous logging script
✅ How to verify all components work together
✅ How to troubleshoot common issues
✅ Best practices for production

Top comments (0)