# 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** ```bash # Your codebase uses these patterns: helm install/upgrade --namespace -f kubectl apply -f / kubectl get pods -n -l app.kubernetes.io/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** ```yaml 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** ```bash # ❌ 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** ```yaml # 📚 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** ```yaml # 🏭 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** ```bash # ❌ 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** ```bash # ✅ 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** ```bash # ✅ 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** ```bash # List pods kubectl get pods kubectl get pods -n # Get detailed info kubectl describe pod # View logs kubectl logs kubectl logs -f # Follow logs # Execute commands in pod kubectl exec -it -- /bin/bash # Delete pod kubectl delete pod ``` ### **Pod Lifecycle** ```bash # 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** ```bash # 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** ```bash # ✅ 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** ```yaml # 📚 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** ```yaml # 🏭 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** ```bash # 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** ```yaml # 📚 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** ```bash # 🏭 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** ```yaml 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** ```bash # ✅ 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 - < # Delete PVC kubectl delete pvc # Check storage classes kubectl get storageclass ``` --- ## 🔧 **4. Practical Examples** ### **Example 1: Web Application with Database** ```yaml # 📚 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** ```yaml # 📚 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** ```bash # 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** ```bash # 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** ```bash # 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** ```yaml # 📚 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** ```bash # 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 ``` --- ## 🔒 **7. Security Best Practices** ### **Pod Security** ```yaml # 📚 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** ```yaml # 📚 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** ```bash # Pod stuck in Pending kubectl describe pod kubectl get events --sort-by='.lastTimestamp' # PVC not bound kubectl describe pvc kubectl get pv # Namespace issues kubectl get namespaces kubectl describe namespace ``` ### **Useful Commands** ```bash # Debug pod kubectl logs kubectl exec -it -- /bin/bash kubectl describe pod # Check resources kubectl get all -n kubectl get pvc,pv -n kubectl get events -n ``` --- ## 🏭 **Appendix: Your Codebase Patterns** ### **Your Actual Deployment Commands** ```bash # 🏭 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 / # 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** ```bash # 🏭 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** ```bash # 🏭 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** ```yaml # 🏭 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