Basic Kubectl Commands

To interact with a Kubernetes cluster, what we use the most is ‘Kubectl’. Kubectl is a Command line Interface for communicating with a Kubernetes cluster’s control plane using the Kubernetes API. Therefore, it is important to know some of the basic Kubectl commands in order to work with Kubernetes.

A Kubectl command usually takes the kubectl <action> <resource> <flags> format.

Eg: kubectl get pods -n default

Create Resources

To create Kubernetes resources we can use the kubectl create command.

$ kubectl create deployment nginx --image=nginx:stable-alpine
deployment.apps/nginx created

Above example will create a Deployment named ‘nginx’ using the ‘nginx:stable-alpine’ from Docker Hub.

To run a pod instead of creating a deployment, we can use the kubectl run command as below.

$ kubectl run nginx-pod --image=nginx:stable-alpine
pod/nginx-pod created

The above command will start a single instance of an Nginx pod.

However, we don’t create resources in this manner by running kubectl create commands in Kubernetes. Instead, we use Kubernetes manifest files. Kubernetes manifest files are configuration files written in YAML that allow us to define how resources should run, connect to other resources etc.. We will discuss about Kubernetes manifest files at length in a future article.

To create or update resources using manifest files, we use kubectl apply command as shown below.

$ kubectl apply -f mobile-app-ws.yaml
deployment.apps/mobile-app-ws created
service/mobile-app-ws-service created

In the above example, I have passed a manifest file named mobile-app-ws.yaml with a -f flag. And as a result, we can see that a Deployment and a Service has been created. In the next article of this Kubernetes series, we are looking into Kubernetes manifests in detail.

Edit Resources

To edit Kubernetes resources we can use the kubectl edit command.

$ kubectl edit deployment nginx
deployment.apps/nginx edited

In the above example, I am editing the Nginx Deployment I created. Once the command is run, the default editor will open the configuration for the resource and we can do any changes in it. Once the file is saved and exited, the command line will show the output as shown above.

Alternatively, we can simply make the change in our manifest file for the resource and then use the kubectl apply command in the same manner we used it to create the resource.

For an example, if I make a small change in the manifest file for a certain resource and apply it, the output would look like below.

$ kubectl apply -f mobile-app-ws.yaml
deployment.apps/mobile-app-ws configured
service/mobile-app-ws-service unchanged  

Delete Resources

To delete Kubernetes resources we can use the kubectl delete command.

$ kubectl delete deployment nginx
deployment.apps "nginx" deleted

In the above example, I am deleting the Nginx Deployment I created. Likewise, you can delete other resources too.

Get/List Resources

To view or list resources we can use kubectl get command.

In below example I have run kubectl get services command to list all the services.

$ kubectl get services
NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes              ClusterIP      10.96.0.1       <none>        443/TCP        4d3h
mobile-app-ws-service   LoadBalancer   10.102.15.204   <pending>     80:30080/TCP   6m12s
mysql-service           ClusterIP      10.103.70.48    <none>        3306/TCP       6m25s

As you can see, there are 3 Services on this occasion. We can see some details like Service name, type, IP address and ports.

Likewise, we can run this command to list down other resources as well. Some more examples below.

$ kubectl get deployments
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
mobile-app-ws   2/2     2            2           63m
mysql           1/1     1            1           63m
$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
mobile-app-ws-86b9d5ddcb-r6l2s   1/1     Running   0          62m
mobile-app-ws-86b9d5ddcb-wq5c2   1/1     Running   0          11s
mysql-984c75797-vqsjc            1/1     Running   0          62m
Wide Output

To get a little bit more details about the resources, we can modify the command by specifying -o wide flag as below.

$ kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
mobile-app-ws-86b9d5ddcb-r6l2s   1/1     Running   0          63m   172.17.0.4   minikube   <none>           <none>
mobile-app-ws-86b9d5ddcb-wq5c2   1/1     Running   0          66s   172.17.0.5   minikube   <none>           <none>
mysql-984c75797-vqsjc            1/1     Running   0          63m   172.17.0.3   minikube   <none>           <none>
Get Details of a Specific Object

If we needed to see the details of only a specific pod, let’s say mobile-app-ws pod in the previous example, we can modify the kubectl get command as below.

$ kubectl get pods mobile-app-ws-86b9d5ddcb-r6l2s
NAME                             READY   STATUS    RESTARTS   AGE
mobile-app-ws-86b9d5ddcb-r6l2s   1/1     Running   0          20m

Notice that I have specified the pod name as a parameter to the command.

Specifying a Namespace

In Kubernetes, we use namespaces to logically organize our resources. When we run the kubectl get command without specifying any namespace, it shows us the results for default namespace. If we need to fetch results for a specific namespace, then we can use the -n flag with the command.

$ kubectl get pods -n kube-system
NAME                               READY   STATUS    RESTARTS       AGE
coredns-64897985d-8szlb            1/1     Running   1 (47m ago)    4d3h
etcd-minikube                      1/1     Running   1 (47m ago)    4d3h
kube-apiserver-minikube            1/1     Running   1 (47m ago)    4d3h
kube-controller-manager-minikube   1/1     Running   1 (47m ago)    4d3h
kube-proxy-4nk2m                   1/1     Running   1 (47m ago)    4d3h
kube-scheduler-minikube            1/1     Running   1 (47m ago)    4d3h
storage-provisioner                1/1     Running   11 (46m ago)   4d3h

In above example, I am listing down the pods in kube-system namespace.

Get by Labels

In Kubernetes, we can specify labels to our resources(a label is basically a key value pair, and we will discuss these in detail later). These come in handy on many occasions.

For instance, I have specified a label as app=mobile-app-ws for mobile-app-ws pods. If I need to get only mobile-app-ws pods, I can amend my kubectl get command with a -l flag as below.

$ kubectl get pods -l app=mobile-app-ws
NAME                             READY   STATUS    RESTARTS   AGE
mobile-app-ws-86b9d5ddcb-r6l2s   1/1     Running   0          73m
mobile-app-ws-86b9d5ddcb-wq5c2   1/1     Running   0          11m

Notice that this time, only 2 mobile-app-ws pods have been fetched and the MySQL pod has been omitted from the output.

If you need to find out the labels assigned for certain pods or any other resource in the first place, you can run the kubectl get command with --show-labels flag as shown below.

$ kubectl get pods --show-labels
NAME                             READY   STATUS    RESTARTS   AGE   LABELS
mobile-app-ws-86b9d5ddcb-r6l2s   1/1     Running   0          77m   app=mobile-app-ws,pod-template-hash=86b9d5ddcb
mobile-app-ws-86b9d5ddcb-wq5c2   1/1     Running   0          15m   app=mobile-app-ws,pod-template-hash=86b9d5ddcb
mysql-984c75797-vqsjc            1/1     Running   0          78m   app=mysql,pod-template-hash=984c75797

As you can see, this shows the labels assigned for each of the pods.

There are many other options available for the the get command but these should be sufficient when getting started.

Verbose Details of Resources

To get verbose details of our resources, we can use the kubectl describe command.

$ kubectl describe deployment mobile-app-ws
Name:                   mobile-app-ws
Namespace:              default
CreationTimestamp:      Sun, 03 Jul 2022 12:12:56 +0530
Labels:                 app=mobile-app-ws
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=mobile-app-ws
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=mobile-app-ws
  Containers:
   mobile-app-ws:
    Image:      dcharith/mobile-app-ws:3.0
    Port:       8080/TCP
    Host Port:  0/TCP
    Environment:
      DB_HOST:      <set to the key 'DB_HOST' of config map 'mobile-app-ws-configmap'>  Optional: false
      DB_USERNAME:  <set to the key 'DB_USERNAME' in secret 'mobile-app-ws-secret'>     Optional: false
      DB_PASSWORD:  <set to the key 'DB_PASSWORD' in secret 'mobile-app-ws-secret'>     Optional: false
    Mounts:         <none>
  Volumes:          <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   mobile-app-ws-86b9d5ddcb (2/2 replicas created)
Events:          <none>

In the above example, I have described one of my deployments. And as you can see, there is a lot of information about the deployment such as the number of replicas, the pod template along with information such as the image used, ports, environment variables etc. and events related to the deployment.

Likewise, you can describe other resources as well to get a detailed output.

View Logs

To view logs related to our application pods, we can use kubectl logs command.

$ kubectl logs mobile-app-ws-86b9d5ddcb-lqjdv
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
03-Jul-2022 06:42:57.913 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/8.5.81
03-Jul-2022 06:42:57.963 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 8 2022 21:30:15 UTC
03-Jul-2022 06:42:57.963 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 8.5.81.0
03-Jul-2022 06:42:57.963 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux

As you can see above, we need to specify the name of our pod to the kubectl logs command.

You can also run this command for a Deployment as well, as shown below.

$ kubectl logs deployment/mobile-app-ws
Found 2 pods, using pod/mobile-app-ws-86b9d5ddcb-lqjdv
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
03-Jul-2022 06:42:57.913 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/8.5.81
03-Jul-2022 06:42:57.963 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 8 2022 21:30:15 UTC

Interacting with Running Pods

To open an interactive terminal inside a pod, we can use the kubectl exec command as below.

If you are on Windows and using a terminal like Git Bash, then you might run into some errors. In that case, use the regular Windows command line. 
C:\Users\Charith>kubectl exec -it mysql-984c75797-49266 -- bash
root@mysql-984c75797-49266:/# pwd
/

The above example opens an interactive Bash shell inside the container. Once connected, I can run Bash commands in the shell.

Since we are inside a MySQL pod, let’s try to connect to the database.

C:\Users\Charith>kubectl exec -it mysql-984c75797-49266 -- bash
root@mysql-984c75797-49266:/# mysql -u charith -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 68
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Here I have connected to the MySQL pod using the kubectl exect command and successfully connected to the database using mysql -u charith -p command. This will prompt for the password of the user. Once that is provided, I get a MySQL prompt where I can run SQL commands.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| photo_app          |
+--------------------+
2 rows in set (0.00 sec)

mysql>

So I have run a simple show databases query and it shows me the results as expected.

Hope you have some understanding of basic Kubectl commands now and how to use them. We will be using these commands and more when we deep dive into Kubernetes.

Share this article if it was helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *