18 KiB
18 KiB
Kubernetes Core Concepts Guide
🎯 Overview
This guide explains the fundamental Kubernetes concepts: Pods, Namespaces, and Persistent Volume Claims (PVCs). These are the building blocks of your applications in Kubernetes.
🏭 Your Codebase Usage Patterns
Before diving into the concepts, here's what your codebase actually uses:
📋 Deployment Methods Used in Your Codebase
| Method | Used In Your Codebase | Example Location |
|---|---|---|
| Helm Charts | ✅ Primary method | freeleaps-ops/freeleaps/helm-pkg/ |
| kubectl apply | ✅ Secondary method | freeleaps-devops-reconciler/scripts/deploy.sh |
| kubectl run | ❌ Not used | - |
| Direct YAML | ✅ For simple resources | freeleaps-ops/cluster/manifests/ |
🔧 Your Actual Commands
# Your codebase uses these patterns:
helm install/upgrade <release> <chart> --namespace <namespace> -f <values.yaml>
kubectl apply -f <directory>/
kubectl get pods -n <namespace> -l app.kubernetes.io/name=<app-name>
📦 1. Pods (The Smallest Unit)
What is a Pod?
A Pod is the smallest deployable unit in Kubernetes. Think of it as a "wrapper" that contains one or more containers.
Pod Characteristics
- Atomic Unit: Pods are created, scheduled, and destroyed together
- Shared Network: Containers in a Pod share the same IP address
- Shared Storage: Containers can share volumes
- Lifecycle: Pods are ephemeral (temporary)
Pod Structure
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
namespace: default
labels:
app: my-app
version: v1
spec:
containers:
- name: app-container
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Creating Pods
Method 1: Direct Pod Creation ❌ BAD PRACTICE - NOT USED IN YOUR CODEBASE
# ❌ BAD PRACTICE: This method is NOT used in your codebase (and shouldn't be!)
# Create a simple nginx pod
kubectl run nginx-pod --image=nginx:latest --port=80
# Why this is BAD:
# - Creates standalone Pods (no self-healing)
# - No scaling capability
# - No rolling updates
# - No rollback capability
# - No resource limits
# - Not declarative
# ✅ GOOD PRACTICE: This method IS used in your codebase
# Create from YAML file
kubectl apply -f pod.yaml
Method 2: Using YAML File ✅ GOOD PRACTICE - USED IN YOUR CODEBASE
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web
spec:
containers:
- name: web
image: nginx:latest
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "production"
Method 3: Helm Charts ✅ BEST PRACTICE - PRIMARY METHOD IN YOUR CODEBASE
# 🏭 ACTUAL EXAMPLE FROM YOUR CODEBASE
# freeleaps-ops/freeleaps/helm-pkg/freeleaps/templates/freeleaps/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/name: "freeleaps"
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
name: "freeleaps"
namespace: {{ .Release.Namespace | quote }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: "freeleaps"
app.kubernetes.io/instance: {{ .Release.Name }}
replicas: {{ .Values.freeleaps.replicas }}
template:
metadata:
labels:
app.kubernetes.io/name: "freeleaps"
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
- name: "freeleaps"
image: "{{ .Values.freeleaps.image.registry }}/{{ .Values.freeleaps.image.repository }}:{{ .Values.freeleaps.image.tag }}"
🎯 Best Practices for Pod Creation
❌ What NOT to Do
# ❌ NEVER use kubectl run for production applications
kubectl run my-app --image=my-app:latest --port=8080
# ❌ NEVER create standalone Pods for services
kubectl run database --image=postgres:13 --port=5432
# ❌ NEVER use imperative commands for production
kubectl run nginx --image=nginx:latest
✅ What TO Do
# ✅ Use Deployments for applications
kubectl create deployment my-app --image=my-app:latest
# ✅ Use Helm charts for complex applications
helm install my-app ./my-app-chart --namespace my-app
# ✅ Use kubectl apply for declarative deployments
kubectl apply -f deployment.yaml
# ✅ Use StatefulSets for databases
kubectl apply -f statefulset.yaml
🔧 When kubectl run is Acceptable
# ✅ OK: One-time debugging pods
kubectl run debug-pod --image=busybox --rm -it --restart=Never -- nslookup my-service
# ✅ OK: Temporary testing
kubectl run test-pod --image=nginx --rm -it --restart=Never -- curl http://my-service:80
# ✅ OK: Quick experiments (development only)
kubectl run temp-pod --image=nginx --port=80
Managing Pods
# List pods
kubectl get pods
kubectl get pods -n <namespace>
# Get detailed info
kubectl describe pod <pod-name>
# View logs
kubectl logs <pod-name>
kubectl logs <pod-name> -f # Follow logs
# Execute commands in pod
kubectl exec -it <pod-name> -- /bin/bash
# Delete pod
kubectl delete pod <pod-name>
Pod Lifecycle
# Check pod status
kubectl get pods -o wide
# Common statuses:
# - Pending: Pod is being scheduled
# - Running: Pod is running
# - Succeeded: Pod completed successfully
# - Failed: Pod failed
# - Unknown: Pod status unclear
🏢 2. Namespaces (Logical Isolation)
What is a Namespace?
A Namespace is a way to divide cluster resources among multiple users, teams, or applications. It provides a scope for names.
Namespace Benefits
- Resource Isolation: Separate resources logically
- Access Control: Different permissions per namespace
- Resource Quotas: Limit resource usage
- Network Policies: Control network traffic
Default Namespaces
# View all namespaces
kubectl get namespaces
# Default namespaces:
# - default: User resources
# - kube-system: System components
# - kube-public: Public resources
# - kube-node-lease: Node lease objects
Creating Namespaces
Method 1: Command Line ✅ USED IN YOUR CODEBASE
# ✅ This method IS used in your codebase
# Create namespace
kubectl create namespace my-app
# ✅ This pattern IS used in your codebase
# Create with labels
kubectl create namespace my-app --dry-run=client -o yaml | \
kubectl label --local -f - environment=production | \
kubectl apply -f -
Method 2: YAML File ✅ USED IN YOUR CODEBASE
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-app
labels:
environment: production
team: backend
Method 3: Helm Charts ✅ PRIMARY METHOD IN YOUR CODEBASE
# 🏭 ACTUAL EXAMPLE FROM YOUR CODEBASE
# Your Helm charts automatically create namespaces
# freeleaps-devops-reconciler/scripts/deploy.sh
HELM_CMD+=(--namespace "$NAMESPACE")
# Create namespace if requested
if [[ "$CREATE_NAMESPACE" == "true" && "$UPGRADE" != "true" ]]; then
HELM_CMD+=(--create-namespace)
fi
Working with Namespaces
# Set default namespace
kubectl config set-context --current --namespace=my-app
# Run command in specific namespace
kubectl get pods -n my-app
# Create resource in namespace
kubectl run nginx --image=nginx -n my-app
# Delete namespace (deletes all resources)
kubectl delete namespace my-app
Namespace Best Practices
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
# Example: Production namespace setup
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
team: platform
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
Your Actual Namespace Structure
# 🏭 YOUR ACTUAL NAMESPACES
kubectl get namespaces
# Your codebase uses these namespaces:
# - freeleaps-controls-system (ingress, cert-manager)
# - freeleaps-devops-system (ArgoCD)
# - freeleaps-prod (Gitea)
# - magicleaps (main application)
# - freeleaps-alpha (testing)
💾 3. Persistent Volume Claims (PVCs)
What is a PVC?
A Persistent Volume Claim (PVC) is a request for storage by a user. It's like a "storage reservation" that provides persistent storage to Pods.
Storage Concepts
- Persistent Volume (PV): The actual storage resource
- Persistent Volume Claim (PVC): A request for storage
- Storage Class: Defines the type of storage
PVC Structure
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-app-storage
namespace: my-app
spec:
accessModes:
- ReadWriteOnce # Single node read/write
resources:
requests:
storage: 10Gi
storageClassName: managed-premium # Azure Premium SSD
Creating PVCs
Method 1: Command Line ✅ USED IN YOUR CODEBASE
# ✅ This method IS used in your codebase
# Create PVC
kubectl create -f pvc.yaml
# ✅ This pattern IS used in your codebase
# Create with kubectl
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
EOF
Method 2: YAML File ✅ USED IN YOUR CODEBASE
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-storage
namespace: my-app
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: managed-premium
Method 3: Helm Charts ✅ PRIMARY METHOD IN YOUR CODEBASE
# 🏭 ACTUAL EXAMPLE FROM YOUR CODEBASE
# freeleaps-ops/freeleaps/helm-pkg/3rd/gitea/values.prod.yaml
persistence:
enabled: true
create: true
mount: true
claimName: freeleaps-prod-gitea-shared-storage
size: 8Gi
accessModes:
- ReadWriteOnce
annotations:
helm.sh/resource-policy: keep
Using PVCs in Pods
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
apiVersion: v1
kind: Pod
metadata:
name: app-with-storage
namespace: my-app
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: app-storage
mountPath: /app/data
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: database-storage
Managing PVCs
# List PVCs
kubectl get pvc
kubectl get pvc -n my-app
# Get detailed info
kubectl describe pvc <pvc-name>
# Delete PVC
kubectl delete pvc <pvc-name>
# Check storage classes
kubectl get storageclass
🔧 4. Practical Examples
Example 1: Web Application with Database
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: webapp
---
# database-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-storage
namespace: webapp
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: managed-premium
---
# database-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: database
namespace: webapp
labels:
app: database
spec:
containers:
- name: postgres
image: postgres:13
env:
- name: POSTGRES_DB
value: "myapp"
- name: POSTGRES_PASSWORD
value: "secret"
ports:
- containerPort: 5432
volumeMounts:
- name: db-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: db-storage
persistentVolumeClaim:
claimName: database-storage
---
# webapp-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: webapp
namespace: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: my-webapp:latest
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
value: "postgresql://postgres:secret@database:5432/myapp"
Example 2: Multi-Container Pod
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
namespace: my-app
spec:
containers:
- name: main-app
image: my-app:latest
ports:
- containerPort: 8080
volumeMounts:
- name: shared-data
mountPath: /app/data
- name: log-collector
image: fluentd:latest
volumeMounts:
- name: shared-data
mountPath: /logs
- name: config-volume
mountPath: /etc/fluentd
volumes:
- name: shared-data
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
🛠️ 5. Management Commands
Pod Management
# Create and manage pods
kubectl run nginx --image=nginx:latest --port=80
kubectl get pods
kubectl describe pod nginx
kubectl logs nginx
kubectl exec -it nginx -- /bin/bash
kubectl delete pod nginx
# Port forwarding
kubectl port-forward nginx 8080:80
# Copy files
kubectl cp local-file.txt nginx:/tmp/
Namespace Management
# Create and manage namespaces
kubectl create namespace my-app
kubectl get namespaces
kubectl get pods -n my-app
kubectl config set-context --current --namespace=my-app
kubectl delete namespace my-app
PVC Management
# Create and manage PVCs
kubectl apply -f pvc.yaml
kubectl get pvc
kubectl describe pvc my-pvc
kubectl delete pvc my-pvc
# Check storage usage
kubectl get pv
kubectl get storageclass
📊 6. Monitoring and Debugging
Pod Health Checks
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
apiVersion: v1
kind: Pod
metadata:
name: healthy-app
spec:
containers:
- name: app
image: my-app:latest
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Resource Monitoring
# Check resource usage
kubectl top pods
kubectl top nodes
# Check events
kubectl get events --sort-by='.lastTimestamp'
# Check pod status
kubectl get pods -o wide
kubectl describe pod <pod-name>
🔒 7. Security Best Practices
Pod Security
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: my-app:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Network Policies
# 📚 EDUCATIONAL EXAMPLE (not from your codebase)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
📚 8. Next Steps
Advanced Concepts
- Deployments: Manage Pod replicas
- Services: Expose Pods internally/externally
- ConfigMaps & Secrets: Configuration management
- Jobs & CronJobs: Batch processing
- StatefulSets: Stateful applications
Best Practices
- Don't create Pods directly - Use Deployments
- Use namespaces for organization
- Set resource limits on all containers
- Use health checks for reliability
- Implement security contexts
- Monitor resource usage
🆘 Troubleshooting
Common Issues
# Pod stuck in Pending
kubectl describe pod <pod-name>
kubectl get events --sort-by='.lastTimestamp'
# PVC not bound
kubectl describe pvc <pvc-name>
kubectl get pv
# Namespace issues
kubectl get namespaces
kubectl describe namespace <namespace-name>
Useful Commands
# Debug pod
kubectl logs <pod-name>
kubectl exec -it <pod-name> -- /bin/bash
kubectl describe pod <pod-name>
# Check resources
kubectl get all -n <namespace>
kubectl get pvc,pv -n <namespace>
kubectl get events -n <namespace>
🏭 Appendix: Your Codebase Patterns
Your Actual Deployment Commands
# 🏭 REAL COMMANDS FROM YOUR CODEBASE
# From freeleaps-devops-reconciler/scripts/deploy.sh
# Helm deployment (primary method)
helm install/upgrade "$RELEASE_NAME" . \
--namespace "$NAMESPACE" \
--create-namespace \
-f "$VALUES_FILE" \
--set "image.tag=$IMAGE_TAG"
# kubectl apply (secondary method)
kubectl apply -f <directory>/
# Status checking
kubectl get pods -n "$NAMESPACE" -l "app.kubernetes.io/name=freeleaps-devops-reconciler"
kubectl logs -n "$NAMESPACE" deployment/"$RELEASE_NAME"
Your Actual Namespace Structure
# 🏭 YOUR REAL NAMESPACES
kubectl get namespaces
# Production namespaces:
# - freeleaps-controls-system (ingress, cert-manager)
# - freeleaps-devops-system (ArgoCD)
# - freeleaps-prod (Gitea)
# - magicleaps (main application)
# - freeleaps-alpha (testing)
Your Actual Storage Classes
# 🏭 YOUR REAL STORAGE CLASSES
kubectl get storageclass
# Azure storage classes used:
# - managed-premium (SSD)
# - managed-standard (HDD)
# - azure-disk-std-lrs (standard disk)
Your Actual Resource Naming Conventions
# 🏭 YOUR REAL NAMING PATTERNS
# From freeleaps-service-hub deployment guidelines
# Resource naming: {APP_NAME}-{RESOURCE_NAME}
# Examples:
# - payment-deployment
# - payment-service
# - payment-configmap
# Namespace: same as repository name
# Examples:
# - freeleaps-service-hub
# - freeleaps-ops
# - magicleaps
Last Updated: September 3, 2025 Version: 1.0 Maintainer: Infrastructure Team