Skip to the content.

Kubernetes Concepts

Understanding Kubernetes fundamentals for Mycelium Cloud deployments.

Table of Contents

What is Kubernetes?

Kubernetes (K8s) is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications. Mycelium Cloud uses K3s, a lightweight Kubernetes distribution perfect for edge and resource-constrained environments.

Why Kubernetes?

Core Concepts

Cluster

A Kubernetes cluster consists of:

┌─────────────────────────────────────┐
│         Control Plane               │
│  ┌──────────┐  ┌──────────────┐   │
│  │ API      │  │ Scheduler    │   │
│  │ Server   │  │              │   │
│  └──────────┘  └──────────────┘   │
│  ┌──────────┐  ┌──────────────┐   │
│  │ etcd     │  │ Controller   │   │
│  │          │  │ Manager      │   │
│  └──────────┘  └──────────────┘   │
└─────────────────────────────────────┘
           │
    ┌──────┴──────┐
    │             │
┌───▼───┐    ┌───▼───┐
│Worker │    │Worker │
│Node 1 │    │Node 2 │
└───────┘    └───────┘

Nodes

Nodes are the worker machines (VMs or physical servers) that run your applications.

Each node contains:

View nodes:

kubectl get nodes

Namespaces

Namespaces provide logical isolation for resources within a cluster.

Common namespaces:

# List namespaces
kubectl get namespaces

# Create namespace
kubectl create namespace my-app

# Use namespace
kubectl get pods -n my-app

Workload Resources

Pods

A Pod is the smallest deployable unit in Kubernetes. It represents one or more containers that share:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
# Create pod
kubectl apply -f pod.yaml

# View pods
kubectl get pods

# View pod details
kubectl describe pod nginx-pod

# View pod logs
kubectl logs nginx-pod

# Execute command in pod
kubectl exec -it nginx-pod -- /bin/bash

Deployments

A Deployment manages a replicated set of Pods and provides declarative updates.

Features:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
# Create deployment
kubectl apply -f deployment.yaml

# View deployments
kubectl get deployments

# Scale deployment
kubectl scale deployment nginx-deployment --replicas=5

# Update image
kubectl set image deployment/nginx-deployment nginx=nginx:1.22

# View rollout status
kubectl rollout status deployment/nginx-deployment

# Rollback
kubectl rollout undo deployment/nginx-deployment

ReplicaSets

A ReplicaSet ensures a specified number of pod replicas are running. Deployments manage ReplicaSets automatically.

# View replicasets
kubectl get replicasets

StatefulSets

StatefulSets manage stateful applications that require:

Use cases: Databases, message queues, distributed systems

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
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

DaemonSets

DaemonSets ensure a pod runs on all (or selected) nodes. Common for:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluentd:latest

Jobs and CronJobs

Jobs run tasks to completion:

apiVersion: batch/v1
kind: Job
metadata:
  name: backup-job
spec:
  template:
    spec:
      containers:
      - name: backup
        image: backup-tool:latest
        command: ["./backup.sh"]
      restartPolicy: Never

CronJobs run jobs on a schedule:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-backup
spec:
  schedule: "0 2 * * *"  # 2 AM daily
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: backup-tool:latest
            command: ["./backup.sh"]
          restartPolicy: Never

Networking

Services

Services provide stable network endpoints for accessing pods.

ClusterIP (Default)

Internal-only service, accessible within the cluster:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

NodePort

Exposes service on each node’s IP at a static port:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080  # 30000-32767

LoadBalancer

Creates an external load balancer (cloud provider dependent):

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
# View services
kubectl get services

# Describe service
kubectl describe service my-service

# View endpoints
kubectl get endpoints my-service

Ingress

Ingress manages external HTTP/HTTPS access to services:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

Network Policies

Control traffic flow between pods:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

Storage

Volumes

Volumes provide persistent storage for pods.

emptyDir

Temporary storage, deleted when pod is removed:

volumes:
- name: cache
  emptyDir: {}

hostPath

Mounts a file/directory from the host node:

volumes:
- name: data
  hostPath:
    path: /data
    type: Directory

PersistentVolume (PV)

Cluster-wide storage resource:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /mnt/data

PersistentVolumeClaim (PVC)

Request for storage by a user:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-data
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Use in pod:

spec:
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-data
# View PVs
kubectl get pv

# View PVCs
kubectl get pvc

Configuration

ConfigMaps

Store non-sensitive configuration data:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgres://db:5432/mydb"
  log_level: "info"

Use in pod:

spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - configMapRef:
        name: app-config

Or mount as volume:

spec:
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: config
      mountPath: /etc/config
  volumes:
  - name: config
    configMap:
      name: app-config
# Create from literal
kubectl create configmap app-config --from-literal=key=value

# Create from file
kubectl create configmap app-config --from-file=config.properties

# View configmaps
kubectl get configmaps

# View content
kubectl describe configmap app-config

Secrets

Store sensitive data (passwords, tokens, keys):

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=  # base64 encoded
# Create secret
kubectl create secret generic app-secret --from-literal=password=password123

# View secrets
kubectl get secrets

# Decode secret
kubectl get secret app-secret -o jsonpath='{.data.password}' | base64 --decode

Use in pod:

spec:
  containers:
  - name: app
    image: myapp:latest
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: password

Security

RBAC (Role-Based Access Control)

Control who can access what resources.

Role

Permissions within a namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

RoleBinding

Bind role to users/groups:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRole & ClusterRoleBinding

Cluster-wide permissions (similar to Role/RoleBinding but not namespaced).

Security Contexts

Define privilege and access control settings:

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true

Resource Limits

Prevent resource exhaustion:

spec:
  containers:
  - name: app
    image: myapp:latest
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Labels and Selectors

Labels are key-value pairs attached to objects:

metadata:
  labels:
    app: nginx
    environment: production
    tier: frontend

Selectors query objects by labels:

# Get pods with label
kubectl get pods -l app=nginx

# Get pods with multiple labels
kubectl get pods -l app=nginx,environment=production

# Get pods without label
kubectl get pods -l '!environment'

Common kubectl Commands

# Cluster info
kubectl cluster-info
kubectl version

# Nodes
kubectl get nodes
kubectl describe node <node-name>

# Pods
kubectl get pods
kubectl get pods -o wide
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl logs -f <pod-name>  # Follow logs
kubectl exec -it <pod-name> -- /bin/bash

# Deployments
kubectl get deployments
kubectl describe deployment <deployment-name>
kubectl scale deployment <name> --replicas=5
kubectl rollout status deployment/<name>
kubectl rollout history deployment/<name>
kubectl rollout undo deployment/<name>

# Services
kubectl get services
kubectl describe service <service-name>

# Apply/Delete resources
kubectl apply -f file.yaml
kubectl delete -f file.yaml
kubectl delete pod <pod-name>

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

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

# Resource usage
kubectl top nodes
kubectl top pods

# Debug
kubectl get events
kubectl get events --sort-by=.metadata.creationTimestamp

Best Practices

  1. Use Namespaces - Organize resources logically
  2. Set Resource Limits - Prevent resource exhaustion
  3. Use Health Checks - Implement liveness and readiness probes
  4. Version Control - Store manifests in Git
  5. Use Labels - Tag resources for organization and selection
  6. Secrets Management - Never hardcode sensitive data
  7. Rolling Updates - Update applications with zero downtime
  8. Monitor Resources - Track CPU, memory, and disk usage
  9. Backup etcd - Regular cluster state backups
  10. Security - Follow least privilege principle

Next Steps

Additional Resources