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:#c8e6c9Table of Contents
- The Container Orchestration Problem
- What Kubernetes Is
- Core Concepts
- How kubectl Works
- YAML Manifests Explained
- Labels and Selectors
- Deployment Lifecycle
- Services and Networking
- ConfigMaps and Secrets
- Health Checks
- Resource Management
- Minimal Deployment Walkthrough
- 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.21Pros: 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.yamlPros: 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 locallyYAML 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: 8080The 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: 80Deployment (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: 80Service (expose Pods for communication)
apiVersion: v1kind: Servicemetadata: name: nginxspec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: app: nginxLabels 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-appNaming Convention
labels: app: my-app # What application version: 1.0 # Version tier: frontend # Layer (frontend, backend, db) environment: production # Environment team: platform # Owning teamUsing 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-appLabels 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:alpineImportant: 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.yaml2. 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=nginx3. ReplicaSet Controller: Creates Pods
The ReplicaSet controller creates the desired number of Pods.
Pod: nginx-7d8f4c7f9b-abc12Pod: nginx-7d8f4c7f9b-def45Pod: nginx-7d8f4c7f9b-ghi894. 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-xyz99Rolling 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 rollbackRollback
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 labelUsage: 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: nginxUsage: 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: nginxUsage: 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
- Service selector matches Pod labels
- Kubernetes discovers Pods with matching labels
- Kube-proxy (running on each node) sets up iptables rules
- Traffic to service IP is redirected to Pod IPs
- 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:8080ConfigMaps 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 ConfigMapResult: 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-passwordUsing 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: passwordImportant: 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 failuresReadiness 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: 2Startup 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 timeProbe Types
HTTP GET: Call a URL endpoint
httpGet: path: /healthz port: 8080TCP Socket: Try to connect to a port
tcpSocket: port: 8080Exec: 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 allowedRequests: 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: 5EOFStep 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-demoEOFStep 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 createdStep 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.45Step 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 pageStep 6: Scale Up
# Increase replicas to 4kubectl scale deployment nginx-demo --replicas=4 # Verifykubectl get pods# Now shows 4 PodsStep 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 outStep 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-demoCommon 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 serviceInit 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.0DaemonSets
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.0Next Steps
Now that you understand Kubernetes fundamentals, you're ready for:
- Helm package manager — Simplify complex deployments (see
helm-fundamentals.md) - Cluster networking — Service mesh, network policies
- Storage — Persistent volumes, databases
- Security — RBAC, network policies, pod security
- 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:80YAML 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.
