0% found this document useful (0 votes)
4 views59 pages

Kuber Net Es

The document provides comprehensive lecture notes on Kubernetes, covering its introduction, architecture, core components, and key concepts such as Pods, ReplicaSets, and Deployments. It details the functionalities of Kubernetes, including automated rollouts, self-healing, and storage orchestration, along with essential commands for managing resources. The notes also include specifications for creating and managing various Kubernetes objects, making it a valuable resource for beginners to advanced users.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views59 pages

Kuber Net Es

The document provides comprehensive lecture notes on Kubernetes, covering its introduction, architecture, core components, and key concepts such as Pods, ReplicaSets, and Deployments. It details the functionalities of Kubernetes, including automated rollouts, self-healing, and storage orchestration, along with essential commands for managing resources. The notes also include specifications for creating and managing various Kubernetes objects, making it a valuable resource for beginners to advanced users.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Kubernetes: Beginner to Pro - Complete Lecture Notes

Table of Contents
1.​ Introduction to Kubernetes
2.​ Architecture and Core Components
3.​ Pods
4.​ ReplicaSets
5.​ Deployments
6.​ Services
7.​ Namespaces
8.​ Networking: Ingress & Egress
9.​ ConfigMaps & Secrets
10.​ Storage
11.​ Setting Up a Three-Node Cluster

1. Introduction to Kubernetes
What is Kubernetes?
Kubernetes (K8s) is an open-source container orchestration platform that automates the
deployment, scaling, and management of containerized applications.

Key Benefits
●​ Automated Rollouts & Rollbacks: Deploy changes safely
●​ Self-Healing: Restarts failed containers automatically
●​ Horizontal Scaling: Scale applications up/down based on demand
●​ Service Discovery & Load Balancing: Automatic DNS and load balancing
●​ Storage Orchestration: Mount storage systems automatically
●​ Secret & Configuration Management: Manage sensitive data securely

Core Concepts
●​ Cluster: A set of nodes running containerized applications
●​ Node: A worker machine (VM or physical) in Kubernetes
●​ Control Plane: Manages the cluster state
●​ Workload: Application running on Kubernetes

Essential Commands to Start


# Check kubectl version​
kubectl version --client​

# View cluster info​
kubectl cluster-info​

# Get all resources​
kubectl get all​

# Get nodes in cluster​
kubectl get nodes​

# Describe a resource​
kubectl describe node <node-name>

2. Architecture and Core Components


Architecture Overview
Kubernetes follows a master-worker architecture with a Control Plane managing multiple
Worker Nodes.

Control Plane Components

1. API Server (kube-apiserver)


●​ Frontend for Kubernetes control plane
●​ Exposes Kubernetes API
●​ All communications go through API server
●​ RESTful interface for cluster management

2. etcd
●​ Consistent and highly-available key-value store
●​ Stores all cluster data (configuration, state, metadata)
●​ Source of truth for cluster state
●​ Distributed and replicated

3. Scheduler (kube-scheduler)
●​ Watches for newly created Pods with no assigned node
●​ Selects optimal node based on:
−​ Resource requirements
−​ Hardware/software constraints
−​ Affinity/anti-affinity specifications
−​ Data locality

4. Controller Manager (kube-controller-manager)


Runs controller processes: - Node Controller: Monitors node health - Replication
Controller: Maintains correct number of pods - Endpoints Controller: Populates
Endpoints object - Service Account Controller: Creates default accounts
5. Cloud Controller Manager
●​ Links cluster with cloud provider API
●​ Manages cloud-specific resources

Worker Node Components

1. Kubelet
●​ Agent running on each node
●​ Ensures containers are running in Pods
●​ Takes PodSpecs from API server
●​ Reports node and Pod status back
●​ Manages container lifecycle

2. Kube-proxy
●​ Network proxy on each node
●​ Maintains network rules for Pod communication
●​ Handles service abstraction and load balancing
●​ Implements Kubernetes Service concept

3. Container Runtime
●​ Software responsible for running containers
●​ Examples: Docker, containerd, CRI-O
●​ Must implement Kubernetes CRI (Container Runtime Interface)

Key Commands
# Get component status​
kubectl get componentstatuses​

# View API server​
kubectl get pods -n kube-system | grep apiserver​

# View etcd​
kubectl get pods -n kube-system | grep etcd​

# View scheduler​
kubectl get pods -n kube-system | grep scheduler​

# View controller manager​
kubectl get pods -n kube-system | grep controller​

# Check kubelet status (on node)​
systemctl status kubelet​

# View kube-proxy​
kubectl get pods -n kube-system | grep kube-proxy
3. Pods
What is a Pod?
●​ Smallest deployable unit in Kubernetes
●​ Encapsulates one or more containers
●​ Shares network namespace (same IP, port space)
●​ Shares storage volumes
●​ Ephemeral by nature

Pod Lifecycle Phases


1.​ Pending: Pod accepted but not yet running
2.​ Running: Pod bound to node, containers created
3.​ Succeeded: All containers terminated successfully
4.​ Failed: All containers terminated, at least one failed
5.​ Unknown: State cannot be determined

Important Pod Spec Fields


apiVersion: v1​
kind: Pod​
metadata:​
name: my-pod​
labels:​
app: myapp​
tier: frontend​
annotations:​
description: "My application pod"​
spec:​
# Container specifications​
containers:​
- name: nginx-container​
image: nginx:1.21​
ports:​
- containerPort: 80​
name: http​
protocol: TCP​

# Resource requests and limits​
resources:​
requests:​
memory: "64Mi"​
cpu: "250m"​
limits:​
memory: "128Mi"​
cpu: "500m"​

# Environment variables​
env:​
- name: ENV_VAR​
value: "production"​
- name: SECRET_KEY​
valueFrom:​
secretKeyRef:​
name: my-secret​
key: password​

# Volume mounts​
volumeMounts:​
- name: data-volume​
mountPath: /data​

# Liveness probe​
livenessProbe:​
httpGet:​
path: /healthz​
port: 80​
initialDelaySeconds: 3​
periodSeconds: 3​

# Readiness probe​
readinessProbe:​
httpGet:​
path: /ready​
port: 80​
initialDelaySeconds: 5​
periodSeconds: 5​

# Init containers (run before main containers)​
initContainers:​
- name: init-myservice​
image: busybox​
command: ['sh', '-c', 'until nslookup myservice; do sleep 2; done']​

# Volumes​
volumes:​
- name: data-volume​
emptyDir: {}​

# Restart policy​
restartPolicy: Always # Always, OnFailure, Never​

# Node selection​
nodeSelector:​
disktype: ssd​

# Service account​
serviceAccountName: my-service-account​

# DNS policy​
dnsPolicy: ClusterFirst​

# Host network​
hostNetwork: false

Essential Pod Commands


# Create pod from YAML​
kubectl apply -f [Link]​
kubectl create -f [Link]​

# Create pod imperatively​
kubectl run nginx --image=nginx --port=80​

# List pods​
kubectl get pods​
kubectl get pods -o wide # More details​
kubectl get pods --all-namespaces​
kubectl get pods -n <namespace>​

# Describe pod​
kubectl describe pod <pod-name>​

# Get pod YAML​
kubectl get pod <pod-name> -o yaml​
kubectl get pod <pod-name> -o json​

# Execute command in pod​
kubectl exec <pod-name> -- <command>​
kubectl exec -it <pod-name> -- /bin/bash​

# Execute in specific container (multi-container pod)​
kubectl exec -it <pod-name> -c <container-name> -- /bin/bash​

# View logs​
kubectl logs <pod-name>​
kubectl logs <pod-name> -c <container-name> # Specific container​
kubectl logs <pod-name> --previous # Previous instance logs​
kubectl logs <pod-name> -f # Follow logs​
kubectl logs <pod-name> --tail=50 # Last 50 lines​

# Port forwarding​
kubectl port-forward <pod-name> 8080:80​

# Copy files to/from pod​
kubectl cp <pod-name>:/path/to/file ./local-file​
kubectl cp ./local-file <pod-name>:/path/to/file​

# Delete pod​
kubectl delete pod <pod-name>​
kubectl delete pod <pod-name> --grace-period=0 --force # Force delete​
kubectl delete -f [Link]​

# Edit pod​
kubectl edit pod <pod-name>​

# Get pod events​
kubectl get events --field-selector [Link]=<pod-name>​

# Top (resource usage)​
kubectl top pod <pod-name>

Multi-Container Pod Patterns

1. Sidecar Pattern
spec:​
containers:​
- name: main-app​
image: myapp:1.0​
- name: log-agent​
image: fluentd​
# Shares volumes with main container

2. Ambassador Pattern
spec:​
containers:​
- name: main-app​
image: myapp:1.0​
- name: ambassador​
image: proxy:1.0​
# Proxies connections

3. Adapter Pattern
spec:​
containers:​
- name: main-app​
image: myapp:1.0​
- name: adapter​
image: adapter:1.0​
# Standardizes output

4. ReplicaSets
What is a ReplicaSet?
●​ Maintains a stable set of replica Pods
●​ Ensures specified number of pod replicas are running
●​ Replaces failed pods automatically
●​ Usually managed by Deployments

ReplicaSet Spec
apiVersion: apps/v1​
kind: ReplicaSet​
metadata:​
name: frontend-rs​
labels:​
app: frontend​
spec:​
# Number of replicas​
replicas: 3​

# Selector matches pod labels​
selector:​
matchLabels:​
app: frontend​
tier: web​
# Advanced matching​
matchExpressions:​
- key: environment​
operator: In # In, NotIn, Exists, DoesNotExist​
values:​
- production​
- staging​

# Pod template​
template:​
metadata:​
labels:​
app: frontend​
tier: web​
environment: production​
spec:​
containers:​
- name: nginx​
image: nginx:1.21​
ports:​
- containerPort: 80​
resources:​
requests:​
cpu: "100m"​
memory: "128Mi"​
limits:​
cpu: "200m"​
memory: "256Mi"
Important ReplicaSet Fields
●​ replicas: Desired number of pods
●​ selector: How to identify pods to manage
−​ matchLabels: Simple equality-based selection
−​ matchExpressions: Set-based selection (more flexible)
●​ template: Pod template for creating pods
−​ Must match selector labels
−​ Defines pod specifications

ReplicaSet Commands
# Create ReplicaSet​
kubectl apply -f [Link]​
kubectl create -f [Link]​

# List ReplicaSets​
kubectl get rs​
kubectl get replicasets​
kubectl get rs -o wide​

# Describe ReplicaSet​
kubectl describe rs <rs-name>​

# Get ReplicaSet YAML​
kubectl get rs <rs-name> -o yaml​

# Scale ReplicaSet​
kubectl scale rs <rs-name> --replicas=5​
kubectl scale --replicas=5 -f [Link]​

# Edit ReplicaSet​
kubectl edit rs <rs-name>​

# Delete ReplicaSet​
kubectl delete rs <rs-name>​
kubectl delete rs <rs-name> --cascade=false # Keep pods​

# View ReplicaSet events​
kubectl describe rs <rs-name> | grep Events -A 10​

# Auto-scale (HPA must be configured)​
kubectl autoscale rs <rs-name> --min=2 --max=10 --cpu-percent=80

How ReplicaSets Work


1.​ Label Selection: ReplicaSet continuously monitors pods matching its selector
2.​ Reconciliation Loop: Compares desired vs actual state
3.​ Pod Creation: Creates pods if count < replicas
4.​ Pod Deletion: Deletes pods if count > replicas
5.​ Pod Adoption: Can adopt existing pods with matching labels

Key Behaviors
# If you delete a pod managed by ReplicaSet​
kubectl delete pod <pod-name>​
# ReplicaSet immediately creates a new pod​

# Changing pod labels removes it from ReplicaSet​
kubectl label pod <pod-name> app=other --overwrite​
# ReplicaSet creates replacement pod​

# Scaling triggers immediate action​
kubectl scale rs <rs-name> --replicas=10​
# ReplicaSet creates 7 new pods (if previously 3)

5. Deployments
What is a Deployment?
●​ Higher-level abstraction over ReplicaSets
●​ Provides declarative updates for Pods and ReplicaSets
●​ Enables rolling updates and rollbacks
●​ Most common way to deploy applications

Deployment Spec
apiVersion: apps/v1​
kind: Deployment​
metadata:​
name: nginx-deployment​
labels:​
app: nginx​
annotations:​
[Link]/change-cause: "Initial deployment"​
spec:​
# Number of replicas​
replicas: 3​

# Selector for pods​
selector:​
matchLabels:​
app: nginx​

# Update strategy​
strategy:​
type: RollingUpdate # RollingUpdate or Recreate​
rollingUpdate:​
maxSurge: 1 # Max pods above desired during update​
maxUnavailable: 1 # Max pods unavailable during update​

# Minimum time pod should be ready​
minReadySeconds: 5​

# Revision history limit​
revisionHistoryLimit: 10​

# Progress deadline​
progressDeadlineSeconds: 600​

# Pod template​
template:​
metadata:​
labels:​
app: nginx​
version: v1​
spec:​
containers:​
- name: nginx​
image: nginx:1.21​
ports:​
- containerPort: 80​
resources:​
requests:​
cpu: "100m"​
memory: "128Mi"​
limits:​
cpu: "500m"​
memory: "256Mi"​
livenessProbe:​
httpGet:​
path: /​
port: 80​
initialDelaySeconds: 30​
periodSeconds: 10​
readinessProbe:​
httpGet:​
path: /​
port: 80​
initialDelaySeconds: 5​
periodSeconds: 5

Deployment Strategies

1. Rolling Update (Default)


strategy:​
type: RollingUpdate​
rollingUpdate:​
maxSurge: 25% # Can be percentage or number​
maxUnavailable: 25%
●​ Gradually replaces old pods with new ones
●​ Zero downtime
●​ Can control update speed

2. Recreate
strategy:​
type: Recreate

●​ Kills all existing pods before creating new ones


●​ Causes downtime
●​ Useful when running multiple versions simultaneously causes issues

Essential Deployment Commands


# Create deployment​
kubectl apply -f [Link]​
kubectl create deployment nginx --image=nginx:1.21 --replicas=3​

# List deployments​
kubectl get deployments​
kubectl get deploy -o wide​

# Describe deployment​
kubectl describe deployment <deploy-name>​

# Get deployment YAML​
kubectl get deployment <deploy-name> -o yaml​

# Scale deployment​
kubectl scale deployment <deploy-name> --replicas=5​

# Update deployment image​
kubectl set image deployment/<deploy-name> nginx=nginx:1.22​
kubectl set image deployment/<deploy-name> container-name=new-image:tag​

# Edit deployment​
kubectl edit deployment <deploy-name>​

# Rollout status​
kubectl rollout status deployment/<deploy-name>​

# Rollout history​
kubectl rollout history deployment/<deploy-name>​
kubectl rollout history deployment/<deploy-name> --revision=2​

# Rollback to previous version​
kubectl rollout undo deployment/<deploy-name>​

# Rollback to specific revision​
kubectl rollout undo deployment/<deploy-name> --to-revision=2​

# Pause rollout​
kubectl rollout pause deployment/<deploy-name>​

# Resume rollout​
kubectl rollout resume deployment/<deploy-name>​

# Restart deployment (recreate pods)​
kubectl rollout restart deployment/<deploy-name>​

# Delete deployment​
kubectl delete deployment <deploy-name>​

# Autoscale deployment​
kubectl autoscale deployment <deploy-name> --min=2 --max=10 --cpu-percent=80​

# View deployment events​
kubectl describe deployment <deploy-name> | grep Events -A 10

Update Workflow
# 1. Create deployment​
kubectl apply -f [Link] --record​

# 2. Update image​
kubectl set image deployment/nginx-deployment nginx=nginx:1.22 --record​

# 3. Monitor rollout​
kubectl rollout status deployment/nginx-deployment​

# 4. Check history​
kubectl rollout history deployment/nginx-deployment​

# 5. If issues, rollback​
kubectl rollout undo deployment/nginx-deployment​

# 6. Verify rollback​
kubectl rollout status deployment/nginx-deployment

Important Deployment Behaviors


Deployment Creates ReplicaSet:
kubectl get rs​
# Shows multiple ReplicaSets (one per revision)​
# Only one ReplicaSet has desired replicas > 0

Progressive Rollout:
# During update, you'll see:​
kubectl get pods​
# Some pods with old version, some with new​
# Gradually shifts from old to new

Rollback Mechanism: - Deployment keeps old ReplicaSets (limited by


revisionHistoryLimit) - Rollback reactivates old ReplicaSet - Fast and reliable

Best Practices
# Always set resource limits​
resources:​
requests:​
cpu: "100m"​
memory: "128Mi"​
limits:​
cpu: "500m"​
memory: "256Mi"​

# Use readiness probes​
readinessProbe:​
httpGet:​
path: /ready​
port: 80​
initialDelaySeconds: 5​
periodSeconds: 5​

# Use liveness probes​
livenessProbe:​
httpGet:​
path: /health​
port: 80​
initialDelaySeconds: 30​
periodSeconds: 10​

# Set appropriate strategy​
strategy:​
type: RollingUpdate​
rollingUpdate:​
maxSurge: 1​
maxUnavailable: 0 # Zero downtime

6. Services
What is a Service?
●​ Stable network endpoint for a set of Pods
●​ Provides load balancing across Pods
●​ Enables service discovery
●​ Decouples frontend from backend

Service Types

1. ClusterIP (Default)
●​ Internal cluster IP
●​ Only accessible within cluster
●​ Most common type
apiVersion: v1​
kind: Service​
metadata:​
name: my-service​
spec:​
type: ClusterIP​
selector:​
app: myapp​
ports:​
- protocol: TCP​
port: 80 # Service port​
targetPort: 8080 # Container port

2. NodePort
●​ Exposes service on each node’s IP at a static port
●​ Accessible from outside cluster
●​ Port range: 30000-32767
apiVersion: v1​
kind: Service​
metadata:​
name: my-nodeport-service​
spec:​
type: NodePort​
selector:​
app: myapp​
ports:​
- protocol: TCP​
port: 80​
targetPort: 8080​
nodePort: 30080 # Optional, auto-assigned if omitted

3. LoadBalancer
●​ Creates external load balancer (cloud provider)
●​ Assigns external IP
●​ Routes traffic to NodePort and ClusterIP
apiVersion: v1​
kind: Service​
metadata:​
name: my-loadbalancer-service​
spec:​
type: LoadBalancer​
selector:​
app: myapp​
ports:​
- protocol: TCP​
port: 80​
targetPort: 8080​
loadBalancerIP: [Link] # Optional

4. ExternalName
●​ Maps service to DNS name
●​ No proxying, returns CNAME
apiVersion: v1​
kind: Service​
metadata:​
name: my-external-service​
spec:​
type: ExternalName​
externalName: [Link]

Complete Service Spec


apiVersion: v1​
kind: Service​
metadata:​
name: my-complete-service​
labels:​
app: myapp​
annotations:​
[Link]/aws-load-balancer-type: "nlb"​
spec:​
# Service type​
type: ClusterIP​

# Selector to match pods​
selector:​
app: myapp​
tier: backend​

# Ports configuration​
ports:​
- name: http​
protocol: TCP​
port: 80 # Service port (what clients connect to)​
targetPort: 8080 # Pod port (can be name or number)​
- name: https​
protocol: TCP​
port: 443​
targetPort: https-port​

# Session affinity​
sessionAffinity: ClientIP # None or ClientIP​
sessionAffinityConfig:​
clientIP:​
timeoutSeconds: 10800​

# Cluster IP (usually auto-assigned)​
clusterIP: [Link]​

# External IPs​
externalIPs:​
- [Link]​

# External traffic policy (for NodePort/LoadBalancer)​
externalTrafficPolicy: Local # Cluster or Local​

# Health check node port​
healthCheckNodePort: 30123​

# IP families​
ipFamilies:​
- IPv4​
ipFamilyPolicy: SingleStack # SingleStack, PreferDualStack,
RequireDualStack​

# Load balancer source ranges​
loadBalancerSourceRanges:​
- [Link]/8​

# Publish not ready addresses​
publishNotReadyAddresses: false

Service Discovery
Via DNS (Recommended):
# Within same namespace​
curl [Link]

# Cross-namespace​
curl [Link]

# Fully qualified​
curl [Link]

Via Environment Variables:


# Kubernetes injects these variables​
MY_SERVICE_SERVICE_HOST=[Link]​
MY_SERVICE_SERVICE_PORT=80
Service Commands
# Create service​
kubectl apply -f [Link]​
kubectl create service clusterip my-service --tcp=80:8080​

# Create NodePort service​
kubectl create service nodeport my-service --tcp=80:8080​

# Expose deployment as service​
kubectl expose deployment nginx --port=80 --target-port=8080 --type=ClusterIP​

# List services​
kubectl get services​
kubectl get svc​
kubectl get svc -o wide​

# Describe service​
kubectl describe service <service-name>​

# Get service YAML​
kubectl get service <service-name> -o yaml​

# Get service endpoints​
kubectl get endpoints <service-name>​
kubectl describe endpoints <service-name>​

# Edit service​
kubectl edit service <service-name>​

# Delete service​
kubectl delete service <service-name>​

# Port forward to service​
kubectl port-forward service/<service-name> 8080:80​

# Test service (from within cluster)​
kubectl run test --rm -it --image=busybox -- /bin/sh​
# Inside pod: wget -qO- [Link]

Headless Services
apiVersion: v1​
kind: Service​
metadata:​
name: headless-service​
spec:​
clusterIP: None # Makes it headless​
selector:​
app: myapp​
ports:​
- port: 80

●​ No cluster IP assigned
●​ DNS returns all pod IPs directly
●​ Used for StatefulSets and service discovery

Service with Endpoints (No Selector)


apiVersion: v1​
kind: Service​
metadata:​
name: external-service​
spec:​
ports:​
- protocol: TCP​
port: 80​
targetPort: 8080​
---​
apiVersion: v1​
kind: Endpoints​
metadata:​
name: external-service​
subsets:​
- addresses:​
- ip: [Link]​
- ip: [Link]​
ports:​
- port: 8080

Service Troubleshooting
# Check service​
kubectl get svc <service-name>​

# Check endpoints​
kubectl get endpoints <service-name>​
# If no endpoints, check pod labels and selector​

# Check if pods are ready​
kubectl get pods -l app=myapp​

# Test DNS resolution​
kubectl run test --rm -it --image=busybox -- nslookup my-service​

# Test connectivity​
kubectl run test --rm -it --image=busybox -- wget -qO- [Link]

# Check service logs​
kubectl logs -l app=myapp​

# Describe service for events​
kubectl describe service <service-name>

7. Namespaces
What is a Namespace?
●​ Virtual cluster within physical cluster
●​ Provides scope for names
●​ Resource isolation and organization
●​ Multi-tenancy support

Default Namespaces
# default: Default namespace for objects without namespace​
# kube-system: System components (DNS, dashboard, etc.)​
# kube-public: Publicly readable, mostly for cluster information​
# kube-node-lease: Node heartbeat information

Namespace Spec
apiVersion: v1​
kind: Namespace​
metadata:​
name: development​
labels:​
environment: dev​
team: backend​
annotations:​
description: "Development environment"

Namespace with Resource Quotas


apiVersion: v1​
kind: Namespace​
metadata:​
name: production​
---​
apiVersion: v1​
kind: ResourceQuota​
metadata:​
name: compute-quota​
namespace: production​
spec:​
hard:​
[Link]: "10"​
[Link]: 20Gi​
[Link]: "20"​
[Link]: 40Gi​
persistentvolumeclaims: "10"​
pods: "50"​
services: "20"​
[Link]: "2"​
---​
apiVersion: v1​
kind: LimitRange​
metadata:​
name: resource-limits​
namespace: production​
spec:​
limits:​
- max:​
cpu: "2"​
memory: 4Gi​
min:​
cpu: "100m"​
memory: 128Mi​
default:​
cpu: "500m"​
memory: 1Gi​
defaultRequest:​
cpu: "200m"​
memory: 512Mi​
type: Container​
- max:​
storage: 10Gi​
min:​
storage: 1Gi​
type: PersistentVolumeClaim

Namespace Commands
# Create namespace​
kubectl create namespace development​
kubectl apply -f [Link]​

# List namespaces​
kubectl get namespaces​
kubectl get ns​

# Describe namespace​
kubectl describe namespace development​

# Get namespace YAML​
kubectl get namespace development -o yaml​

# Delete namespace (deletes all resources in it)​
kubectl delete namespace development​

# Set default namespace for context​
kubectl config set-context --current --namespace=development​

# View current namespace​
kubectl config view --minify | grep namespace​

# Create resource in specific namespace​
kubectl apply -f [Link] -n development​
kubectl run nginx --image=nginx -n development​

# List resources in namespace​
kubectl get pods -n development​
kubectl get all -n development​

# List resources in all namespaces​
kubectl get pods --all-namespaces​
kubectl get pods -A​

# Switch between namespaces​
kubectl config set-context --current --namespace=production​

# View resource quotas​
kubectl get resourcequota -n production​
kubectl describe resourcequota compute-quota -n production​

# View limit ranges​
kubectl get limitrange -n production​
kubectl describe limitrange resource-limits -n production

Cross-Namespace Communication
DNS Format:
# Service in same namespace​
service-name​

# Service in different namespace​
[Link]-name​

# Fully qualified domain name​
[Link]

Example:
# Frontend pod accessing backend service in different namespace​
apiVersion: v1​
kind: Pod​
metadata:​
name: frontend​
namespace: web​
spec:​
containers:​
- name: app​
image: myapp​
env:​
- name: BACKEND_URL​
value: "[Link]

Namespace Best Practices


# Organize by environment​
namespaces:​
- development​
- staging​
- production​

# Or by team​
namespaces:​
- team-frontend​
- team-backend​
- team-data​

# Or by application​
namespaces:​
- app-ecommerce​
- app-analytics​
- app-billing

Network Policies with Namespaces


apiVersion: [Link]/v1​
kind: NetworkPolicy​
metadata:​
name: allow-from-frontend​
namespace: backend​
spec:​
podSelector:​
matchLabels:​
app: api​
policyTypes:​
- Ingress​
ingress:​
- from:​
- namespaceSelector:​
matchLabels:​
environment: production​
- podSelector:​
matchLabels:​
app: frontend​
ports:​
- protocol: TCP​
port: 8080
RBAC with Namespaces
# Role for namespace-specific permissions​
apiVersion: [Link]/v1​
kind: Role​
metadata:​
name: pod-reader​
namespace: development​
rules:​
- apiGroups: [""]​
resources: ["pods"]​
verbs: ["get", "list", "watch"]​
---​
# RoleBinding​
apiVersion: [Link]/v1​
kind: RoleBinding​
metadata:​
name: read-pods​
namespace: development​
subjects:​
- kind: User​
name: developer@[Link]​
apiGroup: [Link]​
roleRef:​
kind: Role​
name: pod-reader​
apiGroup: [Link]

8. Networking: Ingress & Egress


Kubernetes Network Model
Core Principles: 1. All pods can communicate with each other without NAT 2. All nodes can
communicate with all pods without NAT 3. Pod’s IP address is the same as seen by itself and
by others

Pod Networking
# Each pod gets unique IP​
kubectl get pods -o wide​

# Pods communicate directly using pod IPs​
# Example: curl [Link]

# Or using service DNS​
# Example: curl [Link]
Network Policies (Egress & Ingress)

Default Deny All


apiVersion: [Link]/v1​
kind: NetworkPolicy​
metadata:​
name: default-deny-all​
namespace: production​
spec:​
podSelector: {} # Applies to all pods​
policyTypes:​
- Ingress​
- Egress

Allow Specific Ingress


apiVersion: [Link]/v1​
kind: NetworkPolicy​
metadata:​
name: allow-frontend-ingress​
namespace: backend​
spec:​
podSelector:​
matchLabels:​
app: database​
policyTypes:​
- Ingress​
ingress:​
- from:​
# Allow from specific pods​
- podSelector:​
matchLabels:​
app: backend-api​
# Allow from specific namespaces​
- namespaceSelector:​
matchLabels:​
environment: production​
# Allow from specific IP blocks​
- ipBlock:​
cidr: [Link]/8​
except:​
- [Link]/24​
ports:​
- protocol: TCP​
port: 5432

Allow Specific Egress


apiVersion: [Link]/v1​
kind: NetworkPolicy​
metadata:​
name: allow-api-egress​
namespace: frontend​
spec:​
podSelector:​
matchLabels:​
app: web​
policyTypes:​
- Egress​
egress:​
# Allow DNS​
- to:​
- namespaceSelector:​
matchLabels:​
name: kube-system​
ports:​
- protocol: UDP​
port: 53​
# Allow to backend API​
- to:​
- podSelector:​
matchLabels:​
app: backend-api​
ports:​
- protocol: TCP​
port: 8080​
# Allow to external API​
- to:​
- ipBlock:​
cidr: [Link]/0​
except:​
- [Link]/8​
- [Link]/16​
ports:​
- protocol: TCP​
port: 443

Combined Ingress and Egress


apiVersion: [Link]/v1​
kind: NetworkPolicy​
metadata:​
name: api-network-policy​
namespace: application​
spec:​
podSelector:​
matchLabels:​
app: api​
tier: backend​
policyTypes:​
- Ingress​
- Egress​
ingress:​
- from:​
- podSelector:​
matchLabels:​
app: frontend​
- namespaceSelector:​
matchLabels:​
environment: production​
ports:​
- protocol: TCP​
port: 8080​
egress:​
- to:​
- podSelector:​
matchLabels:​
app: database​
ports:​
- protocol: TCP​
port: 5432​
- to:​
- namespaceSelector:​
matchLabels:​
name: kube-system​
podSelector:​
matchLabels:​
k8s-app: kube-dns​
ports:​
- protocol: UDP​
port: 53

Network Policy Commands


# Create network policy​
kubectl apply -f [Link]​

# List network policies​
kubectl get networkpolicies​
kubectl get netpol​

# Describe network policy​
kubectl describe networkpolicy <policy-name>​

# Get network policy YAML​
kubectl get networkpolicy <policy-name> -o yaml​

# Delete network policy​
kubectl delete networkpolicy <policy-name>​

# Test network connectivity (from within pod)​
kubectl exec -it <pod-name> -- curl [Link]

# Check if CNI plugin supports network policies​
# (Calico, Cilium, Weave Net support them; Flannel doesn't)​
kubectl get pods -n kube-system

Ingress

What is Ingress?
●​ API object managing external HTTP/HTTPS access to services
●​ Provides load balancing, SSL termination, name-based virtual hosting
●​ Requires Ingress Controller (nginx, traefik, haproxy, etc.)

Installing Ingress Controller (NGINX)


# Install NGINX Ingress Controller​
kubectl apply -f
[Link]
deploy/static/provider/cloud/[Link]​

# Verify installation​
kubectl get pods -n ingress-nginx​
kubectl get svc -n ingress-nginx​

# Wait for external IP (LoadBalancer)​
kubectl get svc ingress-nginx-controller -n ingress-nginx --watch

Basic Ingress
apiVersion: [Link]/v1​
kind: Ingress​
metadata:​
name: simple-ingress​
namespace: default​
annotations:​
[Link]/rewrite-target: /​
spec:​
ingressClassName: nginx​
rules:​
- host: [Link]​
http:​
paths:​
- path: /​
pathType: Prefix​
backend:​
service:​
name: my-service​
port:​
number: 80

Advanced Ingress with Multiple Paths


apiVersion: [Link]/v1​
kind: Ingress​
metadata:​
name: advanced-ingress​
annotations:​
[Link]/ssl-redirect: "true"​
[Link]/force-ssl-redirect: "true"​
[Link]/rewrite-target: /$2​
[Link]/cluster-issuer: "letsencrypt-prod"​
spec:​
ingressClassName: nginx​
tls:​
- hosts:​
- [Link]​
secretName: myapp-tls​
rules:​
- host: [Link]​
http:​
paths:​
- path: /api(/|$)(.*)​
pathType: Prefix​
backend:​
service:​
name: api-service​
port:​
number: 8080​
- path: /web(/|$)(.*)​
pathType: Prefix​
backend:​
service:​
name: web-service​
port:​
number: 3000​
- path: /​
pathType: Prefix​
backend:​
service:​
name: frontend-service​
port:​
number: 80

Name-Based Virtual Hosting


apiVersion: [Link]/v1​
kind: Ingress​
metadata:​
name: virtual-host-ingress​
spec:​
ingressClassName: nginx​
rules:​
- host: [Link]​
http:​
paths:​
- path: /​
pathType: Prefix​
backend:​
service:​
name: api-service​
port:​
number: 8080​
- host: [Link]​
http:​
paths:​
- path: /​
pathType: Prefix​
backend:​
service:​
name: web-service​
port:​
number: 80​
- host: [Link]​
http:​
paths:​
- path: /​
pathType: Prefix​
backend:​
service:​
name: admin-service​
port:​
number: 3000

Ingress with TLS


apiVersion: v1​
kind: Secret​
metadata:​
name: tls-secret​
namespace: default​
type: [Link]/tls​
data:​
[Link]: <base64-encoded-cert>​
[Link]: <base64-encoded-key>​
---​
apiVersion: [Link]/v1​
kind: Ingress​
metadata:​
name: tls-ingress​
spec:​
ingressClassName: nginx​
tls:​
- hosts:​
- [Link]​
secretName: tls-secret​
rules:​
- host: [Link]​
http:​
paths:​
- path: /​
pathType: Prefix​
backend:​
service:​
name: secure-service​
port:​
number: 443

Path Types
# Prefix: Matches based on URL path prefix split by /​
pathType: Prefix​
path: /api​
# Matches: /api, /api/, /api/users, /api/v1/users​

# Exact: Matches exact path (case-sensitive)​
pathType: Exact​
path: /api​
# Matches only: /api​

# ImplementationSpecific: Depends on IngressClass​
pathType: ImplementationSpecific

Ingress Commands
# Create ingress​
kubectl apply -f [Link]​

# List ingresses​
kubectl get ingress​
kubectl get ing​

# Describe ingress​
kubectl describe ingress <ingress-name>​

# Get ingress YAML​
kubectl get ingress <ingress-name> -o yaml​

# Get ingress with address​
kubectl get ingress -o wide​

# Edit ingress​
kubectl edit ingress <ingress-name>​

# Delete ingress​
kubectl delete ingress <ingress-name>​

# Check ingress controller logs​
kubectl logs -n ingress-nginx -l [Link]/name=ingress-nginx​

# Test ingress​
curl -H "Host: [Link]" [Link]

# Test with HTTPS​
curl -k [Link]

Ingress Annotations (NGINX)


metadata:​
annotations:​
# SSL redirect​
[Link]/ssl-redirect: "true"​

# Rewrite target​
[Link]/rewrite-target: /$2​

# Rate limiting​
[Link]/limit-rps: "10"​

# Connection limits​
[Link]/limit-connections: "10"​

# Timeouts​
[Link]/proxy-connect-timeout: "60"​
[Link]/proxy-send-timeout: "60"​
[Link]/proxy-read-timeout: "60"​

# CORS​
[Link]/enable-cors: "true"​
[Link]/cors-allow-methods: "GET, POST, PUT"​
[Link]/cors-allow-origin: "*"​

# Authentication​
[Link]/auth-type: basic​
[Link]/auth-secret: basic-auth​

# Whitelist source range​
[Link]/whitelist-source-range:
"[Link]/8,[Link]/16"​

# Backend protocol​
[Link]/backend-protocol: "HTTPS"​

# Custom error pages​
[Link]/custom-http-errors: "404,503"​
[Link]/default-backend: error-page-service
Service Mesh (Advanced Networking)
Popular Service Meshes: - Istio - Linkerd - Consul
Benefits: - Advanced traffic management - Security (mTLS) - Observability - Circuit
breaking - Retry logic

9. ConfigMaps & Secrets


ConfigMaps

What is a ConfigMap?
●​ Stores non-confidential configuration data
●​ Key-value pairs
●​ Decouples configuration from container images
●​ Can be consumed as environment variables, command-line arguments, or
configuration files

Creating ConfigMaps
From Literals:
kubectl create configmap app-config \​
--from-literal=DATABASE_URL=postgres://db:5432/mydb \​
--from-literal=CACHE_SIZE=1000 \​
--from-literal=LOG_LEVEL=debug

From Files:
# Single file​
kubectl create configmap nginx-config --from-file=[Link]​

# Multiple files​
kubectl create configmap app-configs --from-file=./config-dir/​

# Specific key name​
kubectl create configmap app-config --from-file=mykey=./[Link]

From Env File:


# [Link]​
DATABASE_URL=postgres://db:5432/mydb​
CACHE_SIZE=1000​
LOG_LEVEL=debug​

kubectl create configmap app-config --from-env-file=[Link]
ConfigMap YAML
apiVersion: v1​
kind: ConfigMap​
metadata:​
name: app-config​
namespace: default​
labels:​
app: myapp​
data:​
# Simple key-value​
DATABASE_URL: "postgres://db:5432/mydb"​
CACHE_SIZE: "1000"​
LOG_LEVEL: "debug"​

# Multi-line values​
[Link]: |​
[Link]=8080​
[Link]=[Link]​
[Link]=10​
[Link]=30​

# JSON configuration​
[Link]: |​
{​
"server": {​
"port": 8080,​
"host": "[Link]"​
},​
"database": {​
"url": "postgres://db:5432/mydb",​
"pool": 10​
}​
}​

# YAML configuration​
[Link]: |​
server:​
port: 8080​
host: [Link]​
database:​
url: postgres://db:5432/mydb​
pool: 10

Using ConfigMaps in Pods


As Environment Variables:
apiVersion: v1​
kind: Pod​
metadata:​
name: app-pod​
spec:​
containers:​
- name: app​
image: myapp:1.0​

# Single environment variable from ConfigMap​
env:​
- name: DATABASE_URL​
valueFrom:​
configMapKeyRef:​
name: app-config​
key: DATABASE_URL​
- name: LOG_LEVEL​
valueFrom:​
configMapKeyRef:​
name: app-config​
key: LOG_LEVEL​

# All keys as environment variables​
envFrom:​
- configMapRef:​
name: app-config​

# With prefix​
- prefix: APP_​
configMapRef:​
name: app-config

As Volume Mounts:
apiVersion: v1​
kind: Pod​
metadata:​
name: app-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
# Mount entire ConfigMap​
- name: config-volume​
mountPath: /etc/config​

# Mount specific key​
- name: nginx-config​
mountPath: /etc/nginx/[Link]​
subPath: [Link]​
readOnly: true​

volumes:​
- name: config-volume​
configMap:​
name: app-config​

- name: nginx-config​
configMap:​
name: nginx-config​
items:​
- key: [Link]​
path: [Link]

As Command Arguments:
apiVersion: v1​
kind: Pod​
metadata:​
name: app-pod​
spec:​
containers:​
- name: app​
image: myapp:1.0​
command: ["/app/[Link]"]​
args:​
- "--port=$(PORT)"​
- "--host=$(HOST)"​
env:​
- name: PORT​
valueFrom:​
configMapKeyRef:​
name: app-config​
key: [Link]​
- name: HOST​
valueFrom:​
configMapKeyRef:​
name: app-config​
key: [Link]

Secrets

What is a Secret?
●​ Stores sensitive data (passwords, tokens, keys)
●​ Base64 encoded (NOT encrypted by default)
●​ Should be encrypted at rest (enable encryption in etcd)
●​ More secure handling than ConfigMaps

Secret Types
# Opaque (default): Arbitrary user-defined data​
# [Link]/service-account-token: Service account token​
# [Link]/dockercfg: Serialized ~/.dockercfg​
# [Link]/dockerconfigjson: Serialized ~/.docker/[Link]​
# [Link]/basic-auth: Basic authentication​
# [Link]/ssh-auth: SSH authentication​
# [Link]/tls: TLS certificate and key​
# [Link]/token: Bootstrap token

Creating Secrets
From Literals:
kubectl create secret generic db-credentials \​
--from-literal=username=admin \​
--from-literal=password='S3cr3tP@ssw0rd!'

From Files:
# Create files​
echo -n 'admin' > [Link]​
echo -n 'S3cr3tP@ssw0rd!' > [Link]​

kubectl create secret generic db-credentials \​
--from-file=username=[Link] \​
--from-file=password=[Link]​

# Clean up​
rm [Link] [Link]

TLS Secret:
kubectl create secret tls tls-secret \​
--cert=path/to/[Link] \​
--key=path/to/[Link]

Docker Registry Secret:


kubectl create secret docker-registry regcred \​
--docker-server=[Link] \​
--docker-username=myuser \​
--docker-password=mypassword \​
--docker-email=user@[Link]

Generic from Env File:


# [Link]​
USERNAME=admin​
PASSWORD=S3cr3tP@ssw0rd!​

kubectl create secret generic app-secrets --from-env-file=[Link]

Secret YAML
apiVersion: v1​
kind: Secret​
metadata:​
name: db-credentials​
namespace: default​
type: Opaque​
data:​
# Base64 encoded values​
username: YWRtaW4= # "admin"​
password: UzNjcjN0UEBzc3cwcmQh​

# Benefits: Performance (no watches), Security (cannot be changed)

Best Practices
# 1. Use Secrets for sensitive data, ConfigMaps for non-sensitive​

# 2. Enable encryption at rest for Secrets​
# Configure in kube-apiserver​

# 3. Use RBAC to restrict access​
apiVersion: [Link]/v1​
kind: Role​
metadata:​
name: secret-reader​
rules:​
- apiGroups: [""]​
resources: ["secrets"]​
verbs: ["get", "list"]​

# 4. Mount as volumes, not environment variables (more secure)​
# Volumes: Updated automatically, not visible in process listing​
# Env vars: Static, visible in process listing​

# 5. Use external secret managers (production)​
# - HashiCorp Vault​
# - AWS Secrets Manager​
# - Azure Key Vault​
# - Google Secret Manager​

# 6. Don't commit secrets to Git​
# Use tools like sealed-secrets, external-secrets operator

10. Storage
Storage Concepts
Volume: Directory accessible to containers in a pod PersistentVolume (PV): Cluster-level
storage resource PersistentVolumeClaim (PVC): Request for storage by a user
StorageClass: Dynamic provisioning of PVs
Volume Types

emptyDir
●​ Temporary storage, deleted when pod is removed
●​ Shared between containers in same pod
apiVersion: v1​
kind: Pod​
metadata:​
name: emptydir-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
- name: cache-volume​
mountPath: /cache​
- name: sidecar​
image: busybox​
volumeMounts:​
- name: cache-volume​
mountPath: /cache​
volumes:​
- name: cache-volume​
emptyDir: {}​
# emptyDir:​
# medium: Memory # Use RAM (faster but lost on restart)​
# sizeLimit: 1Gi

hostPath
●​ Mounts file/directory from host node
●​ Survives pod restart but node-specific
apiVersion: v1​
kind: Pod​
metadata:​
name: hostpath-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
- name: host-volume​
mountPath: /data​
volumes:​
- name: host-volume​
hostPath:​
path: /var/data​
type: DirectoryOrCreate # Directory, File, FileOrCreate, etc.
configMap Volume
apiVersion: v1​
kind: Pod​
metadata:​
name: configmap-volume-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
- name: config​
mountPath: /etc/config​
volumes:​
- name: config​
configMap:​
name: app-config

secret Volume
apiVersion: v1​
kind: Pod​
metadata:​
name: secret-volume-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
- name: secret​
mountPath: /etc/secret​
readOnly: true​
volumes:​
- name: secret​
secret:​
secretName: db-credentials

downwardAPI
●​ Exposes pod/container metadata
apiVersion: v1​
kind: Pod​
metadata:​
name: downwardapi-pod​
labels:​
app: myapp​
annotations:​
build: "123"​
spec:​
containers:​
- name: app​
image: busybox​
command: ["sleep", "3600"]​
volumeMounts:​
- name: podinfo​
mountPath: /etc/podinfo​
volumes:​
- name: podinfo​
downwardAPI:​
items:​
- path: "labels"​
fieldRef:​
fieldPath: [Link]​
- path: "annotations"​
fieldRef:​
fieldPath: [Link]​
- path: "pod-name"​
fieldRef:​
fieldPath: [Link]​
- path: "namespace"​
fieldRef:​
fieldPath: [Link]

PersistentVolumes (PV)

PersistentVolume Spec
apiVersion: v1​
kind: PersistentVolume​
metadata:​
name: pv-example​
labels:​
type: local​
spec:​
# Storage capacity​
capacity:​
storage: 10Gi​

# Access modes​
accessModes:​
- ReadWriteOnce # RWO: Single node read-write​
# - ReadOnlyMany # ROX: Multiple nodes read-only​
# - ReadWriteMany # RWX: Multiple nodes read-write​

# Reclaim policy​
persistentVolumeReclaimPolicy: Retain # Retain, Delete, Recycle​

# Storage class​
storageClassName: manual​

# Volume mode​
volumeMode: Filesystem # Filesystem or Block​

# Mount options​
mountOptions:​
- hard​
- nfsvers=4.1​

# Node affinity​
nodeAffinity:​
required:​
nodeSelectorTerms:​
- matchExpressions:​
- key: [Link]/hostname​
operator: In​
values:​
- node-1​

# Storage backend (examples)​
hostPath:​
path: /mnt/data​
type: DirectoryOrCreate​

# Or NFS​
# nfs:​
# server: [Link]​
# path: /exports/data​

# Or AWS EBS​
# awsElasticBlockStore:​
# volumeID: vol-0123456789abcdef0​
# fsType: ext4​

# Or GCE Persistent Disk​
# gcePersistentDisk:​
# pdName: my-disk​
# fsType: ext4​

# Or Azure Disk​
# azureDisk:​
# diskName: myDisk​
# diskURI: /subscriptions/.../myDisk

PersistentVolumeClaims (PVC)
apiVersion: v1​
kind: PersistentVolumeClaim​
metadata:​
name: pvc-example​
namespace: default​
spec:​
# Access modes (must match PV)​
accessModes:​
- ReadWriteOnce​

# Storage class​
storageClassName: manual​

# Volume mode​
volumeMode: Filesystem​

# Resource requests​
resources:​
requests:​
storage: 5Gi​

# Selector (optional, to bind to specific PV)​
selector:​
matchLabels:​
type: local​
matchExpressions:​
- key: environment​
operator: In​
values:​
- dev

Using PVC in Pod


apiVersion: v1​
kind: Pod​
metadata:​
name: pvc-pod​
spec:​
containers:​
- name: app​
image: nginx​
volumeMounts:​
- name: persistent-storage​
mountPath: /usr/share/nginx/html​
volumes:​
- name: persistent-storage​
persistentVolumeClaim:​
claimName: pvc-example

StorageClass (Dynamic Provisioning)


apiVersion: [Link]/v1​
kind: StorageClass​
metadata:​
name: fast-ssd​
annotations:​
[Link]/is-default-class: "true"​
provisioner: [Link]/aws-ebs​
parameters:​
type: gp3​
iops: "3000"​
throughput: "125"​
encrypted: "true"​
fsType: ext4​
reclaimPolicy: Delete​
allowVolumeExpansion: true​
volumeBindingMode: WaitForFirstConsumer # Immediate or WaitForFirstConsumer

Popular Provisioners:
# AWS EBS​
provisioner: [Link]/aws-ebs​
parameters:​
type: gp3​

# GCE Persistent Disk​
provisioner: [Link]/gce-pd​
parameters:​
type: pd-ssd​

# Azure Disk​
provisioner: [Link]/azure-disk​
parameters:​
storageaccounttype: Premium_LRS​

# NFS (external provisioner)​
provisioner: nfs-provisioner​
parameters:​
server: [Link]​
path: /exports​

# Local path (Rancher)​
provisioner: [Link]/local-path​
parameters:​
path: /opt/local-path-provisioner

PVC with Dynamic Provisioning


apiVersion: v1​
kind: PersistentVolumeClaim​
metadata:​
name: dynamic-pvc​
spec:​
accessModes:​
- ReadWriteOnce​
storageClassName: fast-ssd # References StorageClass​
resources:​
requests:​
storage: 20Gi​
# PV is automatically created by provisioner
StatefulSet with PVC
apiVersion: apps/v1​
kind: StatefulSet​
metadata:​
name: mysql​
spec:​
serviceName: mysql​
replicas: 3​
selector:​
matchLabels:​
app: mysql​
template:​
metadata:​
labels:​
app: mysql​
spec:​
containers:​
- name: mysql​
image: mysql:8.0​
ports:​
- containerPort: 3306​
volumeMounts:​
- name: data​
mountPath: /var/lib/mysql​
env:​
- name: MYSQL_ROOT_PASSWORD​
valueFrom:​
secretKeyRef:​
name: mysql-secret​
key: password​
# Volume claim templates (creates PVC per replica)​
volumeClaimTemplates:​
- metadata:​
name: data​
spec:​
accessModes: ["ReadWriteOnce"]​
storageClassName: fast-ssd​
resources:​
requests:​
storage: 10Gi

Storage Commands
# PersistentVolumes​
kubectl get pv​
kubectl describe pv <pv-name>​
kubectl delete pv <pv-name>​

# PersistentVolumeClaims​
kubectl get pvc​
kubectl describe pvc <pvc-name>​
kubectl delete pvc <pvc-name>​

# StorageClasses​
kubectl get storageclass​
kubectl get sc​
kubectl describe sc <sc-name>​

# Check PV status​
kubectl get pv -o wide​
# Status: Available, Bound, Released, Failed​

# Check PVC status​
kubectl get pvc -o wide​
# Status: Pending, Bound, Lost​

# Get PV details​
kubectl get pv <pv-name> -o yaml​

# Get PVC details​
kubectl get pvc <pvc-name> -o yaml​

# View which PV is bound to PVC​
kubectl get pvc <pvc-name> -o jsonpath='{.[Link]}'​

# Expand PVC (if allowVolumeExpansion: true)​
kubectl patch pvc <pvc-name> -p
'{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'​

# Create PV​
kubectl apply -f [Link]​

# Create PVC​
kubectl apply -f [Link]​

# Check storage capacity​
kubectl get pv --sort-by=.[Link]

Volume Snapshots
# VolumeSnapshotClass​
apiVersion: [Link]/v1​
kind: VolumeSnapshotClass​
metadata:​
name: csi-snapclass​
driver: [Link]​
deletionPolicy: Delete​
---​
# VolumeSnapshot​
apiVersion: [Link]/v1​
kind: VolumeSnapshot​
metadata:​
name: pvc-snapshot​
spec:​
volumeSnapshotClassName: csi-snapclass​
source:​
persistentVolumeClaimName: pvc-example​
---​
# Restore from snapshot​
apiVersion: v1​
kind: PersistentVolumeClaim​
metadata:​
name: pvc-restored​
spec:​
accessModes:​
- ReadWriteOnce​
storageClassName: fast-ssd​
resources:​
requests:​
storage: 10Gi​
dataSource:​
name: pvc-snapshot​
kind: VolumeSnapshot​
apiGroup: [Link]

Storage Best Practices


# 1. Use StorageClasses for dynamic provisioning​
# 2. Set resource requests and limits​
# 3. Use ReadWriteOnce for single-pod access​
# 4. Use ReadWriteMany only when necessary (limited support)​
# 5. Set appropriate reclaim policies​
# - Retain: For production (manual cleanup)​
# - Delete: For development​
# 6. Enable volume expansion in StorageClass​
# 7. Use volumeBindingMode: WaitForFirstConsumer for topology-aware
scheduling​
# 8. Regular backups via volume snapshots​
# 9. Monitor storage usage​
# 10. Use CSI drivers for modern storage features

11. Setting Up a Three-Node Cluster


Prerequisites
System Requirements (per node): - 2 CPU cores minimum - 2 GB RAM minimum (4 GB
recommended) - 20 GB disk space - Ubuntu 20.04/22.04 or CentOS 7/8 - Network
connectivity between nodes - Unique hostname, MAC address, product_uuid per node
Node Setup: - 1 Control Plane Node (Master) - 2 Worker Nodes
Step 1: Prepare All Nodes
# Run on ALL nodes (control plane + workers)​

# 1. Update system​
sudo apt-get update​
sudo apt-get upgrade -y​

# 2. Disable swap (required by Kubernetes)​
sudo swapoff -a​
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab​

# 3. Load kernel modules​
cat <<EOF | sudo tee /etc/modules-load.d/[Link]​
overlay​
br_netfilter​
EOF​

sudo modprobe overlay​
sudo modprobe br_netfilter​

# 4. Configure sysctl​
cat <<EOF | sudo tee /etc/sysctl.d/[Link]​
[Link]-nf-call-iptables = 1​
[Link]-nf-call-ip6tables = 1​
net.ipv4.ip_forward = 1​
EOF​

sudo sysctl --system​

# 5. Verify modules​
lsmod | grep br_netfilter​
lsmod | grep overlay​

# 6. Verify sysctl​
sysctl [Link]-nf-call-iptables [Link]-nf-call-ip6tables
net.ipv4.ip_forward

Step 2: Install Container Runtime (containerd)


# Run on ALL nodes​

# 1. Install containerd​
sudo apt-get install -y containerd​

# 2. Configure containerd​
sudo mkdir -p /etc/containerd​
sudo containerd config default | sudo tee /etc/containerd/[Link]​

# 3. Enable SystemdCgroup​
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g'
/etc/containerd/[Link]​

# 4. Restart containerd​
sudo systemctl restart containerd​
sudo systemctl enable containerd​

# 5. Verify containerd​
sudo systemctl status containerd

Step 3: Install kubeadm, kubelet, kubectl


# Run on ALL nodes​

# 1. Install dependencies​
sudo apt-get update​
sudo apt-get install -y apt-transport-https ca-certificates curl gpg​

# 2. Add Kubernetes apt repository​
curl -fsSL [Link] | sudo gpg
--dearmor -o /etc/apt/keyrings/[Link]​

echo 'deb [signed-by=/etc/apt/keyrings/[Link]]
[Link] /' | sudo tee
/etc/apt/[Link].d/[Link]​

# 3. Install Kubernetes components​
sudo apt-get update​
sudo apt-get install -y kubelet kubeadm kubectl​

# 4. Hold versions (prevent auto-upgrade)​
sudo apt-mark hold kubelet kubeadm kubectl​

# 5. Verify installation​
kubeadm version​
kubelet --version​
kubectl version --client​

# 6. Enable kubelet​
sudo systemctl enable kubelet

Step 4: Initialize Control Plane


# Run ONLY on CONTROL PLANE node​

# 1. Initialize cluster​
sudo kubeadm init \​
--pod-network-cidr=[Link]/16 \​
--apiserver-advertise-address=<CONTROL_PLANE_IP> \​
--control-plane-endpoint=<CONTROL_PLANE_IP>​

# Example:​
# sudo kubeadm init \​
# --pod-network-cidr=[Link]/16 \​
# --apiserver-advertise-address=[Link] \​
# --control-plane-endpoint=[Link]​

# 2. Save the output! You'll need the join command​
# kubeadm join [Link]:6443 --token <token> \​
# --discovery-token-ca-cert-hash sha256:<hash>​

# 3. Configure kubectl for regular user​
mkdir -p $HOME/.kube​
sudo cp -i /etc/kubernetes/[Link] $HOME/.kube/config​
sudo chown $(id -u):$(id -g) $HOME/.kube/config​

# 4. Verify cluster​
kubectl get nodes​
kubectl get pods -A​

# 5. Check control plane components​
kubectl get pods -n kube-system

Step 5: Install Pod Network (CNI)


# Run on CONTROL PLANE node​

# Option 1: Flannel (simple, good for learning)​
kubectl apply -f
[Link]
ml​

# Option 2: Calico (production-ready, supports network policies)​
kubectl create -f
[Link]
[Link]​
kubectl create -f
[Link]
[Link]​

# Option 3: Weave Net​
kubectl apply -f
[Link]
[Link]​

# Wait for pods to be ready​
kubectl get pods -n kube-system --watch​

# Verify network​
kubectl get pods -n kube-system -o wide
Step 6: Join Worker Nodes
# Run on WORKER nodes​

# 1. Use the join command from control plane init output​
sudo kubeadm join [Link]:6443 \​
--token <token-from-init> \​
--discovery-token-ca-cert-hash sha256:<hash-from-init>​

# 2. If you lost the join command, generate new token on control plane:​
kubeadm token create --print-join-command​

# 3. Verify join on control plane​
kubectl get nodes​

# Output should show all nodes:​
# NAME STATUS ROLES AGE VERSION​
# control-plane Ready control-plane 10m v1.28.x​
# worker-1 Ready <none> 5m v1.28.x​
# worker-2 Ready <none> 5m v1.28.x

Step 7: Verify Cluster


# Run on CONTROL PLANE node​

# 1. Check all nodes​
kubectl get nodes -o wide​

# 2. Check system pods​
kubectl get pods -n kube-system​

# 3. Check component status​
kubectl get componentstatuses​

# 4. Deploy test application​
kubectl create deployment nginx --image=nginx --replicas=3​

# 5. Expose as service​
kubectl expose deployment nginx --port=80 --type=NodePort​

# 6. Check deployment​
kubectl get deployments​
kubectl get pods -o wide​
kubectl get services​

# 7. Test access​
curl [Link]

# 8. Clean up test​
kubectl delete deployment nginx​
kubectl delete service nginx
Step 8: Label Worker Nodes
# Run on CONTROL PLANE node​

# Label nodes for better organization​
kubectl label node worker-1 [Link]/worker=worker​
kubectl label node worker-2 [Link]/worker=worker​

# Add custom labels​
kubectl label node worker-1 disktype=ssd​
kubectl label node worker-2 disktype=hdd​

# Verify labels​
kubectl get nodes --show-labels

Cluster Configuration Files


Important locations:
# Kubernetes configuration​
/etc/kubernetes/​
├── [Link] # Admin kubeconfig​
├── [Link] # Kubelet kubeconfig​
├── [Link]​
├── [Link]​
└── manifests/ # Static pod manifests​
├── [Link]​
├── [Link]​
├── [Link]​
└── [Link]​

# Kubelet configuration​
/var/lib/kubelet/[Link]​

# Container runtime​
/etc/containerd/[Link]​

# Kubeconfig (user)​
~/.kube/config

Cluster Management Commands


# View cluster info​
kubectl cluster-info​
kubectl cluster-info dump​

# View nodes​
kubectl get nodes​
kubectl describe node <node-name>​

# Drain node (before maintenance)​
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data​

# Uncordon node (after maintenance)​
kubectl uncordon <node-name>​

# Cordon node (mark unschedulable)​
kubectl cordon <node-name>​

# Remove node from cluster​
kubectl drain <node-name> --ignore-daemonsets --force​
kubectl delete node <node-name>​

# On the worker node being removed:​
sudo kubeadm reset​
sudo rm -rf /etc/cni/net.d​
sudo rm -rf $HOME/.kube/config​

# View certificates​
kubeadm certs check-expiration​

# Renew certificates​
sudo kubeadm certs renew all​

# Upgrade cluster (control plane)​
sudo apt-mark unhold kubeadm​
sudo apt-get update && sudo apt-get install -y kubeadm=1.29.0-00​
sudo apt-mark hold kubeadm​
sudo kubeadm upgrade plan​
sudo kubeadm upgrade apply v1.29.0​

# Upgrade kubelet and kubectl​
sudo apt-mark unhold kubelet kubectl​
sudo apt-get update && sudo apt-get install -y kubelet=1.29.0-00
kubectl=1.29.0-00​
sudo apt-mark hold kubelet kubectl​
sudo systemctl daemon-reload​
sudo systemctl restart kubelet

Troubleshooting Cluster Setup


# Check kubelet logs​
sudo journalctl -u kubelet -f​

# Check containerd logs​
sudo journalctl -u containerd -f​

# Check pod logs​
kubectl logs <pod-name> -n kube-system​

# Describe pod​
kubectl describe pod <pod-name> -n kube-system​

# Check apiserver​
kubectl get pods -n kube-system | grep apiserver​
kubectl logs -n kube-system kube-apiserver-<hostname>​

# Check etcd​
kubectl get pods -n kube-system | grep etcd​
kubectl exec -it -n kube-system etcd-<hostname> -- etcdctl member list​

# Reset node (if initialization fails)​
sudo kubeadm reset​
sudo rm -rf /etc/cni/net.d​
sudo rm -rf $HOME/.kube/config​
sudo rm -rf /etc/kubernetes/​
# Then retry initialization​

# Common issues:​
# 1. Swap not disabled: sudo swapoff -a​
# 2. Port conflicts: Check ports 6443, 2379-2380, 10250-10252​
# 3. Firewall: Ensure required ports are open​
# 4. Network plugin: Wait for CNI pods to be ready

High Availability Setup (Optional)


For production, use multiple control plane nodes:
# Initialize first control plane​
sudo kubeadm init \​
--control-plane-endpoint="[Link]" \​
--upload-certs \​
--pod-network-cidr=[Link]/16​

# Join additional control planes​
sudo kubeadm join [Link] \​
--token <token> \​
--discovery-token-ca-cert-hash sha256:<hash> \​
--control-plane \​
--certificate-key <cert-key>​

# Requirements:​
# - Load balancer in front of control planes​
# - External etcd cluster (recommended for large clusters)​
# - Shared storage for cluster data

Summary and Best Practices


Key Takeaways
1.​ Pods: Smallest unit, ephemeral, share network/storage
2.​ ReplicaSets: Maintain desired pod count, self-healing
3.​ Deployments: Declarative updates, rolling updates, rollbacks
4.​ Services: Stable networking, load balancing, service discovery
5.​ Namespaces: Logical isolation, multi-tenancy, resource quotas
6.​ Networking: Network policies control traffic, Ingress manages external access
7.​ ConfigMaps/Secrets: Decouple configuration, manage sensitive data
8.​ Storage: Volumes for data persistence, dynamic provisioning with StorageClasses
9.​ Cluster: Understanding architecture is crucial for troubleshooting

Production Best Practices


# Always set resource requests and limits​
resources:​
requests:​
cpu: "100m"​
memory: "128Mi"​
limits:​
cpu: "500m"​
memory: "256Mi"​

# Use health probes​
livenessProbe:​
httpGet:​
path: /health​
port: 8080​
readinessProbe:​
httpGet:​
path: /ready​
port: 8080​

# Use namespaces for organization​
# Use labels for selection​
# Use annotations for metadata​

# Security​
# - Use RBAC​
# - Network policies​
# - Pod security standards​
# - Encrypt secrets at rest​
# - Regular updates​

# Monitoring​
# - Prometheus + Grafana​
# - ELK Stack for logs​
# - Jaeger for tracing​

# Backup​
# - etcd snapshots​
# - Volume snapshots​
# - GitOps for declarative configs

Next Steps
1.​ Practice with minikube or kind for local development
2.​ Learn Helm for package management
3.​ Explore GitOps (ArgoCD, Flux)
4.​ Study CKA/CKAD certifications
5.​ Implement CI/CD pipelines
6.​ Learn service mesh (Istio, Linkerd)
7.​ Explore operators and custom resources
8.​ Master troubleshooting techniques

stringData:
username: admin
password: S3cr3tP@ssw0rd!

**TLS Secret**:​
```yaml​
apiVersion: v1​
kind: Secret​
metadata:​
name: tls-secret​
type: [Link]/tls​
data:​
[Link]: <base64-encoded-cert>​
[Link]: <base64-encoded-key>

Docker Registry Secret:


apiVersion: v1​
kind: Secret​
metadata:​
name: regcred​
type: [Link]/dockerconfigjson​
data:​
.dockerconfigjson: <base64-encoded-docker-config>

Using Secrets in Pods


As Environment Variables:
apiVersion: v1​
kind: Pod​
metadata:​
name: app-pod​
spec:​
containers:​
- name: app​
image: myapp:1.0​

# Single environment variable from Secret​
env:​
- name: DB_USERNAME​
valueFrom:​
secretKeyRef:​
name: db-credentials​
key: username​
- name: DB_PASSWORD​
valueFrom:​
secretKeyRef:​
name: db-credentials​
key: password​

# All keys as environment variables​
envFrom:​
- secretRef:​
name: db-credentials

As Volume Mounts:
apiVersion: v1​
kind: Pod​
metadata:​
name: app-pod​
spec:​
containers:​
- name: app​
image: myapp:1.0​
volumeMounts:​
- name: secret-volume​
mountPath: /etc/secrets​
readOnly: true​

volumes:​
- name: secret-volume​
secret:​
secretName: db-credentials​
items:​
- key: username​
path: db-username​
mode: 0400​
- key: password​
path: db-password​
mode: 0400
Docker Registry Secret:
apiVersion: v1​
kind: Pod​
metadata:​
name: private-image-pod​
spec:​
containers:​
- name: app​
image: [Link]/myapp:1.0​
imagePullSecrets:​
- name: regcred

ConfigMap & Secret Commands


# List ConfigMaps​
kubectl get configmaps​
kubectl get cm​

# List Secrets​
kubectl get secrets​

# Describe ConfigMap​
kubectl describe configmap app-config​

# Describe Secret (values hidden)​
kubectl describe secret db-credentials​

# Get ConfigMap YAML​
kubectl get configmap app-config -o yaml​

# Get Secret YAML​
kubectl get secret db-credentials -o yaml​

# Decode secret value​
kubectl get secret db-credentials -o jsonpath='{.[Link]}' | base64
--decode​

# Edit ConfigMap​
kubectl edit configmap app-config​

# Edit Secret​
kubectl edit secret db-credentials​

# Delete ConfigMap​
kubectl delete configmap app-config​

# Delete Secret​
kubectl delete secret db-credentials​

# Create ConfigMap from directory​
kubectl create configmap game-config --from-file=./config-directory/​

# Update ConfigMap​
kubectl create configmap app-config --from-literal=KEY=VALUE --dry-run=client
-o yaml | kubectl apply -f -​

# Watch for changes​
kubectl get configmap app-config --watch

Immutable ConfigMaps and Secrets


apiVersion: v1

kind: ConfigMap
metadata:
name: immutable-config
immutable: true
data:
DATABASE_URL: "postgres://db:5432/mydb"
---
apiVersion: v1
kind: Secret
metadata:
name: immutable-secret
immutable: true
type: Opaque
data:
password: UzNjcjN0

You might also like