freeleaps-ops/docs/Kubernetes_Core_Concepts_Guide.md
2025-09-04 00:58:59 -07:00

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

  1. Don't create Pods directly - Use Deployments
  2. Use namespaces for organization
  3. Set resource limits on all containers
  4. Use health checks for reliability
  5. Implement security contexts
  6. 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