Skip to content

Kubernetes (K3s)

What Is It?

Kubernetes is a container orchestration platform. This course uses K3s, a lightweight Kubernetes distribution packaged as a single binary. It manages Pods, Deployments, Services, and Ingress resources.

Installation

dnf install k3s (via install script)

Key Files and Directories

Path Purpose
/etc/rancher/k3s/config.yaml K3s configuration
/var/lib/rancher/k3s/ K3s data directory
YAML manifests Resource definitions

Default Ports

Port Protocol Purpose
6443 TCP Kubernetes API server
10250 TCP kubelet API
8080/8443 TCP Traefik IngressController (HTTP/HTTPS)
30000–32767 TCP NodePort service range

Configuration

K3s is a lightweight Kubernetes distribution packaged as a single binary. It runs as a systemd service and includes all core Kubernetes components (API server, scheduler, controller, kubelet, kube-proxy) plus a built-in Traefik ingress controller.

Minimal Working Configuration

Pre-installation — move Traefik's default ports to avoid conflicting with Apache:

Create /var/lib/rancher/k3s/server/manifests/traefik-config.yaml:

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    ports:
      web:
        exposedPort: 8080
      websecure:
        exposedPort: 8443

Create /etc/rancher/k3s/config.yaml:

write-kubeconfig-mode: "0644"
tls-san:
  - "<your-vm-external-IP>"
cluster-init: true

Installation:

curl -sfL https://get.k3s.io | sh -

This installs K3s, starts the k3s systemd service, and places kubectl at /usr/local/bin/kubectl.

Resource definitions are YAML manifests. A minimal Pod:

apiVersion: v1
kind: Pod
metadata:
  name: myfirstpod
spec:
  containers:
  - image: nginx
    name: web

A Deployment (manages replicas and rolling updates):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  namespace: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:latest
        ports:
        - containerPort: 80

A Service (exposes Pods on the network):

apiVersion: v1
kind: Service
metadata:
  name: web-service
  namespace: myapp
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

An Ingress (routes external HTTP traffic to Services):

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

Important Directives

Pod
The smallest deployable unit. Contains one or more containers sharing the same network namespace and storage volumes.
Deployment
Manages a ReplicaSet to ensure a specified number of Pod replicas are running. Handles rolling updates and rollbacks.
Service
Provides a stable IP address and DNS name for a set of Pods. Types: ClusterIP (internal), NodePort (host port), LoadBalancer (cloud LB).
Ingress
Routes external HTTP/HTTPS traffic to Services based on hostname and path rules. K3s uses Traefik as the default ingress controller.
Namespace
A virtual cluster within Kubernetes for resource isolation. Resources in different namespaces are separated by default.
ConfigMap / Secret
Store configuration data and sensitive values respectively. Mounted into Pods as files or environment variables.
Volume / PersistentVolumeClaim
Attach storage to Pods. Volumes are ephemeral by default; PersistentVolumeClaims request durable storage that survives Pod restarts.
Labels and Selectors
Key-value pairs attached to resources. Selectors match labels to link Services to Pods, Deployments to ReplicaSets, etc.

Common Commands

# View cluster nodes
kubectl get nodes

# Create resources from a YAML file
kubectl apply -f manifest.yaml

# Delete resources
kubectl delete -f manifest.yaml

# List resources
kubectl get pods
kubectl get pods -n myapp           # In a specific namespace
kubectl get deployments
kubectl get services
kubectl get ingress
kubectl get all -n myapp            # Everything in a namespace

# Describe a resource (detailed info + events)
kubectl describe pod/myfirstpod
kubectl describe service/web-service -n myapp

# View Pod logs
kubectl logs <pod-name>
kubectl logs -f <pod-name>          # Follow logs

# Execute a command in a running Pod
kubectl exec -it <pod-name> -- /bin/sh

# Create a namespace
kubectl create namespace myapp

# Port-forward for local testing
kubectl port-forward service/web-service 8080:80 -n myapp

# View cluster info
kubectl cluster-info

Logging and Debugging

  • Pod logs: kubectl logs <pod> shows application stdout/stderr.
  • Describe: kubectl describe pod/<name> shows events, conditions, and scheduling decisions — essential for diagnosing CrashLoopBackOff or Pending states.
  • Events: kubectl get events -n <namespace> shows recent cluster events.
  • Exec into Pod: kubectl exec -it <pod> -- /bin/sh for interactive debugging.
  • K3s service logs: journalctl -u k3s shows K3s server logs.
  • Common Pod states:
    • Running — healthy
    • Pending — waiting for scheduling (resource constraints, image pull)
    • CrashLoopBackOff — container keeps crashing and restarting
    • ImagePullBackOff — cannot pull the container image

Security Considerations

  • Namespace isolation: Use namespaces to separate applications. Do not deploy workloads in the default namespace.
  • RBAC: Kubernetes uses Role-Based Access Control. K3s creates a kubeconfig at /etc/rancher/k3s/k3s.yaml — protect its permissions.
  • Secrets management: Use Kubernetes Secrets (base64-encoded) rather than hardcoding credentials in manifests. For production, consider external secret stores.
  • Network policies: Restrict Pod-to-Pod communication using NetworkPolicy resources.
  • Image security: Use specific image tags (e.g. nginx:1.25) rather than latest to ensure reproducible deployments.
  • Firewall: Open ports 6443 (API server), 10250 (kubelet), and ingress ports (8080/8443 for Traefik) in both firewalld and cloud security groups.

Further Reading

  • Concepts: Container Orchestration
  • SOPs: Kubernetes Operations