Kubectl tips and tricks

Earlier this year I gave a talk at a Kubernetes meetup around this topic, might be of interest as well: http://mhausenblas.info/kubectl-in-action/

4 Likes

I’m learning how to make custom resources and custom controllers, and I’ve ended up making a kubectl custom plugin for the k8s.io/sample-controller’s Foo resource:


The nice thing about kubectl custom plugins is that you can write them in any language you want.

6 Likes

I have been happy with complete-alias for Bash. In addition to stuff like k=kubectl, it works well for things like gco='git checkout'.

1 Like

The most important tip I would like to share with all

kubectl [...] --v=8 to display detail req/rsp during your call

5 Likes

Run a shell in a new pod (to examine the kubernetes environment from the inside):

alias kshell='kubectl run -it shell --image giantswarm/tiny-tools --restart Never --rm -- sh'

--restart Never” ensures that only a pod resource is created (instead of a deployment, replicaset and pod)
--rm” ensures the pod is deleted when you exit the shell

Of course, if you have existing pods, it may be easier to just run kubectl exec ... sh in one of them (but the container might not have tools like dig, ping, curl, …)

7 Likes

If somebody needs the same as kubectx and kubens for kubecfg see my forked version =>

#dump kubernetes manifests to json
#Ex usage: "kdump -e default -o staging" will export the cluster state to "./staging.json" excluding the "kube-system" and "default" namespaces.

kdumpusage() { echo "Usage: $0 [-e namespace  to exclude from backups] [-o name]" 1>&2; }

function kdump () {
	while getopts ":e:o:" i; do
	    case "${i}" in
	        e)
	            e=${OPTARG}
	            ;;
	        o)
	            o=${OPTARG}
	            ;;
	        *)
	            kdumpusage
	            ;;
	    esac
	done
	shift $((OPTIND-1))

	if [ -z "${e}" ] || [ -z "${o}" ]; then
	    kdumpusage
	fi

	for ns in $(kubectl get ns --no-headers | cut -d " " -f1); do
	  if { [ "$ns" != "kube-system" ]; }; then
	  kubectl --namespace="${ns}" get --export -o=json svc,rc,rs,deployments,cm,secrets,ds,statefulsets,ing,pv,pvc | \
	jq '.items[] |
	    select(.type!="kubernetes.io/service-account-token") |
	    del(
	        .spec.clusterIP,
	        .metadata.uid,
	        .metadata.selfLink,
	        .metadata.resourceVersion,
	        .metadata.creationTimestamp,
	        .metadata.generation,
	        .status,
	        .spec.template.spec.securityContext,
	        .spec.template.spec.dnsPolicy,
	        .spec.template.spec.terminationGracePeriodSeconds,
	        .spec.template.spec.restartPolicy
	    )' >> "./$o.json"
	  fi
	done
}

# quickly terminate stuck pods
function kfp () {
	for ns in $(kubectl get ns --no-headers | cut -d " " -f1); do
		kubectl get pods --namespace="${ns}" | grep 'CrashLoopBackOff\|Error\|Terminating\|ImagePullBackOff\|Pending\|ErrImagePull\|Unknown' | cut -d " " -f 1 | xargs -n 1 kubectl delete pod --namespace="${ns}" --grace-period=0 --force
	done
}
2 Likes

A cople of months ago I write a little article ( in Spanish ) to have some tools ready on the terminal, maybe could be interesting for someone:

A small go tool to merge kubernetes contexts to your ~/.kube/config is k8s-ctx-import

For example: cat <kubeconfig> | k8s-ctx-import to import <kubeconfig>'s active context to your kubeconfig in $KUBECONFIG

1 Like

in the jx binary from Jenkins X we added a bunch of handy sub commands for switching namespaces/contexts visually or via CLI arguments

e.g. to switch namespaces just type:

jx ns

and you are prompted with a list of namespaces to choose from. To switch contexts:

the next one is Jenkins X specific - it requires Jenkins X Environment CRDs - but can switch between environments via:

jx env

this then prompts you with your environments (say Dev, Staging, Production without having to worry what the physical namespaces are etc)

jx ctx

the command I love the most though is sometimes you want to switch contexts/namespaces in just 1 shell only (e.g. to tinker on some production cluster). To do that use

jx shell

Then the context updates and the prompt changes to show the new context/namespace - but all other shells stay on the same namespace/context! Then just exit to get back to the global shared context. Super handy

A couple more:

jx rsh

opens a remote shell giving a list of the pods to pick from. You can supply a filter if you prefer (such as a deployment name).

jx log

As above tails the log of the latest pod from a picked list of pods or takes a deployment filter name. Its handy as the log rolls over to the next pod as pods rollover or restart etc

3 Likes

Yes I do and it works, and autocompletion works too.
The only thing is it does not work with the ‘watch’ command (watch k get pods). In this case I use ‘watch kubectl get pods’.

I even have the alias g=gcloud, because I am on GCP

Thanks

1 Like

Fuzzy search kube contexts and easily switch. (Requires fzf)

alias kctx='kubectl config use-context $(kubectl config get-contexts -o=name | fzf)'
:eyes: https://asciinema.org/a/dltaxEgFpmTzHp4ihhEtZLAKX

1 Like

I made two kubectl plugins. Please try them if you like! :sunglasses:

3 Likes

Hi

I found a little useful tool : shows kubernetes secret with values base64 decoded


e.g :

kubectl get secret my-secret -o yaml | ksd
2 Likes

Update all files stored in ConfigMap at once (Slack #kubernetes-user, thanks @liggitt):

kubectl create configmap your_configmap_here --from-file=/path/to/dir --dry-run -o yaml | kubectl replace -f -

Get all pod names under service / endpoint

kubectl get ep svc_name -n ns -o jsonpath='{range .subsets[*].addresses[*]}{.targetRef.name}{"\n"}{end}'

Get not tainted node(s)

kubectl get nodes -o go-template='{{range .items}}{{if not .spec.taints}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}'

6 Likes

Grab more data from pods

Kubectl get pods -o wide ( will show data such as node which is running on)

Show resources

Kubectl top

The following prepares the ubuntu nodes

#!/bin/bash

apt-get update
apt-get install -y docker.io

cat << EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
systemctl is-enabled kubelet && systemctl is-active kubelet

Kubernetes node restart
systemctl is-enabled kubelet && systemctl is-active kubelet

Solution

  1. kubeadm reset

  2. systemctl restart kubelet

  3. kubeadm init --skip-preflight-checks --pod-network-cidr=10.244.0.0/16

I figured out long time ago, this was because the default bash by osx. The solution: upgrade bash
brew install bash
[ -e "$(which bash)" ] && [ "$(grep $(which bash) /etc/shells)" == "" ] && (echo "$(which bash)" | sudo tee -a /etc/shells) && chsh -s "$(which bash)"

1 Like

A very usefull tool to get logs from different pods in one stream. This tool helped me a lot. Hope will help someone else :slight_smile:

3 Likes