BLOG

kubernetes 3 Controller
kubernetes Controller, Deployment, HPA, DaemonSet, Job, CronJob

Deployment

apiVersion: apps/v1                         # string: API version for Deployment resource
kind: Deployment                            # string: Type of Kubernetes resource
metadata:
  name: my-app-deployment                   # string: Name of the Deployment
  labels:                                   # map[string]string: Key-value labels for grouping and selection
    app: my-app
    tier: backend
spec:
  replicas: 4                               # int: Number of pod replicas
  selector:                                 # object: Defines how to match pods managed by this Deployment
    matchLabels:                            # map[string]string
      app: my-app
      tier: backend
  template:                                 # object: Pod template used by the Deployment
    metadata:
      labels:                               # map[string]string
        app: my-app
        tier: backend
    spec:
      containers:                           # array: List of container definitions
        - name: my-app-container            # string: Name of the container
          image: myregistry.com/my-app      # string: Full image path with tag
          imagePullPolicy: IfNotPresent     # string: Policy to pull image (Always, IfNotPresent, Never)
          ports:
            - containerPort: 8080           # int: Port exposed by the container
          env:                              # array of objects: Environment variables
            - name: ENVIRONMENT             # string: Name of the env var
              value: "production"           # string: Value of the env var
            - name: LOG_LEVEL
              value: "info"
          resources:                        # object: CPU and memory limits/requests
            requests:                       # object: Minimum resources guaranteed
              cpu: "250m"                   # string: CPU in millicores
              memory: "512Mi"               # string: Memory in Mebibytes
            limits:                         # object: Maximum allowed resources
              cpu: "500m"
              memory: "1Gi"
          readinessProbe:                   # object: Probe to check if the pod is ready to serve traffic
            httpGet:                        # object: HTTP GET probe config
              path: /healthz
              port: 8080
            initialDelaySeconds: 10         # int: Delay before the first check
            periodSeconds: 5                # int: Frequency of checks
          livenessProbe:                    # object: Probe to check if the pod is still alive
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
  strategy:                                 # object: Deployment strategy
    type: RollingUpdate                     # string: Type of update strategy
    rollingUpdate:
      maxUnavailable: 1                     # int or string: Max pods that can be unavailable during update
      maxSurge: 1                           # int or string: Max pods that can be created above desired count
  revisionHistoryLimit: 10                  # int: How many old ReplicaSets to keep for rollback
  paused: false                             # bool: If true, pauses the rollout
  progressDeadlineSeconds: 600              # int: Max seconds to wait for a rollout to succeed

Update & Rollout Strategy

RollingUpdate

  1. Create a new pod
  2. Wait the pod becomse "Ready"
  3. Remove a old pod
  4. Repeat

Recreate

  1. Delete all existing pods
  2. Wwat until all pods are fully terminated
  3. Create new pods

HorizontalPodAutoscaler

apiVersion: autoscaling/v2                # string: API version (v2 allows multiple metrics)
kind: HorizontalPodAutoscaler             # string: Kind of resource
metadata:
  name: my-app-hpa                        # string: Name of the HPA object
  namespace: default                      # string: Namespace (optional if default)
spec:
  scaleTargetRef:                         # object: Reference to the target deployment
    apiVersion: apps/v1                   # string: API version of the target
    kind: Deployment                      # string: Kind of the target (e.g., Deployment, StatefulSet)
    name: my-app-deployment               # string: Name of the target resource

  minReplicas: 2                          # int: Minimum number of pods to maintain
  maxReplicas: 10                         # int: Maximum number of pods that can be scaled up

  metrics:                                # array: List of metrics to monitor
    - type: Resource                      # string: Type of metric (Resource | Pods | Object | External)
      resource:
        name: cpu                         # string: Resource to monitor (cpu, memory)
        target:
          type: Utilization               # string: Type of target (Utilization, AverageValue)
          averageUtilization: 60          # int: Target average % CPU usage across pods

    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 70

What this HPA does:
- Watches a Deployment named my-app-deployment
- Keeps pod count between 2 and 10
- Scales up/down based on:
- CPU usage exceeding 60%
- Memory usage exceeding 70%

The target Deployment must have resources.requests.cpu and resources.requests.memory set, or HPA won’t work.

DaemonSet

apiVersion: apps/v1                        # string: API version for DaemonSet
kind: DaemonSet                            # string: Kind of resource
metadata:
  name: fluentd-logger                     # string: Name of the DaemonSet
  namespace: kube-system                   # string: Namespace (commonly kube-system for system agents)
  labels:                                  # map[string]string: Key-value labels
    app: fluentd

spec:
  selector:                                # object: Label selector to match Pods
    matchLabels:
      app: fluentd
  template:                                # object: Pod template
    metadata:
      labels:
        app: fluentd
    spec:
      tolerations:                         # array: Allow scheduling on master or tainted nodes
        - key: node-role.kubernetes.io/control-plane
          operator: Exists
          effect: NoSchedule
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule

      containers:
        - name: fluentd                    # string: Container name
          image: fluent/fluentd:v1.14      # string: Fluentd image
          resources:                       # object: Resource requests and limits
            limits:
              memory: "200Mi"
              cpu: "200m"
            requests:
              memory: "100Mi"
              cpu: "100m"
          volumeMounts:                    # array: Mount volumes for logs
            - name: varlog
              mountPath: /var/log
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true

      volumes:                             # array: Volumes to mount on the container
        - name: varlog
          hostPath:
            path: /var/log                 # string: Path on the host node
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers

  updateStrategy:                          # object: Strategy for updating pods
    type: RollingUpdate                    # string: Type (RollingUpdate or OnDelete)

Use a DaemonSet when you want to run one pod per node, such as:
- Logging agents (Fluentd, Logstash)
- Monitoring agents (Prometheus Node Exporter, Datadog)
- Security tools (Falco, antivirus)
- Storage daemons (Ceph, GlusterFS)

Job

apiVersion: batch/v1                       # string: API version for Job resource
kind: Job                                  # string: Kind of resource
metadata:
  name: data-processing-job                # string: Name of the Job
  namespace: default                       # string: Namespace to run the job in
  labels:                                  # map[string]string: Metadata for organization
    app: batch-job

spec:
  completions: 1                           # int: Total successful pods needed to complete the job
  parallelism: 1                           # int: How many pods can run in parallel
  backoffLimit: 4                          # int: How many retries before marking job as failed
  activeDeadlineSeconds: 300              # int: Max duration (seconds) the job is allowed to run

  template:                                # object: Pod template for the job
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: Never                # string: Must be OnFailure or Never for Jobs
      containers:
        - name: processor                 # string: Name of the container
          image: busybox                  # string: Container image
          command: ["sh", "-c", "echo Hello from the job; sleep 10"] # array[string]: Command to run

What this Job does:
- Runs a busybox container that echoes a message and sleeps.
- Runs only once (completions: 1, parallelism: 1).
- Retries up to 4 times if it fails (backoffLimit: 4).
- Times out if it runs longer than 5 minutes (activeDeadlineSeconds: 300).
- Pod won’t restart on failure unless specified.

Use Cases for Jobs:
- Data migration scripts
- Cleanup tasks
- Sending email reports
- Import/export batches
- One-time maintenance tasks

CronJob

apiVersion: batch/v1                         # string: API version for CronJob
kind: CronJob                                # string: Type of resource
metadata:
  name: daily-report-job                     # string: Name of the CronJob
  namespace: default                         # string: Namespace to run the job
  labels:                                    # map[string]string
    app: reporting

spec:
  schedule: "0 3 * * *"                      # string: Cron schedule (this runs daily at 3:00 AM)
  timeZone: "UTC"                            # string: Time zone for schedule (K8s v1.24+)
  startingDeadlineSeconds: 100               # int: If job misses schedule, how long to allow it to start
  concurrencyPolicy: Forbid                  # string: Allow, Forbid, Replace
  suspend: false                             # bool: If true, pause this cronjob
  successfulJobsHistoryLimit: 3              # int: Number of successful job histories to keep
  failedJobsHistoryLimit: 1                  # int: Number of failed job histories to keep
  jobTemplate:                               # object: Template for the actual Job
    spec:
      backoffLimit: 2                        # int: Retry attempts before job fails
      template:
        spec:
          restartPolicy: OnFailure           # string: OnFailure or Never
          containers:
            - name: report-generator         # string: Container name
              image: busybox                 # string: Image used in the job
              command:                       # array[string]: Shell command to run
                - sh
                - -c
                - "echo Generating daily report... && sleep 20"

How This Works
- Runs every day at 3:00 AM UTC.
- Executes a simple shell command using busybox.
- Keeps history of the last 3 successes and 1 failure.
- Won’t run a new instance if the previous is still running (concurrencyPolicy: Forbid).
- Will retry the job up to 2 times if it fails.