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?
- Automated Deployment - Deploy containers across multiple nodes
- Self-Healing - Automatically restart failed containers
- Horizontal Scaling - Scale applications up or down based on demand
- Service Discovery - Automatic DNS and load balancing
- Rolling Updates - Update applications with zero downtime
- Resource Management - Efficient CPU and memory allocation
Core Concepts
Cluster
A Kubernetes cluster consists of:
- Control Plane (Master nodes) - Manages the cluster
- Worker Nodes - Run your applications
┌─────────────────────────────────────┐
│ 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:
- kubelet - Agent that ensures containers are running
- Container Runtime - Software that runs containers (containerd, Docker)
- kube-proxy - Network proxy for service communication
View nodes:
kubectl get nodes
Namespaces
Namespaces provide logical isolation for resources within a cluster.
Common namespaces:
default
- Default namespace for resourceskube-system
- System componentskube-public
- Publicly accessible resourceskube-node-lease
- Node heartbeat data
# 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:
- Network namespace (same IP address)
- Storage volumes
- Configuration
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:
- Replica Management - Maintain desired number of pods
- Rolling Updates - Update pods with zero downtime
- Rollback - Revert to previous versions
- Self-Healing - Replace failed pods automatically
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:
- Stable network identities
- Persistent storage
- Ordered deployment and scaling
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:
- Log collectors
- Monitoring agents
- Network plugins
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
- Use Namespaces - Organize resources logically
- Set Resource Limits - Prevent resource exhaustion
- Use Health Checks - Implement liveness and readiness probes
- Version Control - Store manifests in Git
- Use Labels - Tag resources for organization and selection
- Secrets Management - Never hardcode sensitive data
- Rolling Updates - Update applications with zero downtime
- Monitor Resources - Track CPU, memory, and disk usage
- Backup etcd - Regular cluster state backups
- Security - Follow least privilege principle
Next Steps
- Getting Started - Deploy your first cluster
- Tutorials - Hands-on deployment examples
- FAQ - Common questions and answers