DevOps

Kubernetes Core Objects

Master Kubernetes Deployments, Services, ConfigMaps, and Secrets. Learn to deploy and manage containerized applications at scale.

By TechCoder TeamLast updated: 2026-06-02
In a Nutshell

Master Kubernetes Deployments, Services, ConfigMaps, and Secrets. Learn to deploy and manage containerized applications at scale. This hands-on tutorial focuses on practical implementation of kubernetes core objects concepts.

Kubernetes Core Objects

Kubernetes provides a rich set of resources for deploying, exposing, and managing containerized applications. Let's explore the core objects every DevOps engineer must master.

Deployments

Deployments provide declarative updates for Pods and ReplicaSets—ideal for stateless applications.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
          name: http
        env:
        - name: NGINX_HOST
          value: "example.com"
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: api-key
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        volumeMounts:
        - name: config-vol
          mountPath: /etc/nginx/conf.d
        - name: html-vol
          mountPath: /usr/share/nginx/html
      volumes:
      - name: config-vol
        configMap:
          name: nginx-config
      - name: html-vol
        persistentVolumeClaim:
          claimName: nginx-pvc
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - nginx
              topologyKey: kubernetes.io/hostname

Deployment Commands

# Create deployment
kubectl apply -f deployment.yaml
kubectl create deployment nginx --image=nginx:alpine --replicas=3

# View deployments
kubectl get deployments
kubectl get deploy -o wide
kubectl describe deployment nginx-deployment

# Scale deployment
kubectl scale deployment nginx-deployment --replicas=5
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80

# Rolling update
kubectl set image deployment/nginx-deployment nginx=nginx:1.26-alpine
kubectl rollout status deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2

# Pause/Resume rollout
kubectl rollout pause deployment/nginx-deployment
kubectl rollout resume deployment/nginx-deployment

Services

Services expose applications running on Pods to network traffic.

Service Types

# ClusterIP - Internal cluster access (default)
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 3000
    protocol: TCP
# NodePort - Expose on each node's IP
apiVersion: v1
kind: Service
metadata:
  name: api-nodeport
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 3000
    nodePort: 30080  # Range: 30000-32767
# LoadBalancer - Cloud provider LB
apiVersion: v1
kind: Service
metadata:
  name: api-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 3000
# ExternalName - DNS alias
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: database.example.com

Headless Services

apiVersion: v1
kind: Service
metadata:
  name: db-headless
spec:
  clusterIP: None  # Headless
  selector:
    app: db
  ports:
  - port: 5432

ConfigMaps

ConfigMaps store non-confidential configuration data.

# From literal values
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgres://db:5432/myapp"
  cache_ttl: "3600"
  feature_flags: |
    NEW_UI=true
    BETA_API=false
# From files
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  default.conf: |
    server {
      listen 80;
      location / {
        root /usr/share/nginx/html;
        index index.html;
      }
    }

Using ConfigMaps

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    env:
    # Single value
    - name: DATABASE_URL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: database_url
    # All values
    envFrom:
    - configMapRef:
        name: app-config
    volumeMounts:
    # As volume
    - name: config-vol
      mountPath: /etc/config
  volumes:
  - name: config-vol
    configMap:
      name: nginx-config
# Create from command line
kubectl create configmap app-config \
  --from-literal=database_url=postgres://db:5432/myapp \
  --from-literal=cache_ttl=3600

kubectl create configmap nginx-config \
  --from-file=default.conf

# View
kubectl get configmap app-config -o yaml

Secrets

Secrets store sensitive data like passwords, tokens, and keys.

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  # Base64 encoded values
  # echo -n 'mysecretpassword' | base64
  db-password: bXlzZWNyZXRwYXNzd29yZA==
  api-key: ZXhhbXBsZS1hcGkta2V5
stringData:
  # Plain text (encoded automatically)
  config.json: |
    {
      "timeout": 30,
      "retries": 3
    }

Using Secrets

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: app-secrets
          key: db-password
    envFrom:
    - secretRef:
        name: app-secrets
    volumeMounts:
    - name: secret-vol
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-vol
    secret:
      secretName: app-secrets
# Create secret
kubectl create secret generic app-secrets \
  --from-literal=db-password=mysecretpassword \
  --from-literal=api-key=example-api-key

kubectl create secret tls tls-secret \
  --cert=path/to/cert.crt \
  --key=path/to/key.key

# View (decoded)
kubectl get secret app-secrets -o jsonpath='{.data.db-password}' | base64 -d

Secret Types

| Type | Use | |------|-----| | Opaque | Arbitrary user-defined data (default) | | kubernetes.io/service-account-token | Service account token | | kubernetes.io/dockerconfigjson | Registry authentication | | kubernetes.io/tls | TLS certificate and key | | kubernetes.io/ssh-auth | SSH authentication | | kubernetes.io/basic-auth | Basic authentication |

Persistent Storage

PersistentVolume (PV)

Cluster storage resource provisioned by admin.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /exports/data
    server: nfs-server.example.com

PersistentVolumeClaim (PVC)

User request for storage.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

Using in Pods

apiVersion: v1
kind: Pod
metadata:
  name: db-pod
spec:
  containers:
  - name: postgres
    image: postgres:15
    volumeMounts:
    - name: data
      mountPath: /var/lib/postgresql/data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: app-pvc

Storage Classes

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  replication-type: regional
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: WaitForFirstConsumer

Resource Management

Resource Quotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "20"
    services: "10"
    persistentvolumeclaims: "5"

Limit Ranges

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: production
spec:
  limits:
  - default:
      memory: 512Mi
      cpu: 500m
    defaultRequest:
      memory: 256Mi
      cpu: 100m
    max:
      memory: 1Gi
      cpu: 1000m
    min:
      memory: 128Mi
      cpu: 50m
    type: Container

Quiz

Quiz

Question 1 of 5

What is the default Service type in Kubernetes?

NodePort
LoadBalancer
ClusterIP
ExternalName

Next Steps

Now let's explore advanced Kubernetes concepts: Ingress, Helm charts, and autoscaling.