K3S: Deploying Applications
Writing and Managing YAML Manifests
Ah, YAML—the universal language of Kubernetes and the source of many developer headaches. Forget JSON; this is how Kubernetes likes to communicate, and we just have to deal with it.
Understanding Kubernetes YAML Syntax
YAML in Kubernetes defines how resources should behave. Indentation matters. One extra space, and Kubernetes will pretend it has no idea what you’re talking about.
Components of a Basic YAML Manifest
- apiVersion: Defines which API version to use. Get this wrong, and Kubernetes will mock you.
- kind: The type of resource (Pod, Deployment, Service, etc.).
- metadata: Names and labels—think of it as Kubernetes’ way of keeping things organized.
- spec: The blueprint of your resource. Where the real magic happens.
Example: Creating a Simple Pod Definition
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp-container
image: nginxApply it using:
kubectl apply -f myapp.yaml
kubectl get podsCreating and Managing Deployments and ReplicaSets
Kubernetes gives us Deployments and ReplicaSets so we don’t have to manually keep Pods alive like some sort of server babysitter.
Creating a Deployment YAML File
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: nginxScaling Applications
kubectl scale deployment myapp-deployment --replicas=5Rolling Updates and Rollbacks
kubectl rollout status deployment myapp-deployment
kubectl rollout undo deployment myapp-deploymentIf your update breaks everything (which it inevitably will), roll it back with that last command. You’re welcome.
Managing Services (ClusterIP, NodePort, LoadBalancer)
Deployments are great, but they’re useless if nobody can access them. That’s where Services come in.
Exposing a Deployment Using a ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80Creating a NodePort Service for External Access
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
spec:
type: NodePort
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007Listing Services and Accessing an Application
kubectl get services
curl http://<node-ip>:30007If this doesn’t work, check your firewall settings—or sacrifice a rubber chicken to the Kubernetes gods.
Configuring Ingress for HTTP Routing
You don’t want to expose everything with NodePort; that’s messy. Instead, let’s use Ingress to route traffic properly.
Deploying Traefik as an Ingress Controller
K3s comes with Traefik pre-installed, so you’re already ahead of the game.
Creating an Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80Applying and Verifying Ingress
kubectl apply -f myapp-ingress.yaml
kubectl get ingressHands-On Exercise
Time to put all this knowledge to work:
- Deploy a sample web application using Deployments and ReplicaSets.
- Expose the application using a NodePort and ClusterIP Service.
- Configure and test Ingress for HTTP routing in K3s.
Congratulations! You’ve just deployed a real application in K3s. Now go break it and debug it—because that’s the real Kubernetes experience. 🚀