Managing resources on a kubernetes cluster using kubectl

Stakater
Stakater
Published in
10 min readJan 22, 2018

If you have been playing with Kubernetes, you should already be familiar with the kubectl command, at least at a basic level. Kubernetes is an open-source tool, originally developed by Google, used for automating deployment and management and auto-scaling of containerized applications. In this article we will be reviewing kubectl and what it is used for in Kubernetes.

kubectl is a powerful command line tool that is used for running commands against Kubernetes clusters. It interacts with the Kubernetes API and its shared state to deploy and manage applications on the Kubernetes cluster.

Install and Setup kubectl

Let’s look at steps required to install kubectl and get it ready for use on Kubernetes cluster. There are different ways you can setup kubectl. One method is by downloading application binary to your OS and make it executable or install it (Windows), and an alternative method involves building the tool from source code available on Github. But the most preferred method is downloading a ready binary file. The method covered here is binary installation.

Install kubectl from binary

Kubectl binary is available on github and can be installed on Linux, Unix and Windows systems.

Prerequisites

  1. Kubernetes cluster already setup. We can do this easily from http://stakater.com
  2. Internet connection
  3. curl or wget tool installed (For Mac and Linux) — refer to your OS documentation on how to install it.
  4. Knowledge of basic Linux/Unix commands; mv, chmod, curl, export — not a must

With all above prerequisites met, proceed to install kubectl.

Run the following commands to install the latest release of kubectl, this covers installation for Linux, MacOS, and Windows.

Linux and MacOS:

Download kubectl binary

curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/darwin/amd64/kubectl

Move the binary to /usr/local/bin/ directory and make it executable.

mv ./kubectl /usr/local/bin/chmod +x /usr/local/bin/kubectl

Make sure /usr/local/bin/ is in your $PATH.

Windows:

For Windows, download the binary from this link and install it like any other normal Windows application.

Check the kubectl configuration

After successful installation, confirm that kubectl has been properly configured by issuing a command which checks cluster state.

$ kubectl cluster-infoKubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use ‘kubectl cluster-info dump’.

If you get a URL response as output, then kubectl is correctly configured and ready for use on your cluster. If you get an error from above command you can dump cluster configuration for further troubleshooting using:

$ kubectl cluster-info dump

To get less content, pipe to head to filter:

$ kubectl cluster-info dump |head
{
“selfLink”: “/api/v1/nodes”,
“resourceVersion”: “29495”,
“Items”: [
{
“name”: “minikube”,
“selfLink”: “/api/v1/nodes/minikube”,
“uid”: “86b7bd31-e550–11e7–8389–080027320547”,
“resourceVersion”: “29493”,
“creationTimestamp”: “2017–12–20T06:39:27Z”,

Enable shell autocompletion for kubectl commands

kubectl comes with built-in bash and zsh completion. This autocompletion is generated by kubectl. It can save you a lot of typing and improve your productivity by autocompleting flags and objects, e.g. pod names and namespaces. To configure autocompletion for kubectl, run:

echo “source <(kubectl completion bash)” >> ~/.bashrc

This will add kubectl autocomplete to your profile so it’s automatically loaded upon any new shell invocation. If you’re using zsh, add the following lines to

# kubectl bash completion
if [ $commands[kubectl] ]; then
source <(kubectl completion zsh)
fi

Confirm changes:

$ tail -n 5 ~/.zshrc
# kubectl bash completion
if [ $commands[kubectl] ]; then
source <(kubectl completion zsh)
fi

Now if you type kubectl and press enter, it should list all available options:

$ kubectl <TAB TWICE>
alpha cluster-info describe logs rollout
annotate completion drain options runapi-versions config edit patch scaleapply convert exec plugin setattach cordon explain port-forward taintauth cp expose proxy topautoscale create get replace uncordoncertificate delete label rolling-update version

Kubectl commands syntax is

$ kubectl [command] [TYPE] [NAME] [flags]

This syntax apply for all kubectl commands that you run on your terminal. Where command, TYPE, NAME, and flags are:

Command — This specifies the operation to be performed on a resource, e.g describe, get, delete, create, run, edit, set, convert, label, scale e.t.c

TYPE — This specifies a resource type. Note that resource types are case sensitive, and can be singular, plural, or abbreviated forms. For example commands pod,pods,po will return same output.

NAME — This specifies a resource name, names are case sensitive. If no name is given, details for all resources will be displayed. A resource can be specified by type and name.

Flags — Used to specify optional flags which override default values,example, -s or —server flag is used to specify the address of Kubernetes API Server.

Kubectl Common Operations

Having looked at kubectl basics, let’s proceed to see common kubectl operations that can be performed on Kubernetes cluster.

Create a resource from a file

To create a resource on Kubernetes with kubectl from a file or from stdin, use the following command syntax:

$ kubectl create -f FILENAME

Supported file formats are JSON and YAML. So to create a pod from yaml file named pod.yml, you’ll run

$ kubectl create -f ./pod.ymlpod “mytestserver” created

The same pod.yml contents can be passed as stdin to kubectl command as below.

$ cat pod1.yml | kubectl create -f -pod “mytestserver1” created

List resources

To list one or more resources, kubectl get command is used for this, it supports plain-text output format. A number of resource types are supported. To get all pods in human readable format, use

$ kubectl get podsNAME            READY     STATUS    RESTARTS   AGEmytestserver    1/1       Running   0          59smytestserver1   1/1       Running   0          32s

For json output format, use json flag:

$ kubectl get pods -o json | head
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2018-01-06T07:00:42Z",
"name": "mytestserver",
"namespace": "default",

To list all pods with more information, wide flag is used.

$ kubectl get pods -o wideNAME            READY     STATUS    RESTARTS   AGE       IP           NODE
mytestserver 1/1 Running 0 5m 172.17.0.4 minikube
mytestserver1 1/1 Running 0 5m 172.17.0.5 minikube

You can also list more than two resources together by separating them with a comma.

$ kubectl get nodes,jobs,events,pods

Where pods,jobs,events and nodes are resource types. You can consult Kubernetes documentation for all resource types available.

Display detailed state of resources

To display detailed state of a resource with kubectl, the command describe is used. This will print debug information about the given resource. As an example, to display the details of the pod with name <pod-name>, use:

$ kubectl describe pods/<pod-name>

Example:

$ kubectl describe pods/mytestserver
Name: mytestserver
Namespace: defaultNode: minikube/192.168.99.100Start Time: Sat, 06 Jan 2018 10:00:42 +0300Labels: <none>Annotations: <none>Status: RunningIP: 172.17.0.4Containers:hello:Container ID: docker://7bb649c9d703bb5c78d48ba0b353fd6d391e16d574a3372b9e431cc7ec11e605Image: andygrunwald/simple-webserverImage ID: docker-pullable://andygrunwald/simple-webserver@sha256:be5665894aa8df984d34334a837fda2886c107137d0a7b1537c7cb47fe92b9b6Port: 8082/TCPState: RunningStarted: Sat, 06 Jan 2018 10:00:48 +0300Ready: TrueRestart Count: 0Environment: <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from default-token-k8pmr (ro)Conditions:Type StatusInitialized TrueReady TruePodScheduled TrueVolumes:default-token-k8pmr:Type: Secret (a volume populated by a Secret)SecretName: default-token-k8pmrOptional: falseQoS Class: BestEffortNode-Selectors: <none>Tolerations: <none>Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 10m default-scheduler Successfully assigned mytestserver to minikubeNormal SuccessfulMountVolume 10m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-k8pmr"Normal Pulling 10m kubelet, minikube pulling image "andygrunwald/simple-webserver"Normal Pulled 10m kubelet, minikube Successfully pulled image "andygrunwald/simple-webserver"Normal Created 10m kubelet, minikube Created containerNormal Started 10m kubelet, minikube Started container

Similar commands are used for other resource types.

Delete resources

With kubectl delete, you can delete resources from either a file or stdin. To delete service defined in a file, you’ll use -f flag followed by the name of the file:

$ kubectl delete -f pod1.yamlpod “mytestserver1” deleted

This deletes a service using a type and name that’s specified in the service.yml file. To delete all pods including ones that have not been initialized, run

$ kubectl delete pods --allpod “mytestserver” deleted
pod “mytestserver1” deleted

Execute a command against a container in a pod

If you have containers running in Kubernetes and would like to execute commands on these containers, kubectl exec comes in handy. Let’s say we have a container called apache on pod web, If i want to test internet access through pin, I would run:

$ kubectl exec web -c <container-name> date

Replace <container-name> with the name of your container and date with the command to be executed on a container.

$ kubectl exec mytestserver dateSat Jan 6 07:18:22 UTC 2018

Print the logs for a container in a pod.

At times you need pull logs from a container for troubleshooting issues, this can be achieved using kubectl logs command. In below example, assuming you want to print logs on a pod named mytestserver with only one container, you’ll run:

$ kubectl logs mytestserver 
2018/01/06 07:17:43 Starting webserver and listen on :8082

Next command below will return snapshot of previous terminated nginx container logs from pod prod-web

$ kubectl logs -p -c hello-world mytestserver1

You can also stream real time logs using -f flag:

$ kubectl logs -f -c hello-world mytestserver12018/01/06 07:17:43 Starting webserver and listen on :8082

Other options available are —tail and —since

$ kubectl logs --tail=50 mytestserver # Print most recent 50 lines
$ kubectl logs --since=3h mytestserver # Print last 3 hours logs

Forward one or more local ports to a pod.

If your node has a public IP address and you would like to access service port on a container through host system port, you’ll need to forward ports using kubectl port-forward command. The syntax is:

$ kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT

Below command will forward port 80 on the host to port 80 on the on the pod.

$ kubectl port-forward prod-web 80:80

Edit a resource

To edit a resource using kubectl command line tool, use edit command. It will open the editor defined by your KUBE_EDITOR, or EDITOR environment variables, fallback being vi for Linux and notepad for Windows. The default format is YAML. The syntax is

$ kubectl edit (RESOURCE/NAME | -f FILENAME)

Have a look at below example which edits pod called mytestserver1 using vim editor.

$ KUBE_EDITOR=”vim” kubectl edit pod mytestserver1

Create a secret for use with a Docker registry.

If you have a docker registry which requires authentication, create a new secret for use in Dockercfg. This will be used by commands like docker login command for image pushing and pulling. Commands syntax is as shown

$ kubectl create secret docker-registry mydocker-key \
--docker-username=test --docker-password=password --docker-email=test@example.com
secret “mydocker-key” created

Replace user with your username, password with real password, and email with a valid email address.

Check for the created secret:

$ kubectl get secret 
NAME TYPE DATA AGE
default-token-k8pmr kubernetes.io/service-account-token 3 17d
mydocker-key kubernetes.io/dockercfg 1 57s

Delete secret:

$ kubectl delete secret mydocker-key 
secret “mydocker-key” deleted

Apply a configuration to a resource

You can apply a configuration to a resource by filename or stdin. If the resource doesn’t exist yet, it will be created. The formats accepted are JSON and YAML. Consider these examples

# Apply configuration in mypod.yml to a pod
$ kubectl apply -f ./pod.yml
pod “mytestserver” created
# Apply the JSON passed into stdin to a pod
$ cat mypod.json | kubectl apply -f -

Auto-scale a deployment or replication controller

It’s easy to scale a deployment or replication controller using kubectl command. What you need to do is create an autoscaler that automatically chooses and sets thhe number of pods that run in a kubernetes cluster. This autoscaler can automatically increase or decrease number of pods deployed within the system as needed.

Create deployment

$ kubectl run hello-node --image=hello-node:v1 --port=8080
deployment “hello-node” created

Get deployments:

$ kubectl get deploymentsNAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-node 1 1 1 0 1s

Configure autoscaling:

$ kubectl autoscale deployment hello-node --min 2 --max 3 
deployment “hello-node” autoscaled

Again run get deployments command to confirm autoscaling:

$ kubectl get deploymentNAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-node 2 2 2 0 4m
$ kubectl get podNAME READY STATUS RESTARTS AGE
hello-node-75ddf8bc9d-d7bqj 0/1 ImagePullBackOff 0 5m
hello-node-75ddf8bc9d-sj646 0/1 ImagePullBackOff 0 2m

From above output, you can see the number of pods are now two ( set to minimum):

This will automatically scale a deployment called hello-node with a number of pods between 2 and 3.

To target average CPU utilization of 70%, use:

$ kubectl autoscale deployment hello-node --min=3 --max=7 --cpu-percent=80

Convert config files between different API versions

To convert configuration files between different formats, use kubectl convert command. This support both YAML and JSON formats. An input passed to the command can be a filename, directory, or URL. Output format version is specified using — output-version tag, if no version is specified, latest will be used.

To specify a destination, use -o flag. The default output will be printed to stdout in YAML

Examples:

$ kubectl convert -f tests/pod.yml # convert to latest version and print on stdout
apiVersion: v1
items:- apiVersion: v1kind: Podmetadata:creationTimestamp: nullname: mytestserverspec:containers:- image: andygrunwald/simple-webserverimagePullPolicy: Alwaysname: helloports:- containerPort: 8082protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: NeverschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30status: {}$ kubectl convert -f tests/pod.yml --local -o json # convert and print to stdout in json format{"kind": "Pod","apiVersion": "v1","metadata": {"name": "mytestserver","creationTimestamp": null},"spec": {"containers": [{"name": "hello","image": "andygrunwald/simple-webserver","ports": [{"containerPort": 8082,"protocol": "TCP"}],"resources": {},"terminationMessagePath": "/dev/termination-log","terminationMessagePolicy": "File","imagePullPolicy": "Always"}],"restartPolicy": "Never","terminationGracePeriodSeconds": 30,"dnsPolicy": "ClusterFirst","securityContext": {},"schedulerName": "default-scheduler"},"status": {}}$ kubectl convert -f . | kubectl create -f - # Convert all files in current directory and create them all

Convert to json and redirect output to a file:

$ kubectl convert -f tests/pod.yml --local -o json > pod.json
$ cat pod.json

{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "mytestserver",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "hello",
"image": "andygrunwald/simple-webserver",
"ports": [
{
"containerPort": 8082,
"protocol": "TCP"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"imagePullPolicy": "Always"
}
],
"restartPolicy": "Never",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst",
"securityContext": {},
"schedulerName": "default-scheduler"
},
"status": {}
}

Conclusion

We have come to the end of our guide on how to manage Kubernetes cluster and resources with kubectl command. We started with the installation of kubectl on Windows and Linux, looked at command line syntax for kubectl command tool, and finalized with examples on management of Kubernetes cluster with kubectl command.

--

--

Stakater
Stakater

We offer professional tools, services and support to help customers create and manage their Kubernetes based infrastructure effortlessly. (http://stakater.com)