Linux Operations Skills
Supported Versions: Bash on maintained Linux distributions; commands assume the named tools are installed Last Updated: September 11, 2026
This document covers essential Linux operations skills for working effectively in Kubernetes environments.
Table of Contents
- Environment Variables and Shell Configuration
- Shell Scripting Basics
- Text Processing Tools
- SSH and Remote Access
- Performance Monitoring and Troubleshooting
- Storage Management Basics
- curl and API Calls
- Practical One-Liners Collection
1. Environment Variables and Shell Configuration
Environment variables are the core mechanism for managing configuration in Linux and Kubernetes.
1.1 Environment Variable Basics
env
echo "$HOME"
echo "$PATH"
printenv HOME1.2 The export Command
export MY_VAR="hello"
export DATABASE_URL="postgresql://localhost:5432/mydb"
export KUBECONFIG="/home/user/.kube/config"1.3 The source Command
cat > ~/my-env.sh << 'SCRIPT'
export APP_ENV="production"
export APP_PORT="8080"
alias k='kubectl'
SCRIPT
source ~/my-env.sh1.4 .bashrc and .bash_profile
Interactive non-login Bash reads .bashrc; login Bash reads the first available .bash_profile/.bash_login/.profile. A login profile may explicitly source .bashrc. Add the block below once.
cat >> ~/.bashrc << 'SCRIPT'
export KUBECONFIG=~/.kube/config
command -v kubectl >/dev/null && source <(kubectl completion bash)
alias k='kubectl'
SCRIPT
source ~/.bashrc1.5 Kubernetes ConfigMap Connection
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "mysql.default.svc.cluster.local"
DATABASE_PORT: "3306"
---
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config2. Shell Scripting Basics
2.1 Variables
#!/bin/bash
NAME="kubernetes"
NAMESPACE=${1:-default}
: "${REQUIRED_VAR:?REQUIRED_VAR must be set}"2.2 Conditionals
if [ "$ENV" = "production" ]; then
echo "Production mode"
fi
case "$1" in
start) echo "Starting..." ;;
stop) echo "Stopping..." ;;
esac2.3 Loops
for ns in default kube-system monitoring; do
kubectl get pods -n "$ns"
done
# Running phase does not imply readiness. A bounded wait propagates API errors/timeouts.
kubectl wait --for=condition=Ready pod/mypod --timeout=120s2.4 Functions
check_pod_exists() {
local pod_name=${1:?Pod name required}
local namespace=${2:-default}
# Nonzero also includes authorization/connection errors; inspect stderr.
kubectl get pod "$pod_name" -n "$namespace" -o name >/dev/null
}2.5 Init Container Patterns
This bounded-loop example waits for DNS discovery. DNS success does not imply database readiness; the application needs connection retries or a database-specific readiness check. Prepare the mysql Service and custom myapp image. Kubelet can restart a failed init container, so this is distinct from a total Pod startup deadline.
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
initContainers:
- name: wait-for-db-dns
image: busybox:1.37.0
command:
- sh
- -c
- |
for attempt in $(seq 1 60); do
nslookup mysql.default.svc.cluster.local >/dev/null 2>&1 && exit 0
sleep 2
done
echo "Database Service DNS did not become available" >&2
exit 1
containers:
- name: app
image: myapp:1.03. Text Processing Tools
3.1 grep with kubectl
kubectl get pods --field-selector=status.phase!=Running
kubectl logs nginx-pod | grep -i error3.2 awk Field Extraction
kubectl get pods | awk 'NR>1 {print $1}'
kubectl get pods --no-headers | awk '$3 != "Running" {print $1, $3}'3.3 sed Editing
# Text-only preview; this can match more than the intended YAML field.
sed 's/replicas: [0-9]*/replicas: 5/' deployment.yaml
# For a structured edit, use the yq example below.3.4 JSON Parsing with jq
kubectl get pod nginx -o json | jq '.metadata.name'
kubectl get pods -o json | jq -r '.items[].metadata.name'3.5 YAML Parsing with yq
These examples use Mike Farah yq v4; Python yq has different options.
yq '.metadata.name' deployment.yaml
yq -i '.spec.replicas = 5' deployment.yaml4. SSH and Remote Access
4.1 SSH Key Generation
ssh-keygen -t ed25519 -C "your_email@example.com"4.2 SSH Tunneling
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:localhost:80 user@server
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:6443:kubernetes-api:6443 user@bastionFor API tunnels, retain the original CA and TLS server name in kubeconfig. When connecting to 127.0.0.1, set tls-server-name to the actual API certificate name; keep TLS verification enabled.
4.3 Bastion Host Usage
ssh -J bastion user@internal-server4.4 rsync
rsync -avzP ./local/ user@remote:/path/5. Performance Monitoring and Troubleshooting
5.1 top and htop
top -b -n 1 | head -205.2 vmstat and iostat
vmstat 1 5
iostat -dx 1 55.3 free and df
free -h
df -h5.4 kubectl top
Requires a metrics.k8s.io provider such as Metrics Server; kubectl top is not a historical monitoring store.
kubectl top nodes
kubectl top pods --sort-by=memory6. Storage Management Basics
6.1 lsblk
lsblk -f6.2 LVM
# Use only an explicitly selected empty training disk. These commands write storage metadata.
: "${LAB_DISK:?Set an unused lab block device after checking lsblk and backups}"
lsblk -f "$LAB_DISK"
sudo wipefs --no-act "$LAB_DISK"
# Stop if the disk contains data, mounted filesystems, or existing volume metadata.
sudo pvcreate "$LAB_DISK"
sudo vgcreate data_vg "$LAB_DISK"
sudo lvcreate -l 100%FREE -n data_lv data_vg6.3 Kubernetes PV/PVC
The path and hostname below must match the node where the existing filesystem is mounted.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 100Gi
accessModes: [ReadWriteOnce]
storageClassName: local-storage
persistentVolumeReclaimPolicy: Retain
local:
path: /mnt/disks/vol1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: [replace-with-actual-node-hostname]
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-pvc
spec:
storageClassName: local-storage
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 10GiLocal storage cannot move to another node after a node failure. This StorageClass does not provision disks; the PVC may remain Pending until a consumer Pod is scheduled. Match PV capacity to the real filesystem: the advertised value is not a directory quota. Retain cleanup/reuse is a separate operator action.
7. curl and API Calls
7.1 HTTP Methods
curl -X POST -H "Content-Type: application/json" -d '{"name":"John"}' https://api.example.com/users7.2 Kubernetes API Calls
# Run inside a Pod with projected ServiceAccount credentials and curl installed.
set -e
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
CACERT="$SERVICEACCOUNT/ca.crt"
NAMESPACE=$(cat "$SERVICEACCOUNT/namespace")
TOKEN=$(cat "$SERVICEACCOUNT/token")
curl --fail --silent --show-error --cacert "$CACERT" \
-H "Authorization: Bearer $TOKEN" \
"https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods"
unset TOKENThe ServiceAccount needs pods list RBAC permission in that namespace. These files may be absent with automountServiceAccountToken: false. Projected tokens rotate, so long-lived clients must reread the file; do not log tokens.
7.3 Useful curl Options
curl --silent --show-error -o /dev/null -w "%{http_code}\n" https://api.example.com/health8. Practical One-Liners Collection
8.1 Kubernetes Operations
kubectl get pods -A | awk '$4 != "Running" && NR>1 {print $1, $2, $4}'
kubectl get pods -A -o json | jq -r '.items[] | select(any((.status.containerStatuses // [])[]; .restartCount > 5)) | [.metadata.namespace, .metadata.name] | @tsv'8.2 Log Analysis
kubectl logs deploy/app --since=1h | grep -i error8.3 Network Debugging
nslookup kubernetes.default.svc.cluster.local
nc -zv service-name 80Conclusion
- Environment Variables: Foundation for K8s ConfigMap/Secret
- Shell Scripting: Essential for init containers, health checks
- Text Processing: Core to kubectl output parsing
- SSH: Important for node debugging
- Performance Monitoring: Foundation of troubleshooting
Previous: Linux Basics | Next: Container Basics
Verification References
- https://kubernetes.io/docs/concepts/storage/volumes/#local
- https://kubernetes.io/docs/concepts/storage/storage-classes/#local
- https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/
- https://kubernetes.io/docs/concepts/configuration/configmap/
- https://kubernetes.io/docs/reference/kubectl/generated/kubectl_wait/
- https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
- https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
- https://download.samba.org/pub/rsync/rsync.1
- https://github.com/mikefarah/yq
- https://busybox.net/downloads/BusyBox.html
- https://github.com/docker-library/official-images/blob/master/library/busybox