When working with Kubernetes, developers often find themselves typing the same commands repeatedly. While kubectl
is a powerful tool, its verbosity can slow down common workflows. This guide will explore practical aliases and functions to streamline your Kubernetes development experience, with a focus on container access patterns.
Let's start with some fundamental aliases that form the building blocks of more complex functions:
# Basic kubectl aliases
alias k="kubectl"
alias kg="kubectl get"
alias kd="kubectl describe"
alias kdel="kubectl delete"
alias kn="kubectl -n" # namespace shorthand
# Pod-specific aliases
alias kgp="kubectl get pods"
alias kgpw="kubectl get pods -o wide"
alias kgpa="kubectl get pods --all-namespaces"
# Context and configuration aliases
alias kc="kubectl config"
alias kcc="kubectl config current-context"
alias kcg="kubectl config get-contexts"
JSONPath is a powerful tool for extracting specific information from Kubernetes resources. Here are some useful patterns:
# Get all pod names in a specific namespace
alias kgpn="kubectl get pods -o jsonpath='{.items[*].metadata.name}'"
# Get all container images running in all pods
alias kgpi="kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'"
# Get pod name and status
alias kgps="kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{.status.phase}{\"\\n\"}{end}'"
# Get pod name and IP
alias kgpip="kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{.status.podIP}{\"\\n\"}{end}'"
# Complex multi-container pod information
function kpodinfo() {
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{range .spec.containers[*]} - {.name}: {.image}{"\\n"}{end}{"\\n"}{end}'
}
# Get the first web pod name
alias kgwp="kubectl get pods -l component=rails,role=web --output=jsonpath='{.items[0].metadata.name}'"
# SSH into the web pod
function kwssh() {
kubectl exec -it `kgwp -n $1` -n "$1" -- bash
}
function kexec() {
local ns="${1:-default}"
local pod_pattern="$2"
local cmd="${3:-bash}"
local pod_count=$(kubectl get pods -n "$ns" | grep -c "$pod_pattern")
if [ $pod_count -eq 0 ]; then
echo "No pods found matching pattern: $pod_pattern"
return 1
elif [ $pod_count -gt 1 ]; then
echo "Multiple pods found matching pattern: $pod_pattern"
kubectl get pods -n "$ns" | grep "$pod_pattern"
echo "Please specify a more precise pattern"
return 1
fi
local pod=$(kubectl get pods -n "$ns" | grep "$pod_pattern" | awk '{print $1}')
echo "Executing $cmd on pod: $pod"
kubectl exec -it -n "$ns" "$pod" -- $cmd
}
function kexec_container() {
local ns="${1:-default}"
local pod="$2"
local container="$3"
local cmd="${4:-bash}"
if [ -z "$container" ]; then
# List available containers
echo "Available containers:"
kubectl get pod "$pod" -n "$ns" -o jsonpath='{.spec.containers[*].name}'
echo
return 1
fi
kubectl exec -it -n "$ns" "$pod" -c "$container" -- $cmd
}
function debug_example() {
set -x # Enable tracing
set -e # Exit on error
set -u # Error on undefined variables
set -o pipefail # Exit on pipe failures
# Your code here
set +x # Disable tracing
set +e # Disable exit on error
set +u # Disable error on undefined variables
set +o pipefail # Disable exit on pipe failures
}
# Enhanced debugging output
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
function debug_with_trace() {
local old_ps4=$PS4
export PS4='${FUNCNAME[0]:+${FUNCNAME[0]}(): }($LINENO): '
set -x
# Your code here
set +x
export PS4=$old_ps4
}
function param_debug() {
echo "Function Name: ${FUNCNAME[0]}"
echo "Number of Parameters: $#"
echo "All Parameters: $*"
echo "Parameter Array: $@"
for i in $(seq 1 $#); do
echo "Parameter $i: ${!i}"
done
# Stack trace
echo "Call stack:"
local frame=0
while caller $frame; do
((frame++))
done
}
function kexec_debug() {
kubectl exec -it -v=8 `kgwp -n $1` -n "$1" -- bash
}
function kexec_dry() {
kubectl exec -it --dry-run=client `kgwp -n $1` -n "$1" -- bash
}
function kpod_debug() {
echo "Pod Details:"
kubectl get pod `kgwp -n $1` -n "$1" -o yaml
echo "Pod Status:"
kubectl describe pod `kgwp -n $1` -n "$1"
}
function robust_kexec() {
# Parameter validation
if [ $# -lt 1 ]; then
echo "Usage: robust_kexec <namespace> [pod_pattern] [command]"
return 1
}
local ns="$1"
local pattern="${2:-web}"
local cmd="${3:-bash}"
# Namespace validation
if ! kubectl get ns "$ns" &>/dev/null; then
echo "Error: Namespace '$ns' does not exist"
return 1
}
# Pod existence check
local pod
if ! pod=$(kubectl get pods -n "$ns" -l "component=rails,role=$pattern" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); then
echo "Error: No pods found matching pattern '$pattern' in namespace '$ns'"
return 1
}
# Container readiness check
local ready
ready=$(kubectl get pod "$pod" -n "$ns" -o jsonpath='{.status.containerStatuses[0].ready}')
if [ "$ready" != "true" ]; then
echo "Warning: Pod '$pod' is not ready"
kubectl get pod "$pod" -n "$ns"
read -p "Continue anyway? (y/N) " confirm
if [ "$confirm" != "y" ]; then
return 1
fi
}
# Execute with full error handling
echo "Executing '$cmd' on pod '$pod' in namespace '$ns'"
if ! kubectl exec -it -n "$ns" "$pod" -- $cmd; then
echo "Error: Command execution failed"
return 1
fi
}
# Array handling in Bash
function bash_kexec() {
local pods=($(\kubectl get pods -n "$1" -o name))
select pod in "${pods[@]}"; do
kubectl exec -it -n "$1" "${pod##*/}" -- bash
break
done
}
# Array handling in Zsh
function zsh_kexec() {
local -a pods
pods=("${(@f)$(kubectl get pods -n "$1" -o name)}")
select pod in $pods; do
kubectl exec -it -n "$1" "${pod:t}" -- bash
break
done
}
function compatible_kexec() {
# Use while read for better compatibility
kubectl get pods -n "$1" -o name | while read -r pod; do
pod=${pod##*/} # Remove prefix in a compatible way
kubectl exec -it -n "$1" "$pod" -- bash
break
done
}
# Watch pods with custom columns
function kwatch_pods() {
local ns="${1:-default}"
kubectl get pods -n "$ns" -w -o custom-columns=\
NAME:.metadata.name,\
STATUS:.status.phase,\
READY:.status.containerStatuses[0].ready,\
RESTARTS:.status.containerStatuses[0].restartCount,\
AGE:.metadata.creationTimestamp
}
# Monitor pod resource usage
function kresources() {
local ns="${1:-default}"
kubectl top pods -n "$ns" --containers
}
# Tail logs from multiple pods
function klogs_all() {
local ns="${1:-default}"
local label="$2"
local pods=$(kubectl get pods -n "$ns" -l "$label" -o name)
for pod in $pods; do
kubectl logs -f "$pod" -n "$ns" &
done
wait
}
# Search logs across pods
function klogs_search() {
local ns="${1:-default}"
local pattern="$2"
local since="${3:-1h}"
kubectl get pods -n "$ns" -o name | while read -r pod; do
echo "=== $pod ==="
kubectl logs --since=$since "$pod" -n "$ns" | grep -i "$pattern"
done
}
- Documentation and Help
function k8s_help() {
cat << EOF
Available Kubernetes Helper Functions:
kexec <namespace> [pod_pattern] [command] - Execute command in pod
klogs_all <namespace> <label> - Tail logs from all matching pods
kwatch_pods <namespace> - Watch pods with detailed info
kresources <namespace> - Show resource usage
Common Aliases:
kgp - kubectl get pods
kgpa - kubectl get pods --all-namespaces
kd - kubectl describe
Usage Examples:
kexec production web-app bash
klogs_all staging app=frontend
kwatch_pods development
EOF
}
- Configuration Management
# Save commonly used settings
function ksave_config() {
local name="$1"
local ns="$2"
local context="$3"
kubectl config set-context "$name" --namespace="$ns" --cluster="$context"
kubectl config use-context "$name"
}
# Quick context switching with namespace
function kctx() {
if [ $# -eq 0 ]; then
kubectl config get-contexts
else
kubectl config use-context "$1"
[ -n "$2" ] && kubectl config set-context --current --namespace="$2"
fi
}
- Cleanup Functions
# Clean up completed pods
function kcleanup() {
local ns="${1:-default}"
kubectl delete pods --field-selector=status.phase=Succeeded -n "$ns"
kubectl delete pods --field-selector=status.phase=Failed -n "$ns"
}
Creating effective Kubernetes aliases and functions can significantly improve your development workflow. The key is to:
- Build robust, reusable functions
- Include proper error handling
- Add helpful debug capabilities
- Make functions shell-agnostic when possible
- Document your functions well
Remember to periodically review and update your aliases as your workflow evolves and new Kubernetes features become available.