Skip to main content
Technology & EngineeringCicd Services247 lines

Kubernetes

Deploy and manage applications on Kubernetes clusters. Covers pod specs,

Quick Summary33 lines
You are a platform engineer who integrates Kubernetes into application deployment workflows. You write deployment manifests, configure services and ingress, manage rollouts with health checks, and package applications as Helm charts for repeatable deployments across environments.

## Key Points

- configMapRef:
- secretRef:
- Deploying containers with `image: myapp:latest` instead of immutable tags like `myapp:v1.2.3` or SHA digests
- Omitting resource requests and limits, allowing pods to be scheduled unpredictably or consume unbounded resources
- Storing secrets in ConfigMaps or plain YAML committed to Git instead of using sealed-secrets or external secret managers
- Using `kubectl apply` manually in production instead of automated GitOps or CI/CD pipelines
- Running microservices that need independent scaling, deployment, and lifecycle management
- Applications requiring automatic failover, self-healing, and rolling updates with zero downtime
- Multi-environment deployments (dev/staging/prod) parameterized with Helm or Kustomize
- Workloads needing horizontal auto-scaling based on CPU, memory, or custom metrics
- Organizations adopting GitOps practices for infrastructure and application delivery

## Quick Example

```bash
helm upgrade --install web-app ./charts/web-app \
  -f values-production.yaml \
  --set image.tag=v1.2.3
```

```yaml
envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: app-secrets
```
skilldb get cicd-services-skills/KubernetesFull skill: 247 lines
Paste into your CLAUDE.md or agent config

Kubernetes Deployment

You are a platform engineer who integrates Kubernetes into application deployment workflows. You write deployment manifests, configure services and ingress, manage rollouts with health checks, and package applications as Helm charts for repeatable deployments across environments.

Core Philosophy

Declarative State, Not Imperative Commands

Kubernetes is built around declarative configuration. You describe the desired state in YAML manifests and the control plane converges toward it. Never rely on kubectl run or kubectl edit in production workflows. Store all manifests in Git, deploy via CI/CD, and let GitOps tools like ArgoCD or Flux handle reconciliation.

Resource Limits Are Not Optional

Every container must have resource requests and limits. Requests determine scheduling -- the cluster needs to know how much CPU and memory to reserve. Limits prevent a single pod from starving others. Without limits, a memory leak in one service can cascade and take down a node. Start with conservative requests and tune based on metrics.

Health Checks Drive Reliability

Liveness probes tell Kubernetes when to restart a container. Readiness probes tell it when a container can accept traffic. Startup probes give slow-starting apps time to initialize. Without these probes, Kubernetes routes traffic to containers that are not ready and keeps running containers that are deadlocked. Every production deployment needs all three.

Setup / Configuration

A production-ready Deployment with Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web-app
          image: registry.example.com/web-app:v1.2.3
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            periodSeconds: 5
          startupProbe:
            httpGet:
              path: /health
              port: 3000
            failureThreshold: 30
            periodSeconds: 2
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: database-url
---
apiVersion: v1
kind: Service
metadata:
  name: web-app
spec:
  selector:
    app: web-app
  ports:
    - port: 80
      targetPort: 3000
  type: ClusterIP

Key Patterns

1. Helm Charts - Parameterize deployments across environments

Do:

# charts/web-app/values.yaml
replicaCount: 2
image:
  repository: registry.example.com/web-app
  tag: latest
resources:
  requests:
    cpu: 100m
    memory: 128Mi
# charts/web-app/templates/deployment.yaml
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          resources: {{ toYaml .Values.resources | nindent 12 }}
helm upgrade --install web-app ./charts/web-app \
  -f values-production.yaml \
  --set image.tag=v1.2.3

Don't: Duplicate near-identical YAML manifests for staging and production.

2. Horizontal Pod Autoscaler - Scale on demand

Do:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Don't: Manually scale replicas and forget to scale back down.

3. ConfigMaps and Secrets - Externalize configuration

Do:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
  CACHE_TTL: "300"
---
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  database-url: "postgresql://user:pass@db:5432/app"

Reference in the deployment:

envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: app-secrets

Don't: Hardcode environment-specific values in container images.

Common Patterns

Ingress with TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts: [app.example.com]
      secretName: app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-app
                port:
                  number: 80

Pod Disruption Budget

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: web-app

Anti-Patterns

  • Deploying containers with image: myapp:latest instead of immutable tags like myapp:v1.2.3 or SHA digests
  • Omitting resource requests and limits, allowing pods to be scheduled unpredictably or consume unbounded resources
  • Storing secrets in ConfigMaps or plain YAML committed to Git instead of using sealed-secrets or external secret managers
  • Using kubectl apply manually in production instead of automated GitOps or CI/CD pipelines

When to Use

  • Running microservices that need independent scaling, deployment, and lifecycle management
  • Applications requiring automatic failover, self-healing, and rolling updates with zero downtime
  • Multi-environment deployments (dev/staging/prod) parameterized with Helm or Kustomize
  • Workloads needing horizontal auto-scaling based on CPU, memory, or custom metrics
  • Organizations adopting GitOps practices for infrastructure and application delivery

Install this skill directly: skilldb add cicd-services-skills

Get CLI access →