|$ curl https://forge-ai.dev/api/markdown?path=docs/ci/kubernetes
$cat docs/ci/cd-—-kubernetes.md
updated Recently·16 min read·published

CI/CD — Kubernetes

CI/CDAdvanced
Introduction

Kubernetes (K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. Originally developed by Google and now maintained by the CNCF, it has become the industry standard for running workloads in production.

This section covers the core Kubernetes concepts — pods, deployments, services, ingress, ConfigMaps, Secrets, Helm charts — and how to integrate Kubernetes into CI/CD pipelines for automated rollouts.

Kubernetes Architecture

A Kubernetes cluster is divided into a control plane and worker nodes. The control plane manages the desired state of the cluster, while worker nodes run the actual application workloads.

ComponentRole
API ServerFrontend for the control plane; all communication goes through it
etcdDistributed key-value store holding all cluster state
SchedulerAssigns pods to nodes based on resource requirements and constraints
Controller ManagerRuns reconciliation loops to match desired state with actual state
KubeletAgent on each worker node that manages pod lifecycle
Kube-proxyHandles network routing and load balancing for services

info

For learning and development, use a local cluster with Minikube, Kind, or k3s. For production, use managed services like EKS (AWS), GKE (Google Cloud), or AKS (Azure) to offload control plane management.
Pods & Containers

A Pod is the smallest deployable unit in Kubernetes — one or more co-located containers that share network namespace and storage volumes. In practice, most pods run a single container.

pod.yaml
YAML
1apiVersion: v1
2kind: Pod
3metadata:
4 name: web-app
5 labels:
6 app: web
7spec:
8 containers:
9 - name: nginx
10 image: nginx:1.25-alpine
11 ports:
12 - containerPort: 80
13 resources:
14 requests:
15 memory: "64Mi"
16 cpu: "100m"
17 limits:
18 memory: "128Mi"
19 cpu: "250m"
20 livenessProbe:
21 httpGet:
22 path: /healthz
23 port: 80
24 initialDelaySeconds: 10
25 periodSeconds: 5

warning

Always set resource requests and limits on every container. Without them, a single misbehaving pod can consume all node resources and starve other workloads.
Deployments & ReplicaSets

A Deployment manages ReplicaSets and provides declarative updates for pods. When you update a Deployment, it performs a rolling update — gradually replacing old pods with new ones with zero downtime.

deployment.yaml
YAML
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: web-app
5 labels:
6 app: web
7spec:
8 replicas: 3
9 selector:
10 matchLabels:
11 app: web
12 strategy:
13 type: RollingUpdate
14 rollingUpdate:
15 maxSurge: 1
16 maxUnavailable: 0
17 template:
18 metadata:
19 labels:
20 app: web
21 spec:
22 containers:
23 - name: app
24 image: ghcr.io/myorg/web-app:v1.2.0
25 ports:
26 - containerPort: 3000
27 env:
28 - name: NODE_ENV
29 value: "production"
30 readinessProbe:
31 httpGet:
32 path: /ready
33 port: 3000
34 initialDelaySeconds: 5
35 periodSeconds: 3

maxSurge: 1

During update, create at most 1 extra pod above the desired replica count.

maxUnavailable: 0

Never take more pods offline than needed — ensures full capacity during rollout.

Services

Services provide stable networking for pods. Since pods are ephemeral (they can be created, destroyed, and rescheduled at any time), a Service gives them a fixed DNS name and IP address for internal and external communication.

Service TypePurpose
ClusterIPInternal-only access within the cluster (default)
NodePortExposes service on a static port on every node (30000-32767)
LoadBalancerProvisions a cloud load balancer for external traffic
service.yaml
YAML
1apiVersion: v1
2kind: Service
3metadata:
4 name: web-service
5spec:
6 selector:
7 app: web
8 type: ClusterIP
9 ports:
10 - port: 80
11 targetPort: 3000
12 protocol: TCP
Ingress & Ingress Controllers

Ingress exposes HTTP/HTTPS routes from outside the cluster to services inside. An Ingress Controller (like NGINX or Traefik) processes Ingress resources and configures the underlying load balancer accordingly.

ingress.yaml
YAML
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4 name: web-ingress
5 annotations:
6 cert-manager.io/cluster-issuer: letsencrypt-prod
7 nginx.ingress.kubernetes.io/rate-limit: "100"
8spec:
9 ingressClassName: nginx
10 tls:
11 - hosts:
12 - app.example.com
13 secretName: app-tls
14 rules:
15 - host: app.example.com
16 http:
17 paths:
18 - path: /
19 pathType: Prefix
20 backend:
21 service:
22 name: web-service
23 port:
24 number: 80

best practice

Use cert-manager with Let's Encrypt for automatic TLS certificate provisioning and renewal. The nginx ingress controller handles SSL termination and can enforce HTTPS redirects.
ConfigMaps & Secrets

ConfigMaps store non-sensitive configuration data. Secrets store sensitive data like passwords, tokens, and keys (base64-encoded, not encrypted by default — use external secrets management for production).

configmap-secret.yaml
YAML
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: app-config
5data:
6 DATABASE_HOST: "postgres.default.svc.cluster.local"
7 DATABASE_PORT: "5432"
8 LOG_LEVEL: "info"
9---
10apiVersion: v1
11kind: Secret
12metadata:
13 name: app-secrets
14type: Opaque
15data:
16 DATABASE_PASSWORD: cGFzc3dvcmQxMjM= # base64 encoded
17 API_KEY: c2VjcmV0LWFwaS1rZXk=
env-from.yaml
YAML
1# Inject into a pod via env vars
2containers:
3 - name: app
4 envFrom:
5 - configMapRef:
6 name: app-config
7 - secretRef:
8 name: app-secrets

warning

Kubernetes Secrets are only base64-encoded, not encrypted. For production, use External Secrets Operator, Sealed Secrets, or a vault integration (HashiCorp Vault, AWS Secrets Manager) to manage sensitive data securely.
Helm Charts for Package Management

Helm is the package manager for Kubernetes. A Helm chart is a collection of YAML templates that describe related Kubernetes resources. Helm allows you to install, upgrade, and rollback complex applications with a single command.

helm-commands.sh
Bash
1# Add a chart repository
2helm repo add bitnami https://charts.bitnami.com/bitnami
3helm repo update
4
5# Search for charts
6helm search repo nginx
7
8# Install a chart with custom values
9helm install my-release bitnami/nginx \
10 --set service.type=LoadBalancer \
11 --set replicaCount=3 \
12 --namespace production \
13 --create-namespace
14
15# Upgrade a release
16helm upgrade my-release bitnami/nginx \
17 --set image.tag=1.27.0 \
18 --namespace production
19
20# Rollback to previous version
21helm rollback my-release 1 --namespace production
22
23# List all releases
24helm list --all-namespaces
Chart.yaml
YAML
1# Chart.yaml
2apiVersion: v2
3name: web-app
4description: A Helm chart for our web application
5type: application
6version: 0.1.0
7appVersion: "1.2.0"
8
9# values.yaml (defaults)
10replicaCount: 2
11image:
12 repository: ghcr.io/myorg/web-app
13 tag: "latest"
14 pullPolicy: IfNotNotPresent
15service:
16 type: ClusterIP
17 port: 80
18ingress:
19 enabled: true
20 host: app.example.com

info

Store your Helm values files in version control alongside your application code. Use environment-specific overrides (values-staging.yaml, values-production.yaml) to manage differences across deployments.
kubectl Essentials

kubectl is the command-line tool for interacting with the Kubernetes API server. Master these commands for daily cluster operations.

kubectl-commands.sh
Bash
1# Inspect cluster state
2kubectl get nodes
3kubectl get pods -A # all namespaces
4kubectl get deployments -n production
5kubectl get svc,ingress -n production
6
7# Detailed information
8kubectl describe pod web-app-xyz123 -n production
9kubectl describe deployment web-app -n production
10
11# View logs
12kubectl logs web-app-xyz123 -n production --tail=100
13kubectl logs -f web-app-xyz123 -n production # follow
14
15# Execute into a pod
16kubectl exec -it web-app-xyz123 -n production -- /bin/sh
17
18# Apply and delete resources
19kubectl apply -f deployment.yaml
20kubectl delete -f deployment.yaml
21
22# Scale
23kubectl scale deployment web-app --replicas=5 -n production
24
25# Restart all pods (rolling restart)
26kubectl rollout restart deployment web-app -n production
27
28# Check rollout status
29kubectl rollout status deployment web-app -n production
30
31# View resource usage
32kubectl top nodes
33kubectl top pods -n production

best practice

Set up kubectl autocompletion and aliases for faster interaction. Add alias k=kubectl and enable context switching with kubectx and kubens to move between clusters and namespaces quickly.
Kubernetes in CI/CD Pipelines

Integrating Kubernetes with CI/CD involves building container images, pushing them to a registry, updating manifests, and applying them to the cluster. Tools like ArgoCD, Flux, and GitHub Actions simplify this workflow.

k8s-deploy.yml
YAML
1# GitHub Actions: Build, push, and deploy to K8s
2name: Deploy to Kubernetes
3on:
4 push:
5 tags: ["v*"]
6
7jobs:
8 deploy:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12
13 - name: Build and push image
14 run: |
15 docker build -t ghcr.io/myorg/app:${{ github.sha }} .
16 docker push ghcr.io/myorg/app:${{ github.sha }}
17
18 - name: Update manifest and apply
19 run: |
20 kubectl set image deployment/web-app \
21 app=ghcr.io/myorg/app:${{ github.sha }} \
22 -n production
23 kubectl rollout status deployment/web-app -n production
24 env:
25 KUBECONFIG: ${{ secrets.KUBECONFIG }}
argocd-setup.sh
Bash
1# ArgoCD: declarative GitOps approach
2# Install ArgoCD
3kubectl create namespace argocd
4kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
5
6# Create an application
7argocd app create web-app \
8 --repo https://github.com/myorg/k8s-manifests.git \
9 --path apps/web-app \
10 --dest-server https://kubernetes.default.svc \
11 --dest-namespace production \
12 --sync-policy automated \
13 --auto-prune \
14 --self-heal

info

GitOps (ArgoCD, Flux) is the recommended approach for Kubernetes deployments. The desired state lives in Git, and a controller continuously reconciles the actual cluster state with the declared state — giving you audit trails, rollback, and drift detection for free.
Alternatives

Kubernetes is powerful but complex. Depending on your scale and requirements, simpler alternatives may be more appropriate.

ToolBest ForTrade-off
Docker ComposeSingle-host development and simple deploymentsNo multi-node scaling or self-healing
NomadSimpler orchestrator with multi-platform supportSmaller ecosystem than Kubernetes
ECS FargateServerless containers on AWS without node managementAWS vendor lock-in
Railway / Fly.ioRapid deployment with zero infrastructure managementLess control over networking and scheduling
Best Practices

✓ Use namespaces for isolation

Separate staging, production, and monitoring workloads into dedicated namespaces with resource quotas.

✓ Always set resource requests and limits

Without resource constraints, a single pod can monopolize node resources. Requests ensure scheduling, limits prevent runaway usage.

✓ Use readiness and liveness probes

Readiness probes prevent traffic to unready pods. Liveness probes restart crashed containers automatically.

✓ Prefer GitOps for deployments

Store manifests in Git and use ArgoCD or Flux for automated, auditable deployments with built-in rollback and drift detection.

✓ Use Pod Disruption Budgets

PDBs ensure a minimum number of pods remain available during voluntary disruptions like node drains and cluster upgrades.

$Blueprint — Engineering Documentation·Section ID: CICD-K8S·Revision: 1.0