📜 ⬆️ ⬇️

Useful commands and tips when working with Kubernetes through the kubectl console utility

Translator's Foreword : This article is a combination of the translation of two materials from the CoreOS project (see links at the end of the publication) on working with the console tool for executing commands on Kubernetes- kubectl clusters . The listing provided by the original author for Mac OS X was adapted for Linux, in other listings the YAML formatting was corrected, and for ease of reading all the material, subtitles were added to it.

Kubectl is a tool that is familiar to users of Kubernetes and has extensive functionality. Mastering them takes time, but allows you to see that this is a more powerful tool than many have assumed. I present a set of tips to improve your capabilities when working with kubectl . Do not forget to look at the cheat sheet in the official documentation section Kubernetes!

Automatic addition to the shell


kubectl has excellent built-in autocompletion for bash and zsh, which makes it much easier to work with commands, flags, and objects like namespaces and subnames. The documentation has ready-made instructions for its inclusion. And the GIF animation below shows how autocompletion works:


')
 #        Bash source <(kubectl completion bash) # …           .bashrc mkdir ~/.kube kubectl completion bash > ~/.kube/completion.bash.inc printf "\n# Kubectl shell completion\nsource '$HOME/.kube/completion.bash.inc'\n" >> $HOME/.bashrc source $HOME/.bashrc #  —        Zsh source <(kubectl completion zsh) 

Merging configs with contexts via KUBECONFIG


Kubernetes configuration merging is a popular pattern if you interact with many Kubernetes clusters. When working with different configs, the concept of context ( context ) is used, indicating the parameters that kubectl will use to search for a specific, target cluster. But to achieve the desired result with contexts can be difficult. To simplify your life, use the KUBECONFIG environment KUBECONFIG - it allows you to point to the configuration files that are used during the merge. More information about KUBECONFIG can be found in the official documentation .

For example, you have two Kubernetes config for different clusters, and you need to merge them.

Config of the first cluster:

 $ kubectl config view --minify > cluster1-config 

 apiVersion: v1 clusters: - cluster: certificate-authority: cluster1_ca.crt server: https://cluster1 name: cluster1 contexts: - context: cluster: cluster1 user: cluster1 name: cluster1 current-context: cluster1 kind: Config preferences: {} users: - name: cluster1 user: client-certificate: cluster1_apiserver.crt client-key: cluster1_apiserver.key 

Config of the second cluster:

 $ cat cluster2-config 

 apiVersion: v1 clusters: - cluster: certificate-authority: cluster2_ca.crt server: https://cluster2 name: cluster2 contexts: - context: cluster: cluster2 user: cluster2 name: cluster2 current-context: cluster2 kind: Config preferences: {} users: - name: cluster2 user: client-certificate: cluster2_apiserver.crt client-key: cluster2_apiserver.key 

They can be merged using KUBECONFIG . The advantage of this merge will be the ability to dynamically switch between contexts. A context is a “map” (map) that includes the descriptions of the cluster and the user, as well as the name by which the configuration can be referenced for cluster authentication and interaction with it. The --kubeconfig flag allows you to look at the context for each file:

 $ kubectl --kubeconfig=cluster1-config config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * cluster1 cluster1 cluster1 $ kubectl --kubeconfig=cluster2-config config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * cluster2 cluster2 cluster2 

Each configuration file has a single context, so they do not conflict with each other. Merging the two files through KUBECONFIG shows both contexts. To save the current context, create a new empty file with the name cluster-merge :

 $ export KUBECONFIG=cluster-merge:cluster-config:cluster2-config dcooley@lynx ~ $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * cluster1 cluster1 cluster1 cluster2 cluster2 cluster2 

The list of files exported from KUBECONFIG is loaded in a strict order. Therefore, the context that is selected corresponds to the one specified as current-context in the first config. Changing the context to cluster2 shifts the sign of the current ( * ) to this context in the list, and the kubectl begin to apply to this (second) context:

 $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * cluster1 cluster1 cluster1 cluster2 cluster2 cluster2 $ kubectl config use-context cluster2 Switched to context "cluster2". $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE cluster1 cluster1 cluster1 * cluster2 cluster2 cluster2 $ cat cluster-merge 

 apiVersion: v1 clusters: [] contexts: [] current-context: cluster2 kind: Config preferences: {} users: [] 

It remains only to maintain the correct value of current-context . You can use Kubernetes contexts and merge them in different ways. For example, you can create a context ( cluster1_kube-system ) that will define the namespace ( kube-system ) for all kubectl executable commands:

 $ kubectl config set-context cluster1_kube-system --cluster=cluster1 --namespace=kube-system --user=cluster1 Context "cluster1_kube-system" set. $ cat cluster-merge 

 apiVersion: v1 clusters: [] contexts: - context: cluster: cluster1 namespace: kube-system user: cluster1 name: cluster1_kube-system current-context: cluster2 kind: Config preferences: {} users: [] 

New context can be used like this:

 $ kubectl config use-context cluster1_kube-system Switched to context "cluster1_kube-system". $ kubectl get pods NAME READY STATUS RESTARTS AGE default-http-backend-fwx3g 1/1 Running 0 28m kube-addon-manager-cluster 1/1 Running 0 28m kube-dns-268032401-snq3h 3/3 Running 0 28m kubernetes-dashboard-b0thj 1/1 Running 0 28m nginx-ingress-controller-b15xz 1/1 Running 0 28m 

Learning Kubernetes API


To learn more about the features provided by the Kubernetes API, request the swagger.json file:

 $ kubectl proxy $ curl -O 127.0.0.1:8001/swagger.json 

You can also go to http://localhost:8001/api/ and look at the paths available in Kubernetes API.

Since swagger.json is a JSON document, you can view it with jq . The jq utility is a lightweight JSON file handler that allows you to perform comparisons and other operations. Read more here .

View swagger.json helps to understand the Kubernetes API. This is a complex API, the functions in which are divided into groups, which complicates its perception:

 $ cat swagger.json | jq '.paths | keys[]' "/api/" "/api/v1/" "/api/v1/configmaps" "/api/v1/endpoints" "/api/v1/events" "/api/v1/namespaces" "/api/v1/nodes" "/api/v1/persistentvolumeclaims" "/api/v1/persistentvolumes" "/api/v1/pods" "/api/v1/podtemplates" "/api/v1/replicationcontrollers" "/api/v1/resourcequotas" "/api/v1/secrets" "/api/v1/serviceaccounts" "/api/v1/services" "/apis/" "/apis/apps/" "/apis/apps/v1beta1/" "/apis/apps/v1beta1/statefulsets" "/apis/autoscaling/" "/apis/batch/" "/apis/certificates.k8s.io/" "/apis/extensions/" "/apis/extensions/v1beta1/" "/apis/extensions/v1beta1/daemonsets" "/apis/extensions/v1beta1/deployments" "/apis/extensions/v1beta1/horizontalpodautoscalers" "/apis/extensions/v1beta1/ingresses" "/apis/extensions/v1beta1/jobs" "/apis/extensions/v1beta1/networkpolicies" "/apis/extensions/v1beta1/replicasets" "/apis/extensions/v1beta1/thirdpartyresources" "/apis/policy/" "/apis/policy/v1beta1/poddisruptionbudgets" "/apis/rbac.authorization.k8s.io/" "/apis/storage.k8s.io/" "/logs/" "/version/" 

The following command describes the APIs that are available in the Kubernetes cluster and to which you have access. The command in the example below is executed under the administrator user. If you have RBAC access control enabled, the output may differ:

 $ kubectl api-versions apps/v1beta1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1beta1 autoscaling/v1 batch/v1 batch/v2alpha1 certificates.k8s.io/v1alpha1 coreos.com/v1 etcd.coreos.com/v1beta1 extensions/v1beta1 oidc.coreos.com/v1 policy/v1beta1 rbac.authorization.k8s.io/v1alpha1 storage.k8s.io/v1beta1 v1 

The kubectl explain command helps to better understand what different API components do:

 $ kubectl explain You must specify the type of resource to explain. Valid resource types include: * all * certificatesigningrequests (aka 'csr') * clusters (valid only for federation apiservers) * clusterrolebindings * clusterroles * componentstatuses (aka 'cs') * configmaps (aka 'cm') * daemonsets (aka 'ds') * deployments (aka 'deploy') * endpoints (aka 'ep') * events (aka 'ev') * horizontalpodautoscalers (aka 'hpa') * ingresses (aka 'ing') * jobs * limitranges (aka 'limits') * namespaces (aka 'ns') * networkpolicies * nodes (aka 'no') * persistentvolumeclaims (aka 'pvc') * persistentvolumes (aka 'pv') * pods (aka 'po') * poddisruptionbudgets (aka 'pdb') * podsecuritypolicies (aka 'psp') * podtemplates * replicasets (aka 'rs') * replicationcontrollers (aka 'rc') * resourcequotas (aka 'quota') * rolebindings * roles * secrets * serviceaccounts (aka 'sa') * services (aka 'svc') * statefulsets * storageclasses * thirdpartyresources error: Required resource not specified. See 'kubectl explain -h' for help and examples. 

Try kubectl explain deploy . The explain command works with different levels of nesting, which allows you to also refer to dependent objects:

 $ kubectl explain deploy.spec.template.spec.containers.livenessProbe.exec RESOURCE: exec <Object> DESCRIPTION: One and only one of the following should be specified. Exec specifies the action to take. ExecAction describes a "run in container" action. FIELDS: command <[]string> Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. 

Operations with hems through kubectl


All the following examples use the Kubernetes API to learn something about the subframes. One of the ways to get the necessary data is to build a query and understand what its expression will be needed in terms of jsonpath . For example, you can run kubectl get pods --all-namespaces -o json to see all the output, from which we can then filter the necessary data for an example with sorting pods by time (see below).

If you do not have an application running, to familiarize yourself with the examples, you can create pods with the run = shop label and run them as a service on port 80:

 $ kubectl run shop --replicas=2 --image quay.io/coreos/example-app:v1.0 --port 80 --expose 

Now you can see what we will do with jsonpath . More information on it can be obtained from the official documentation .

Filtering the Kubernetes pods by the time they were created


 $ kubectl get pods --all-namespaces --sort-by='.metadata.creationTimestamp' -o jsonpath='{range .items[*]}{.metadata.name}, {.metadata.creationTimestamp}{"\n"}{end}' 

Search for Kubernetes pod by label selector and view its logs


Specify the namespace ( your-namespace ) and your request for the presence of a label that will help you find the right pitches, and get the logs of these pitches. If under not the only one, logs will be obtained from all the pods in parallel:

 $ ns='<your-namespace>' label='<yourkey>=<yourvalue>' kubectl get pods -n $ns -l $label -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | xargs -I {} kubectl -n $ns logs {} 

Search for Kubernetes pod by label selector and connect to it


Specify the namespace ( your-namespace ) and your request for the presence of a label that will help you find the necessary pitches, and connect to it by name (to the first of the found tabs). Replace the 8080 for the desired hearth port:

 $ ns='<your-namespace>' label='<yourkey>=<yourvalue>' kubectl -n $ns get pod -l $label -o jsonpath='{.items[1].metadata.name}' | xargs -I{} kubectl -n $ns port-forward {} 8080:80 

Operations with nodes (nodes) via kubectl


The combination of jq and jq output kubectl allows you to make complex queries, such as filtering all resources by the time they are created.

Counting the number of pods in the Kubernetes node


Often, high-level statistics help in debugging. This command will calculate the number of all pods on each of the nodes:

 $ kubectl get pods --all-namespaces -o json | jq '.items[] | .spec.nodeName' -r | sort | uniq -c 

Filtering Nodes by Label


Label queries can also be used for nodes. This approach is often used for deployments that require certain restrictions. For more information about selectors, see the output of kubectl explain deployment.spec.selector .

 $ kubectl get nodes -l 'master' or kubectl get nodes -l '!master' 

You can display all labels using the --show-labels argument for any Kubernetes object:

 $ kubectl get nodes --all-namespaces --show-labels 

List of all pods for each node


A JSON document is generated with the name of the Kubernetes node and a list of all the titles of the pods running on this node. Very useful debugging command:

 $ kubectl get pods --all-namespaces -o json | jq '.items | map({podName: .metadata.name, nodeName: .spec.nodeName}) | group_by(.nodeName) | map({nodeName: .[0].nodeName, pods: map(.podName)})' 

Getting external IP for Kubernetes nodes


 $ kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name} {.status.addresses[?(@.type=="ExternalIP")].address}{"\n"}{end}' 

Note : Read in our blog a translation of another article from CoreOS about working with Kubernetes from the console: “ Automating SSH access to Kubernetes nodes using Fabric and integration from CoreOS ”, as well as the note “ Useful utilities when working with Kubernetes ” (it contains mostly console tools).

Sources


Source: https://habr.com/ru/post/333956/


All Articles