Kubernetes Operations¶
Prerequisites¶
- K3s installed and running
- kubectl available
Procedure: Install K3s¶
When to use: Setting up a single-node Kubernetes cluster on a fresh VM using the K3s lightweight distribution.
Steps:
-
Create pre-configuration files before running the installer. K3s reads both at startup and will not pick them up if created afterwards:
-
/var/lib/rancher/k3s/server/manifests/traefik-config.yaml— overrides Traefik's default HTTP port from 80 to 8080 so it does not conflict with Apache:apiVersion: helm.cattle.io/v1 kind: HelmChartConfig metadata: name: traefik namespace: kube-system spec: valuesContent: |- ports: web: exposedPort: 8080 websecure: exposedPort: 8443 -
/etc/rancher/k3s/config.yaml— sets the kubeconfig permissions to world-readable and adds the VM's external IP as a valid TLS subject alternative name (required forkubectlto connect from outside the VM):write-kubeconfig-mode: "0644" tls-san: - "<your-vm-external-IP>" cluster-init: true
-
-
Run the installer:
curl -sfL https://get.k3s.io | sh - -
Verify the service started and the node is ready:
systemctl status k3s kubectl get nodes -
Open port
6443/tcpinfirewalldand your cloud security group — this is the Kubernetes API port used bykubectland the scoring server. You have done this before with other services. -
Add the K3s pod and service networks to the trusted firewall zone so that the Traefik ingress pod can reach application pods:
firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16 # pods firewall-cmd --permanent --zone=trusted --add-source=10.43.0.0/16 # services firewall-cmd --reload
Notes:
kubectlis bundled with K3s — the installer creates a symlink at/usr/local/bin/kubectl. No separate installation is required.- The kubeconfig file at
/etc/rancher/k3s/k3s.yamlis set to world-readable bywrite-kubeconfig-mode: "0644", sokubectlworks for any user without setting aKUBECONFIGenvironment variable. - If
kubectlgives "command not found",/usr/local/binis not in your PATH. Either use the full path or runexport PATH=$PATH:/usr/local/bin.
Troubleshooting:
- Traefik still listening on port 80: The
traefik-config.yamlwas not in place before installation. Reinstall or patch the HelmChartConfig resource. kubectlcertificate error: The VM's external IP was not intls-san. Add it and restart k3s:systemctl restart k3s.- K3s fails to start — check
journalctl -u k3s -n 50for the specific error.
Procedure: Test Pod Connectivity at Each Layer¶
When to use: Verifying that a new deployment works at each level of the stack before testing the full Ingress path.
Steps:
-
Get pod IPs:
kubectl get pods -n <namespace> -l app=<app-label> -o wide -
Test a pod directly (no Service, no Ingress — raw pod IP):
curl http://<pod-ip>:<container-port>/If this fails, the application itself has a problem. Check
kubectl logs <pod-name> -n <namespace>. -
Get the Service ClusterIP:
kubectl get svc <service-name> -n <namespace> -
Test via the Service (stable IP, load-balanced across pods):
curl http://<cluster-ip>:<service-port>/If pod works but Service doesn't, check that the Service
selectormatches the pod's labels. -
Test via Traefik Ingress (uses hostname routing):
curl --resolve <hostname>:8080:<vm-ip> http://<hostname>:8080/If Service works but Ingress doesn't, check that the Ingress
hostmatches exactly and thatingressClassName: traefikis set.
Troubleshooting:
- Pod IP is unreachable from the host: ensure the pod/service CIDRs are in the trusted firewall zone (see Install K3s procedure).
- Service returns no endpoints:
kubectl describe svc <name> -n <namespace>— check theEndpointsfield. - Ingress returns 404:
kubectl get ingress -n <namespace>and check the host and path match what you're requesting.
Procedure: Apply a Manifest¶
When to use: Creating or updating Kubernetes resources (Pods, Deployments, Services).
Steps:
-
Apply a YAML file:
kubectl apply -f manifest.yaml -
Apply all files in a directory:
kubectl apply -f ./k8s/
Troubleshooting:
- "The connection to the server was refused": Check if K3s/K8s is running (
systemctl status k3s) or ifKUBECONFIGis set.
Procedure: Check Pod Status¶
When to use: Monitoring deployment rollout and health.
Steps:
-
List all pods in default namespace:
kubectl get pods -
List pods in all namespaces:
kubectl get pods -A -
Watch for changes (live update):
kubectl get pods -w
Troubleshooting:
- "ImagePullBackOff": Check image name and registry credentials. If using a local image, ensure
imagePullPolicyis set toNeverorIfNotPresentand the image exists on the node. - "CrashLoopBackOff": Application is crashing. Check logs. Use
kubectl logs <pod> --previousto see the logs of the last crashed instance. - "Pending": The pod cannot be scheduled. Run
kubectl describe pod <name>to check for resource limits (CPU/Memory) or Node Selectors/Taints.
Procedure: View Pod Logs¶
When to use: Debugging application errors.
Steps:
-
View logs:
kubectl logs <pod_name> -
View logs of a specific container (in multi-container pod):
kubectl logs <pod_name> -c <container_name> -
Follow logs:
kubectl logs -f <pod_name>
Troubleshooting:
- "Pod not found": Check if you are in the correct namespace (
-n <namespace>).
Procedure: Create a Namespace¶
When to use: Isolating resources for different environments or projects.
Steps:
-
Create namespace:
kubectl create namespace my-app -
Switch context to use it by default:
kubectl config set-context --current --namespace=my-app
Troubleshooting:
- "Already exists": No action needed, or check spelling.
Procedure: Expose a Service via NodePort¶
When to use: Making an internal application accessible from outside the cluster.
Steps:
-
Expose a deployment:
kubectl expose deployment my-dep --type=NodePort --port=80 --name=my-svc -
Find the assigned NodePort:
kubectl get svc my-svc
Troubleshooting:
- Cannot access port: Ensure firewall allows traffic on the assigned NodePort (30000-32767).
Procedure: Create an Ingress¶
When to use: Exposing HTTP/HTTPS services via a domain name.
Steps:
-
Create
ingress.yaml:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-svc port: number: 80 -
Apply it:
kubectl apply -f ingress.yaml
Troubleshooting:
- 404 Not Found: Ensure the Ingress Controller (Traefik/Nginx) is running and DNS points to the cluster IP.
Procedure: Debug a Failing Pod¶
When to use: Detailed investigation of why a pod is pending or failing.
Steps:
-
Describe the pod events and status:
Look at the "Events" section at the bottom.kubectl describe pod <pod_name> -
Exec into the pod (if running):
kubectl exec -it <pod_name> -- /bin/sh
Troubleshooting:
- "SchedulingFailed": Insufficient CPU/Memory resources on nodes.
Quick Reference¶
| Action | Command |
|---|---|
| Get Pods | kubectl get pods |
| Get All | kubectl get all |
| Describe | kubectl describe <res> <name> |
| Logs | kubectl logs <pod> |
| Apply | kubectl apply -f <file> |
| Delete | kubectl delete -f <file> |
| Exec | kubectl exec -it <pod> -- sh |
Related Documentation¶
- Technologies: Kubernetes
- Concepts: Container Orchestration