kubectl cheatsheet (Kubernetes for Mac/OSX)
This is a bit of an extension on some earlier thoughts on using Kubernetes on a Mac/OSX laptop.
Shell completion is a must while you are learning Kubernetes.
kubectl: shell completion
Shell Autocompletion set up guide
In 2019, Apple announced that macOS Catalina would now use Zsh (Z Shell) as the default shell, replacing bash. The zsh extends Bourne shell but with improvements and of course features from Bash, ksh, and tcsh.
Add autoload -Uz compinit; compinit; source <(kubectl completion zsh) to .zshrc if you are using bash still follow the instructions at shell Autocompletion set up guide just use the bash tab on that web page.
Now you should get shell completion for all kubeclt commands (e.g., get pods, get pod, create) and resources hello-fbc47cc98-wlj67.
You might as well do this for minikube too if you are using minikube.
% cat .zshrc autoload -Uz compinit compinit source <(kubectl completion zsh) source <(minikube completion zsh)
.zshrc
autoload -Uz compinit compinit source <(kubectl completion zsh) ...
kubectl: Check Liveness and show pod events using describe
kubectl describe can describe a node, pod or label. It also shows liveness events from a pod.
kubectl describe pod hello-fbc47cc98-wlj67
kubectl: Get information on k8s object document (API) schema using kubectl explain
kubectl explain describes fields for supported resources. The fields are identified using a JSONPath identifier.
This command describes the fields associated with each supported API resource. Fields are identified using a simple JSONPath identifier:
% kubectl explain deploy.spec.replicas KIND: Deployment VERSION: extensions/v1beta1 FIELD: replicas <integer> DESCRIPTION: Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1
kubectl: Watch for changes using kubectl get pods --watch
After getting the pods, watch for changes to pods. This command is useful after you run a large helm install and want to see if the associated pods are ready. Many kubectl have a --watch option to watch for changes.
% kubectl get pods --watch NAME READY STATUS RESTARTS AGE hello-547ffd886c-khfbp 1/1 Running 0 4d15h lumpy-arachnid-prometheus-alertmanager-79ff6d8bcf-ql27z 2/2 Running 0 4d18h lumpy-arachnid-prometheus-kube-state-metrics-f46d484-k8mj6 1/1 Running 0 4d18h lumpy-arachnid-prometheus-node-exporter-sf7vb 1/1 Running 0 4d18h lumpy-arachnid-prometheus-pushgateway-84b5f94d76-cpkjn 1/1 Running 0 4d18h lumpy-arachnid-prometheus-server-567f96c6bf-kzn2m 2/2 Running 0 4d18h solemn-salamander-jenkins-555df964d5-8vfbd 1/1 Running 0 4d18h
It works with other resources as well, e.g., namespaces kubectl get namespaces --watch.
kubectl: edit k8s objects
The kubectl edit command allows you to directly edit k8s objects and resource. This command is useful for debugging and testing.
% kubectl edit deployments hello deployment.extensions/hello edited
This goes nicely with the watch command above.
% kubectl get pods --watch NAME READY STATUS RESTARTS AGE hello-547ffd886c-8bwrq 0/1 Running 0 10s hello-547ffd886c-khfbp 1/1 Running 0 4d15h lumpy-arachnid-prometheus-alertmanager-79ff6d8bcf-ql27z 2/2 Running 0 4d18h lumpy-arachnid-prometheus-kube-state-metrics-f46d484-k8mj6 1/1 Running 0 4d18h lumpy-arachnid-prometheus-node-exporter-sf7vb 1/1 Running 0 4d18h lumpy-arachnid-prometheus-pushgateway-84b5f94d76-cpkjn 1/1 Running 0 4d18h lumpy-arachnid-prometheus-server-567f96c6bf-kzn2m 2/2 Running 0 4d18h solemn-salamander-jenkins-555df964d5-8vfbd 1/1 Running 0 4d18h hello-547ffd886c-8bwrq 1/1 Running 0 41s
See how hello pod replica (hello-547ffd886c-8bwrq) is added as not ready and then changes to ready. This console output happens because I changed the replica count to 2 in the deployment file.
kubectl: get the YAML of a k8s object use -o yaml
You can use -o yaml to get a starter yaml file to edit. (Take off the state and event data from the yaml file).
% kubectl get deployment hello -o yaml
Full example
% kubectl get deployment hello -o yaml > newDeployment.yaml
Edit file and change replica count back to 1 (vi newDeployment.yaml). Then run a diff before you rerun.
kubectl: diff
kubectl diff -f newDeployment.yaml ... spec: progressDeadlineSeconds: 600 - replicas: 2 + replicas: 1 ...
You should always use diff and see if the changes match your expectations just in case someone manually changed files and did not check those changes into git.
Once satisfied, use apply to apply the changes.
kubectl: apply
% kubectl apply -f newDeployment.yaml
This applied the changes that we edited and diffed earlier. If you check (kubectl get deployment hello -o yaml), you will see the replica count is back to 1.
kubectl: view logs
% kubectl logs -n default hello-547ffd886c-khfbp
To follow a pod's log.
% kubectl logs -n default --follow hello-547ffd886c-khfbp
kubectl: debug deploy issues
Let's say you have an RBAC permission error, you may want to view the K8s API server. Let's show how to do that.
First, remember the system namespace.
% kubectl get namespaces NAME STATUS AGE default Active 4d19h kube-node-lease Active 4d19h kube-public Active 4d19h kube-system Active 4d19h kubernetes-dashboard Active 4d19h
List the pods in the system namespace.
% kubectl -n kube-system get pods NAME READY STATUS RESTARTS AGE coredns-5c98db65d4-8dsh6 1/1 Running 0 4d19h coredns-5c98db65d4-lfgb4 1/1 Running 0 4d19h elasticsearch-logging-w98q5 1/1 Running 0 4d19h etcd-minikube 1/1 Running 0 4d19h fluentd-es-hfl7s 1/1 Running 0 4d19h heapster-9j8bw 1/1 Running 0 4d19h influxdb-grafana-9fln9 2/2 Running 0 4d19h kibana-logging-fplvw 1/1 Running 0 4d19h kube-addon-manager-minikube 1/1 Running 0 4d19h kube-apiserver-minikube 1/1 Running 0 4d19h kube-controller-manager-minikube 1/1 Running 0 4d19h kube-proxy-f2q87 1/1 Running 0 4d19h kube-scheduler-minikube 1/1 Running 0 4d19h logviewer-8664c4bdcd-4gfjh 1/1 Running 0 4d19h nginx-ingress-controller-778fcbd96-dgcdm 1/1 Running 0 4d19h storage-provisioner 1/1 Running 0 4d19h tiller-deploy-548fd5dc4f-fcvrt 1/1 Running 0 4d19h
kubectl watch the k8s api server log
% kubectl logs -n kube-system -f --tail 10 kube-apiserver-minikube
kubectl watch the etcd server log
% kubectl logs -n kube-system -f --tail 10 etcd-minikube
Make a change like an edit the deployment, as shown earlier. See if you see anything in the logs.
kubectl attach to the container
% kubectl attach hello-547ffd886c-khfbp
If you want to see the output directly without logging, do the following.
kubectl run a shell in a container
% kubectl exec -it hello-547ffd886c-khfbp bin/sh sh-4.2# ls app boot etc lib media opt root sbin sys usr bin dev home lib64 mnt proc run srv tmp var
The kubectl exec command just runs a shell inside of an existing pod (first container in the pod if you don't specify a container.)
The kubectl run creates and runs a particular image. This command includes creating a deployment or job to manage the created container.
kubectl: run a command inside of an image (debugging)
% kubectl run hello6 --generator=run-pod/v1 --image cloudurable/spring_boot_k8s:0.4.0 \ --attach=true --command --restart=Never -- echo "hi mom" hi mom
kubectl: delete Clean up our misfires.
% kubectl delete pod hello pod "hello" deleted % kubectl delete pod hello2 pod "hello2" deleted % kubectl delete pod hello3 pod "hello3" deleted % kubectl delete pod hello4 pod "hello4" deleted % kubectl delete pod hello5 pod "hello5" deleted % kubectl delete pod hello6
I added this for comical relief. It took me six tries to get kubectl run to work the way I wanted it to.
kubectl: Cluster info for debugging
% kubectl cluster-info Kubernetes master is running at https://192.168.64.4:8443 KubeDNS is running at https://192.168.64.4:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To really debug what is going on with a cluster try cluster-info dump.
The kubectl cluster-info dump subcommand dumps all of the cluster info which is useful for debugging and troubleshooting cluster problems. The command dumps everything to stdout or a subdirectory, as shown above. More importantly, it dumps all of the logs for every pod in the cluster per namespace and pods.
% kubectl cluster-info dump `` You can also log to a directory. ```sh (? |k8s-kafka:default) % mkdir dump (? |k8s-kafka:default) % kubectl cluster-info dump --output-directory ./dump Cluster info dumped to ./dump (? |k8s-kafka:default) % cd dump (? |k8s-kafka:default) % atom .
kubectl: Context
To solve the problem of accessing several k8s environments from the same laptop, kubectl has the concept of contexts. This way you can manage a local cluster (minikube, Kind, Rancher K3s, Docker Desktop K8s), and your production cluster (Azure AKS, AWS EKS, Google GKE, Rancher, etc.)
% kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * minikube minikube minikube app01 gke-p prod prod_team app01 gke-i integration qa_team app01 eks RandD dev_team app01
You can also create a new context to manage a different cluster environment.
kubectl config set-context gke-p2 --cluster=eks --namespace=app01 Context "gke-p2" created.
Working with K8s namespaces and context
Use kube-ps1, kubens, and kubectx to manage k8s namespaces and contexts. See install instructions for your OS at kubectx. You will also want to install kube-ps1 to see your current context and namespace.
Install kubectx, kubens, and kube-ps1 on mac / osx
brew update brew install kubectx brew install kube-ps1
Add kube-ps1 to your shell
~ % cat .zshrc autoload -Uz compinit compinit source <(kubectl completion zsh) source <(minikube completion zsh) source "/usr/local/opt/kube-ps1/share/kube-ps1.sh" PS1='$(kube_ps1)'$PS1 ...
Using kubectx and kube-ps1
% kubectl config set-context sys --cluster=minikube --namespace=kube-system Context "sys" created. (? |minikube:default)richardhightower@Richards-MacBook-Pro ~ % kubectx sys Switched to context "sys". (? |sys:kube-system) ~ % kubectx - Switched to context "minikube". (? |minikube:default) ~ % kubectl get pods NAME READY STATUS RESTARTS AGE hello-547ffd886c-khfbp 1/1 Running 1 5d11h lumpy-arachnid-prometheus-alertmanager-79ff6d8bcf-ql27z 2/2 Running 2 5d13h lumpy-arachnid-prometheus-kube-state-metrics-f46d484-k8mj6 1/1 Running 1 5d13h lumpy-arachnid-prometheus-node-exporter-sf7vb 1/1 Running 1 5d13h lumpy-arachnid-prometheus-pushgateway-84b5f94d76-cpkjn 1/1 Running 1 5d13h lumpy-arachnid-prometheus-server-567f96c6bf-kzn2m 2/2 Running 2 5d13h solemn-salamander-jenkins-555df964d5-8vfbd 1/1 Running 1 5d13h (? |minikube:default)~ % kubens default kube-node-lease kube-public kube-system kubernetes-dashboard (? |minikube:default) ~ % kubens default Context "minikube" modified. Active namespace is "default". (? |minikube:default) ~ % kubens kube-system Context "minikube" modified. Active namespace is "kube-system". (? |minikube:kube-system) ~ % kubectl get pods NAME READY STATUS RESTARTS AGE coredns-5644d7b6d9-9925c 1/1 Running 0 10m coredns-5644d7b6d9-nk7l4 1/1 Running 0 10m elasticsearch-logging-w98q5 1/1 Running 1 5d14h etcd-minikube 1/1 Running 0 10m fluentd-es-hfl7s 1/1 Running 1 5d14h heapster-9j8bw 1/1 Running 1 5d14h influxdb-grafana-9fln9 2/2 Running 2 5d14h kibana-logging-fplvw 1/1 Running 1 5d14h kube-addon-manager-minikube 1/1 Running 0 10m kube-apiserver-minikube 1/1 Running 0 10m kube-controller-manager-minikube 1/1 Running 0 10m kube-proxy-dpp4d 1/1 Running 0 10m kube-scheduler-minikube 1/1 Running 0 10m logviewer-8664c4bdcd-4gfjh 1/1 Running 1 5d14h nginx-ingress-controller-778fcbd96-dgcdm 1/1 Running 1 5d14h storage-provisioner 1/1 Running 1 5d14h tiller-deploy-548fd5dc4f-fcvrt 1/1 Running 1 5d14h (? |minikube:kube-system) ~ % kubens default Context "minikube" modified. Active namespace is "default". (? |minikube:default) ~ % kubectl get pods NAME READY STATUS RESTARTS AGE hello-547ffd886c-khfbp 1/1 Running 1 5d11h lumpy-arachnid-prometheus-alertmanager-79ff6d8bcf-ql27z 2/2 Running 2 5d13h lumpy-arachnid-prometheus-kube-state-metrics-f46d484-k8mj6 1/1 Running 1 5d13h lumpy-arachnid-prometheus-node-exporter-sf7vb 1/1 Running 1 5d13h lumpy-arachnid-prometheus-pushgateway-84b5f94d76-cpkjn 1/1 Running 1 5d13h lumpy-arachnid-prometheus-server-567f96c6bf-kzn2m 2/2 Running 2 5d13h solemn-salamander-jenkins-555df964d5-8vfbd 1/1 Running 1 5d13h
You may also consider kube-sh. The kubed-sh is "the Kubernetes distributed shell for the casual cluster user." and "lets you execute a program in a Kubernetes cluster without having to create a container image or learn new concepts."
More to come.
Check out this slide deck on digital transformation and accelerating your DevOps experience.