Skip to main content
CleanStart

Knowledge Hub

Kubernetes Fundamentals for Container Users

Watch the Lesson

This guide teaches you Kubernetes from the ground up — the orchestration platform, core concepts, and practical patterns. This is vendor-neutral education to prepare you for production container deployments. No previous Kubernetes experience required.

graph TB    Problem["Container<br/>Orchestration<br/>Challenge"]    Problem -->|Solve| K8s["Kubernetes<br/>Cluster"]    K8s --> Control["Control Plane<br/>API Server<br/>Scheduler<br/>Controller Manager"]    K8s --> Worker["Worker Nodes<br/>kubelet<br/>Container Runtime<br/>kube-proxy"]    Control --> Pod["Manage Pods<br/>Deployments<br/>Services"]    Worker --> Pod    Pod --> App["Running<br/>Applications"]    style K8s fill:#fff9c4    style App fill:#c8e6c9

Table of Contents

  1. The Container Orchestration Problem
  2. What Kubernetes Is
  3. Core Concepts
  4. How kubectl Works
  5. YAML Manifests Explained
  6. Labels and Selectors
  7. Deployment Lifecycle
  8. Services and Networking
  9. ConfigMaps and Secrets
  10. Health Checks
  11. Resource Management
  12. Minimal Deployment Walkthrough
  13. Next Steps

The Container Orchestration Problem

Before Kubernetes existed, teams managing containers faced several fundamental challenges that forced them to build complex manual systems to maintain reliability and efficiency.

The first major problem was running many containers across many machines. Consider having 100 containerized microservices where each one needs 3-5 copies for reliability. That means 300-500 containers distributed across 10 or more servers. The question of which container goes on which machine becomes operationally complex: you need to decide this placement based on current resource availability, affinity requirements, and failure domains. You must handle machine failures gracefully, automatically rescheduling containers when a machine goes down. You must balance load across replicas to distribute incoming requests. The manual approach was to write scripts and manage spreadsheets, resulting in pages at 3 AM. Kubernetes changes this by allowing you to declare your desired state—"I want 5 copies of this service"—and Kubernetes maintains it automatically, moving containers around as needed to match your specification.

The second major problem was network communication between containers. Containers constantly come and go as they are created and destroyed. Service A needs to call Service B, but which IP address should it use? When Service B is restarted, it gets a new IP address, breaking hard-coded connections. Service A also needs to know all of Service B's replicas so it can distribute load across them. When a container dies, how does Service A know to stop sending traffic to it? The manual approach required service discovery tools, load balancers, and complex DNS configuration. Kubernetes addresses this with built-in service discovery and networking that automatically tracks which containers are available and distributes traffic accordingly.

The third problem was resource efficiency. Servers have finite resources (CPU, memory, storage), and you want to pack containers as densely as possible without oversubscribing. You need to prevent one resource-hungry container from starving other containers on the same machine. You must handle gracefully when you run out of capacity. The manual approach was capacity planning spreadsheets and manual tweaking. Kubernetes provides automatic bin-packing with resource constraints, automatically placing containers on the most suitable machines based on their resource requirements.

The fourth problem was updates without downtime. You need to roll out new versions of your services while keeping the system running, automatically roll back if something breaks, and do all this without users experiencing downtime. The manual approach involved blue-green deployments, manual coordination between teams, and error-prone scripts. Kubernetes provides built-in rolling updates that gradually replace old versions with new ones and automatic rollback capabilities if health checks fail.

What Kubernetes Is

Kubernetes (K8s) is an open-source container orchestration system that automates the complex tasks of deploying, managing, and scaling containerized applications. It handles deployment decisions about where and when containers should run across your cluster. It manages scaling, allowing you to specify how many copies of each service you want. It provides networking so containers can discover and communicate with each other. It handles storage, allowing containers to access persistent data even when they are recreated. It orchestrates updates, rolling out new versions safely with zero downtime. It provides self-healing capabilities, automatically restarting failed containers and removing dead nodes from the cluster.

Kubernetes is declarative in nature, which represents a fundamental shift in how infrastructure is managed. Rather than imperative procedures ("SSH into this server and start these containers"), you declare desired state ("I want 3 copies of this service with these resource limits running at all times"). Kubernetes continuously works to maintain that state, automatically adjusting to changes. This declarative approach is powerful because it means you can express intent once and Kubernetes figures out the implementation details.

Kubernetes is designed to be highly scalable, handling anything from dozens of containers in a development environment to thousands of containers in a massive production cluster. It is self-healing, automatically restarting failed containers and removing dead nodes from service, reducing operational burden. Kubernetes is cloud-agnostic, running on AWS, Google Cloud, Azure, or bare metal infrastructure. This portability prevents vendor lock-in. The Kubernetes ecosystem is open and vibrant, with thousands of vendors building tools on top of Kubernetes. You are not locked into proprietary solutions.

Core Concepts

1. Pods

A Pod is the smallest deployable unit in Kubernetes. Think of it as a wrapper around one or more containers. The key characteristic of a pod is that all containers within it share the same network namespace, meaning they share a single IP address and can communicate through localhost. Containers in a pod can share storage volumes, allowing them to read and write the same files. Pods always run together on the same machine—Kubernetes will never schedule different containers from the same pod on different nodes. Containers in a pod come and go together; when a pod terminates, all its containers are terminated.

In practice, most pods (approximately 95% of the time) contain a single container. Multi-container pods are used for tightly coupled helper containers called sidecars, which provide cross-cutting concerns like logging aggregation, monitoring, or service meshes. A pod is essentially the combination of one or more containers, a shared IP address, and shared storage volumes.

2. Deployments

A Deployment is a higher-level object that manages pods. While you could create pods directly, Deployments provide the orchestration layer that makes Kubernetes powerful. A Deployment allows you to specify how many replicas (copies) of a pod you want running. You specify which container image to use and how to update pods safely when you need to roll out new versions. Behind the scenes, Deployments create and manage ReplicaSets, which handle the actual management of creating and destroying pods to match the desired replica count. You rarely interact with ReplicaSets directly; Deployments are the abstraction you work with.

The relationship is clear: Deployment manages a ReplicaSet, and ReplicaSet manages Pods. An example Deployment might say "I want 3 copies of my nginx app running at all times." The Deployment ensures those 3 pods exist and recreates any that fail.

3. Services

A Service provides stable networking to pods. Services solve a critical problem: pods are ephemeral and get new IP addresses when they restart, making it impossible to maintain static connections. A Service provides a stable IP address and DNS name that routes traffic to the pods behind it. Services tell Kubernetes how to find pods (using labels as selectors), how to expose them (specifying port and protocol), and what load balancing strategy to use.

Services are how pods communicate with each other. Without Services, every pod would need to know the IP addresses of every other pod, and those addresses would change constantly. With Services, pods call stable service names and the Service automatically routes traffic to available pods.

Three main service types exist. ClusterIP is the default, providing internal communication only—pods can reach the service, but it is not accessible from outside the cluster. NodePort exposes the service on a specific port on every node in the cluster, allowing external access but at the cost of managing node IPs. LoadBalancer exposes the service via the cloud provider's load balancer (AWS ELB, Google Cloud Load Balancer, etc.), providing external access with automatic load balancing and a stable external IP.

4. Namespaces

A Namespace is a virtual cluster partition. It provides logical separation within a single physical cluster. Namespaces are useful for multi-tenancy, allowing different teams or projects to share a cluster without interfering with each other. They are useful for environment isolation, with separate namespaces for development, staging, and production. Namespaces provide name scoping, allowing the same application name to exist in different namespaces without conflict. Every Kubernetes object belongs to a namespace, and the default is default. When you create an object without specifying a namespace, it goes into the default namespace.

How kubectl Works

kubectl is the Kubernetes command-line tool. It communicates with the Kubernetes API server.

Two Approaches: Imperative vs Declarative

Imperative (Direct commands)

# Create a deployment directlykubectl create deployment nginx --image=nginx:alpine # Scale it upkubectl scale deployment nginx --replicas=3 # Update the imagekubectl set image deployment/nginx nginx=nginx:1.21

Pros: Quick for testing, immediate feedback Cons: Hard to reproduce, difficult to version, not idempotent

Declarative (YAML files)

# Describe state in YAMLcat > deployment.yaml << EOFapiVersion: apps/v1kind: Deploymentmetadata:  name: nginxspec:  replicas: 3  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:alpineEOF # Apply the desired statekubectl apply -f deployment.yaml # Update: Modify the file and apply againkubectl apply -f deployment.yaml

Pros: Reproducible, version-controllable, idempotent, auditable Cons: More typing, need to learn YAML

Best practice: Use declarative (YAML) for everything except quick testing.

Common kubectl Commands

# View cluster resourceskubectl get nodes              # List nodes (machines)kubectl get pods              # List Pods in current namespacekubectl get deployments       # List Deploymentskubectl get services          # List Serviceskubectl get all              # List all object types # Detailed informationkubectl describe pod nginx-abc123          # Details about a Podkubectl logs nginx-abc123                  # Container outputkubectl logs nginx-abc123 -f               # Follow logskubectl exec -it nginx-abc123 -- /bin/sh  # Shell into container # Modify resourceskubectl apply -f deployment.yaml    # Create or update from filekubectl delete pod nginx-abc123    # Delete a Podkubectl scale deployment nginx --replicas=5  # Scale up # Debuggingkubectl get events                           # See what happenedkubectl top nodes                            # CPU/memory usagekubectl top pods                             # Pod resource usagekubectl port-forward pod/nginx-abc123 8080:80  # Access container locally

YAML Manifests Explained

Kubernetes objects are defined in YAML files. All follow the same structure:

apiVersion: apps/v1          # API version (changes per object type)kind: Deployment             # Object typemetadata:                    # Object identity  name: my-app              # Name (unique in namespace)  namespace: default        # Namespace (optional, defaults to "default")  labels:                   # Key-value tags for organization    app: my-appspec:                        # Desired state (object-type-specific)  replicas: 3  selector:    matchLabels:      app: my-app  template:    metadata:      labels:        app: my-app    spec:      containers:      - name: my-app        image: my-app:1.0        ports:        - containerPort: 8080

The Pattern

Every manifest has these four sections:

1. apiVersion: Specifies which version of the Kubernetes API to use. Different object types use different versions, and you can discover which version applies to each type by running kubectl api-resources.

2. kind: Describes what type of object you're creating. Common kinds include Pod, Deployment, Service, ConfigMap, and Secret.

3. metadata: Contains object identity information, including the unique name in the namespace, the namespace itself (which is optional and defaults to "default"), and labels, which are key-value pairs used for grouping and selection.

4. spec: Defines the actual desired state and varies significantly by object type. For example, a Deployment.spec looks very different from a Service.spec.

Example Manifests

Pod (rarely created directly; use Deployments instead)

apiVersion: v1kind: Podmetadata:  name: nginx-podspec:  containers:  - name: nginx    image: nginx:alpine    ports:    - containerPort: 80

Deployment (most common way to run containers)

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx  labels:    app: nginxspec:  replicas: 3  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:alpine        ports:        - containerPort: 80

Service (expose Pods for communication)

apiVersion: v1kind: Servicemetadata:  name: nginxspec:  type: ClusterIP  ports:  - port: 80    targetPort: 80  selector:    app: nginx

Labels and Selectors

Labels are key-value pairs attached to objects. They're used to organize, group, and select objects.

Why Labels?

Without labels, you have no way to group related objects:

# Without labels: you can't easily ask "which Pods belong to my app?"kubectl get pods# Just a list, no way to filter # With labels: you can select by matching criteriakubectl get pods -l app=my-app

Naming Convention

labels:  app: my-app              # What application  version: 1.0             # Version  tier: frontend           # Layer (frontend, backend, db)  environment: production  # Environment  team: platform           # Owning team

Using Selectors

# Select by exact matchkubectl get pods -l app=my-app # Select with conditionskubectl get pods -l "app=my-app,tier=frontend"kubectl get pods -l "app in (app-a, app-b)"kubectl get pods -l "app!=my-app" # Delete all Pods for an appkubectl delete pods -l app=my-app

Labels in Deployments

The Deployment's selector must match the Pod labels:

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginxspec:  replicas: 3  selector:    matchLabels:      app: nginx         # ← Deployment looks for Pods with this label  template:    metadata:      labels:        app: nginx       # ← Pod gets this label    spec:      containers:      - name: nginx        image: nginx:alpine

Important: The selector (app: nginx) must match the Pod template labels.

Deployment Lifecycle

Here's what happens when you deploy an application:

1. Create: You apply the Deployment manifest

kubectl apply -f deployment.yaml

2. Deployment Controller: Creates a ReplicaSet

The Deployment controller watches the Deployment and creates a ReplicaSet that matches the spec.

ReplicaSet: nginx-7d8f4c7f9b  replicas: 3  selector: app=nginx

3. ReplicaSet Controller: Creates Pods

The ReplicaSet controller creates the desired number of Pods.

Pod: nginx-7d8f4c7f9b-abc12Pod: nginx-7d8f4c7f9b-def45Pod: nginx-7d8f4c7f9b-ghi89

4. Scheduler: Places Pods on Nodes

The Scheduler looks at available nodes and places each Pod where there are resources.

node-1: [nginx-abc12] [nginx-def45]node-2: [nginx-ghi89]

5. Kubelet: Starts Containers

On each node, the Kubelet pulls the image and starts the container.

6. Self-healing: Monitoring

If a Pod dies, the ReplicaSet automatically creates a replacement:

Pod: nginx-7d8f4c7f9b-abc12 ← CRASHReplicaSet sees mismatch (wants 3, has 2)Creates: nginx-7d8f4c7f9b-xyz99

Rolling Updates

When you change the image, Kubernetes updates Pods one at a time:

# Update imagekubectl set image deployment/nginx nginx=nginx:1.21 # What happens:# 1. Create a new ReplicaSet with nginx:1.21# 2. Scale old ReplicaSet down: 3 → 2 → 1 → 0# 3. Scale new ReplicaSet up: 1 → 2 → 3# Result: Zero downtime, old version still running if needed for quick rollback

Rollback

If the new version is broken:

# Manual rollback:kubectl rollout history deployment/nginx          # See revisionskubectl rollout undo deployment/nginx             # Go back one versionkubectl rollout undo deployment/nginx --to-revision=2  # Go to specific version # Note: Kubernetes does not automatically roll back failed Deployments. Failed Pods# are marked unready and removed from Service endpoints, but the rollout pauses rather# than reversing. Use kubectl rollout undo for manual rollback, or tools like Helm with# --atomic for automated rollback.

Services and Networking

Pods are ephemeral. They come and go. Services provide stable networking.

The Problem Services Solve

Pod A wants to call Pod BPod A: "What's Pod B's IP?"Pod B: 10.2.3.4 [Pod B restarts] Pod A: "What's Pod B's IP?"Pod B: 10.2.3.5  ← Different IP!

Solution: Service acts as a stable proxy.

Pod A → Service (stable IP) → Pod B (any IP)Pod A → Service (stable IP) → Pod B (any IP, Pod restarted, new IP)

Service Types

ClusterIP (Default)

apiVersion: v1kind: Servicemetadata:  name: nginxspec:  type: ClusterIP      # Internal only  ports:  - port: 80           # Service port    targetPort: 8080   # Container port  selector:    app: nginx         # Route to Pods with this label

Usage: Internal communication only. Pods find each other via service name such as nginx.default.svc.cluster.local, which serves as the DNS name. This type is only accessible from within the cluster.

NodePort

apiVersion: v1kind: Servicemetadata:  name: nginxspec:  type: NodePort  ports:  - port: 80    targetPort: 8080    nodePort: 30080     # Port on every node (30000-32767)  selector:    app: nginx

Usage: External access to specific Pods, though this is not recommended for production since load balancing is not handled properly. Access is via the node IP and port, such as node-ip:30080, which opens port 30080 on every node.

LoadBalancer

apiVersion: v1kind: Servicemetadata:  name: nginxspec:  type: LoadBalancer   # Requires cloud provider support  ports:  - port: 80    targetPort: 8080  selector:    app: nginx

Usage: Production external access with full integration with cloud provider load balancers. AWS automatically creates an ELB while GCP creates a Cloud Load Balancer, the service is assigned an external IP, and traffic is automatically load balanced across all Pods.

How Services Route Traffic

  1. Service selector matches Pod labels
  2. Kubernetes discovers Pods with matching labels
  3. Kube-proxy (running on each node) sets up iptables rules
  4. Traffic to service IP is redirected to Pod IPs
  5. Load balancing happens via round-robin

Example:

Service: nginx (selector: app=nginx)Discovered Pods:  - Pod A: 10.2.3.4:8080  - Pod B: 10.2.3.5:8080  - Pod C: 10.2.3.6:8080 Request to Service: 10.0.0.50:80Gets round-robined to: 10.2.3.4:8080, 10.2.3.5:8080, 10.2.3.6:8080

ConfigMaps and Secrets

Applications need configuration. Kubernetes provides two objects:

ConfigMaps

For non-sensitive configuration data.

apiVersion: v1kind: ConfigMapmetadata:  name: app-configdata:  DATABASE_URL: "postgres://db:5432"  LOG_LEVEL: "info"  APP_MODE: "production"

Using in Deployments:

apiVersion: apps/v1kind: Deploymentmetadata:  name: my-appspec:  template:    spec:      containers:      - name: my-app        image: my-app:1.0        envFrom:        - configMapRef:            name: app-config    # Container gets env vars from ConfigMap

Result: Container has env vars: DATABASE_URL=postgres://db:5432, LOG_LEVEL=info, etc.

Secrets

For sensitive data (passwords, API keys, tokens).

apiVersion: v1kind: Secretmetadata:  name: db-credentialstype: OpaquestringData:  username: admin  password: super-secret-password

Using in Deployments:

apiVersion: apps/v1kind: Deploymentmetadata:  name: my-appspec:  template:    spec:      containers:      - name: my-app        image: my-app:1.0        env:        - name: DB_USERNAME          valueFrom:            secretKeyRef:              name: db-credentials              key: username        - name: DB_PASSWORD          valueFrom:            secretKeyRef:              name: db-credentials              key: password

Important: Secrets are base64-encoded, not encrypted by default. For production, use Secret encryption at rest.

Health Checks

Kubernetes can automatically restart or remove unhealthy containers using probes.

Three Types of Probes

Liveness Probe

Asks: "Is the container still running properly?" If not, restart it.

spec:  containers:  - name: app    livenessProbe:      httpGet:        path: /healthz        port: 8080      initialDelaySeconds: 30    # Wait 30 seconds before first check      periodSeconds: 10          # Check every 10 seconds      timeoutSeconds: 5          # Timeout after 5 seconds      failureThreshold: 3        # Restart after 3 failures

Readiness Probe

Asks: "Is the container ready to receive traffic?" If not, remove from Service.

spec:  containers:  - name: app    readinessProbe:      httpGet:        path: /ready        port: 8080      initialDelaySeconds: 10      periodSeconds: 5      failureThreshold: 2

Startup Probe

Asks: "Has the application started?" Used for slow-starting apps.

spec:  containers:  - name: app    startupProbe:      httpGet:        path: /startup        port: 8080      periodSeconds: 10      failureThreshold: 30       # 30 * 10 = 300 seconds max startup time

Probe Types

HTTP GET: Call a URL endpoint

httpGet:  path: /healthz  port: 8080

TCP Socket: Try to connect to a port

tcpSocket:  port: 8080

Exec: Run a command

exec:  command: ["pg_isready", "-h", "localhost"]

Resource Management

Kubernetes needs to know how much CPU and memory your containers use to schedule them efficiently.

Resource Requests and Limits

spec:  containers:  - name: app    image: my-app:1.0    resources:      requests:        cpu: 100m              # Minimum guaranteed CPU (millicores)        memory: 128Mi          # Minimum guaranteed memory      limits:        cpu: 500m              # Maximum CPU allowed        memory: 512Mi          # Maximum memory allowed

Requests: Minimum resource reservation. Kubernetes won't schedule a Pod if the node doesn't have enough free requests.

Limits: Maximum resource usage. Container is throttled (CPU) or killed (memory) if it exceeds limits.

Units

CPU is measured in millicores where 100m equals 0.1 CPU cores, 1 equals 1 full CPU core, and 2000m equals 2 cores.

Memory is measured in mebibytes and gibibytes, where 128Mi equals 128 mebibytes, 1Gi equals 1 gibibyte, and 512Mi equals 512 mebibytes.

Resource Quotas (Namespace-level)

Limit total resource usage per namespace:

apiVersion: v1kind: ResourceQuotametadata:  name: team-quota  namespace: team-aspec:  hard:    requests.cpu: "10"         # Max 10 cores total in team-a    requests.memory: "20Gi"    # Max 20GB total in team-a    limits.cpu: "20"    limits.memory: "40Gi"

Minimal Deployment Walkthrough

Let's deploy a real application: a simple nginx web server.

Step 1: Create the Deployment Manifest

cat > nginx-deployment.yaml << 'EOF'apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-demo  labels:    app: nginx-demospec:  replicas: 2  selector:    matchLabels:      app: nginx-demo  template:    metadata:      labels:        app: nginx-demo    spec:      containers:      - name: nginx        image: nginx:alpine        ports:        - containerPort: 80        resources:          requests:            cpu: 50m            memory: 64Mi          limits:            cpu: 100m            memory: 128Mi        livenessProbe:          httpGet:            path: /            port: 80          initialDelaySeconds: 30          periodSeconds: 10        readinessProbe:          httpGet:            path: /            port: 80          initialDelaySeconds: 5          periodSeconds: 5EOF

Step 2: Create the Service Manifest

cat > nginx-service.yaml << 'EOF'apiVersion: v1kind: Servicemetadata:  name: nginx-demo  labels:    app: nginx-demospec:  type: LoadBalancer  ports:  - port: 80    targetPort: 80    protocol: TCP  selector:    app: nginx-demoEOF

Step 3: Apply the Manifests

# Create the Deploymentkubectl apply -f nginx-deployment.yaml# Output: deployment.apps/nginx-demo created # Create the Servicekubectl apply -f nginx-service.yaml# Output: service/nginx-demo created

Step 4: Verify Deployment

# Check Deployment statuskubectl get deployments# NAME          READY   UP-TO-DATE   AVAILABLE# nginx-demo    2/2     2            2 # Check Podskubectl get pods# NAME                          READY   STATUS    RESTARTS# nginx-demo-7f6d4d8c9b-abc12   1/1     Running   0# nginx-demo-7f6d4d8c9b-def45   1/1     Running   0 # Check Servicekubectl get services# NAME         TYPE           CLUSTER-IP     EXTERNAL-IP# nginx-demo   LoadBalancer   10.0.0.50      35.201.123.45

Step 5: Access the Application

# Get the external IP (cloud-based) or use port-forward (local)kubectl port-forward svc/nginx-demo 8080:80# Forwarding from 127.0.0.1:8080 -> 80 # In another terminal:curl http://localhost:8080# Serves nginx default page

Step 6: Scale Up

# Increase replicas to 4kubectl scale deployment nginx-demo --replicas=4 # Verifykubectl get pods# Now shows 4 Pods

Step 7: Update the Image

# Update to nginx 1.21kubectl set image deployment/nginx-demo nginx=nginx:1.21 # Watch the rolling updatekubectl rollout status deployment/nginx-demo# deployment "nginx-demo" successfully rolled out

Step 8: Rollback (if something went wrong)

# Undo the last updatekubectl rollout undo deployment/nginx-demo # Verify back on nginx:alpinekubectl describe pod <pod-name>

Step 9: Cleanup

# Delete everythingkubectl delete -f nginx-deployment.yaml -f nginx-service.yaml# Or delete by labelkubectl delete deployment,service -l app=nginx-demo

Common Patterns

Sidecar Pattern

Extra container in the same Pod for cross-cutting concerns:

spec:  containers:  - name: app    image: my-app:1.0  - name: logging-sidecar    image: fluent-bit:latest    # Ships logs to external service

Init Containers

Run setup tasks before main container starts:

spec:  initContainers:  - name: wait-for-db    image: busybox:1.28    command: ['sh', '-c', 'until wget -O- http://db:5432; do echo waiting; sleep 2; done']  containers:  - name: app    image: my-app:1.0

DaemonSets

Run a Pod on every node (monitoring, logging):

apiVersion: apps/v1kind: DaemonSetmetadata:  name: node-monitorspec:  selector:    matchLabels:      app: node-monitor  template:    metadata:      labels:        app: node-monitor    spec:      containers:      - name: monitor        image: node-monitor:1.0

Next Steps

Now that you understand Kubernetes fundamentals, you're ready for:

  1. Helm package manager — Simplify complex deployments (see helm-fundamentals.md)
  2. Cluster networking — Service mesh, network policies
  3. Storage — Persistent volumes, databases
  4. Security — RBAC, network policies, pod security
  5. Advanced features — StatefulSets, Jobs, CronJobs

And most importantly: Apply these principles to your workloads — Build secure container manifests following best practices in the container security fundamentals.

Quick Reference

kubectl Cheat Sheet

# Cluster infokubectl cluster-infokubectl get nodes # Deploymentskubectl create deployment NAME --image=IMAGEkubectl get deploymentskubectl scale deployment NAME --replicas=Nkubectl rollout history deployment NAMEkubectl rollout undo deployment NAME # Podskubectl get podskubectl describe pod POD_NAMEkubectl logs POD_NAMEkubectl exec -it POD_NAME -- /bin/shkubectl delete pod POD_NAME # Serviceskubectl expose deployment NAME --type=LoadBalancer --port=8080 # YAMLkubectl apply -f manifest.yamlkubectl delete -f manifest.yamlkubectl explain Deployment.spec # Debuggingkubectl get eventskubectl top nodeskubectl port-forward svc/NAME 8080:80

YAML Template

apiVersion: apps/v1kind: Deploymentmetadata:  name: my-app  namespace: default  labels:    app: my-appspec:  replicas: 3  selector:    matchLabels:      app: my-app  template:    metadata:      labels:        app: my-app    spec:      containers:      - name: my-app        image: my-app:1.0        ports:        - containerPort: 8080        resources:          requests:            cpu: 100m            memory: 128Mi          limits:            cpu: 500m            memory: 512Mi        livenessProbe:          httpGet:            path: /healthz            port: 8080          periodSeconds: 10        readinessProbe:          httpGet:            path: /ready            port: 8080          periodSeconds: 5        env:        - name: LOG_LEVEL          value: "info"

Next Steps: Operate Kubernetes Securely

Deploy containers to Kubernetes — Practical deployment guides including End-to-End Secure Deployment for deploying with security checks, Getting Started guides for Python/Node.js/Go/Java with language-specific Kubernetes guidance, and Helm Charts & Kubernetes resources for using Helm to manage deployments.

Security in Kubernetes — Secure your clusters with Container Security Best Practices that cover security for every container, Read-Only Filesystem guidance to make filesystems immutable, Network Policies to control pod communication, and Secret Management for secure credential handling.

Operations at scale — Managing Kubernetes production systems through guides on Upgrade & Patching to keep images patched, Multi-Cloud Registries for managing containers across multiple cloud platforms, and Disaster Recovery planning to protect your supply chain.

Resources

For further learning, consult the Official Kubernetes Documentation at https://kubernetes.io/docs/, the Interactive Tutorial at https://kubernetes.io/docs/tutorials/, the kubectl Reference at https://kubernetes.io/docs/reference/kubectl/, and the Kubernetes API Reference at https://kubernetes.io/docs/reference/kubernetes-api/.

Learn Kubernetes at your pace. Start with this guide, try the minimal example, then explore official documentation for deeper dives into specific topics.