DEV Community

Cover image for Getting Started With Kubectl: A Guide To Kubernetes
Otuekong Arthur
Otuekong Arthur

Posted on

Getting Started With Kubectl: A Guide To Kubernetes

Kubernetes features and scalability make it a preferred choice for managing containerized applications. However, harnessing the full power of Kubernetes requires proficiency in various tools and one of the most essential among them is Kubectl.

In this guide, we will get into the heart of Kubernetes management, offering a guide to mastering Kubectl. This guide will equip you with the knowledge and skills needed to streamline your Kubernetes workflow. Let's navigate the complexities of Kubectl together and unlock the potential of seamless Kubernetes administration.

Prerequisites:

Before we begin, ensure you have the following:

  • Package manager, on macOS, you can use Homebrew, on Linux, you can use Snap, and on Windows, you can use a package manager like Chocolatey.
  • A Kubernetes Cluster: You need a working Kubernetes cluster. If you don't have one, you can set up a local cluster using tools like Minikube, Kind or use a cloud-based Kubernetes service like Google Kubernetes Engine (GKE) or Amazon EKS. In this article, I will be using Minikube.

Notes:
-Due to lengthy outputs, some screenshots may be cut off.
-If you are using Minikube,kubectl comes bundled with it.

I will be working from a folder I created on my desktop called kubectl_practice.

What is Kubectl?

Kubectl is a command-line utility designed for communication with Kubernetes clusters. It enables users to deploy and oversee applications, inspect and manage cluster resources, and examine logs.

Kubectl Installation

We will be looking at ways of installing Kubectl on Windows, Mac, and Linux.

On Windows, open Command Prompt or PowerShell as an administrator and run:

choco install kubernetes-cli

On MacOS If you have Homebrew installed, run the following:

brew install kubectl

On Linux For uniformity of installation,I will be using Snap, a package manager that comes bundled in most Linux distributions.
First check if you have Snap installed by running:
snap --version
You should get the output below if you have Snap installed.

Image description
If you don't have Snap installed, on Ubuntu-based systems you can do so by running
sudo apt-get install snapd -y
while on Red-hat-based distribution, you will first have to install the Epel repository with:
sudo dnf install epel-release -y
Then, update dnf with:
sudo dnf upgrade
Finally, install Snap with:
sudo dnf install snap -y

When you are done with the above steps, just run:
sudo snap install kubectl --classic
And you are in!
Image description

Verifying the Installation

After installation, verify that kubectl is working by running the command:

kubectl version

Image description

If you are using a cloud-based Kubernetes cluster, there are extra things you need to get Kubectl up and running.

Configuring Kubectl for cloud-based Kubernetes cluster

You need the cluster configuration details to connect kubectl to your cluster. These details typically include:

  • Cluster API Server: The endpoint where your cluster is running.
  • Cluster Certificate Authority: The certificate authority data for your cluster.
  • Authentication Token: A token for authenticating with the cluster (used in some configurations).

There are 2 ways of achieving this:

  • Using kubectl config command
  • Kubeconfig File

Using kubectl config command: To set cluster configuration using the kubectl config command, open a terminal and paste the following commands



kubectl config set-cluster my-cluster-name --server=https://cluster-api-server-address --certificate-authority=path/to/certificate-authority
kubectl config set-credentials my-cluster-cred --token=your-auth-token
kubectl config set-context my-cluster-context --cluster=my-cluster-name --user=my-cluster-


Enter fullscreen mode Exit fullscreen mode

Replace my-cluster-name, https://cluster-api-server-address, path/to/certificate-authority, and your-auth-token with your specific cluster details.

Using kubeconfig file: You can directly edit the kubeconfig file (usually located at ~/.kube/config) to add multiple clusters. Manually add your cluster details in the clusters, users, and contexts sections.



apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <certificate-authority-data>
    server: https://cluster-api-server-address
  name: my-cluster-name
contexts:
- context:
    cluster: my-cluster-name
    user: my-cluster-cred
  name: my-cluster-context
current-context: my-cluster-context
kind: Config
preferences: {}
users:
- name: my-cluster-cred
  user:
    token: your-auth-token


Enter fullscreen mode Exit fullscreen mode

Once you've configured kubectl, you can test the connection by running:



kubectl cluster-info


Enter fullscreen mode Exit fullscreen mode

Getting Minikube Ready

I will use Minikube to set up a Kubernetes cluster on my local machine.

For this guide, I will be using the bash terminal on Windows but command prompt or PowerShell will work fine. Let’s start a Minikube cluster of 3 nodes. Open the terminal and type:



minikube start --nodes 3


Enter fullscreen mode Exit fullscreen mode

When Minikube is done starting, you will be presented with the below output

Image description
All good, we now have our Minikube cluster running.

Now let us get into business.

In this article, we will not be looking at all the commands that are available in Kubectl.To get you up and running, we will check out Kubectl commands as they pertain to:

  • Node and Cluster Management
  • Application Management
  • Updating and Deleting Application
  • Debugging Application

For a comprehensive list of all Kubectl commands please check the Kubectl documentation.

Below is a table of commands we will be looking at in this guide.

Commands Uses
kubectl get Retrieving information about Kubernetes resources
kubectl describe Detailed information about a specific resource
kubectl logs Accessing container logs
kubectl create Creating resources
kubectl apply Updating resources
kubectl delete Removing resources from the cluster
kubectl exec Running commands inside containers
kubectl cordon Marks a node as unschedulable
kubectl uncordon Unmarks a node as unschedulable
kubectl drain Gracefully moves all pods off a node
kubectl set image deployment Updating the container image in a specific deployment
kubectl api-versions Lists the API groups and their versions understood by the Kubernetes API server.
kubectl api-resources Display the available API resources

Node and Cluster Management

As a Kubernetes user, among the things you will be doing is working with nodes and clusters. This section will guide you on using kubectl to operate Kubernetes node and cluster.

Get Nodes

Do you still remember the cluster we created? Let’s now put it to use.

First, let’s get some information about the minikube cluster. In your terminal, type:

kubectl get nodes

This command gets information about the nodes in our minikube cluster and presents us with the below output:

Image description

Describe Nodes

Let’s go further and get detailed information about the nodes.

Type kubectl describe nodes and you will be presented with descriptions of all the nodes on your cluster.

Let’s narrow our command and get a description of our minikube control-plane node.

Type kubectl describe node minikube

Kubernetes returns an output stating details about the minikube node.

Image description
Before we move on, let's get information about our minikube-m02 node.

In the terminal, type: kubectl describe node minikube-m02

The above command displays a description of our minikube-m02 node below:

Image description

Cordon Nodes

Imagine you have a team of workers doing their tasks in an office. Now, let's say you need to do some maintenance on a particular desk and don't want anyone to start new tasks there until you're done. In Kubernetes, kubectl cordon is like putting a Do Not Disturb sign on that desk. It tells Kubernetes not to schedule any new work on a specific worker node so you can conduct maintenance on it.

Let us demonstrate this with our minikube-m02 node.

On the terminal,type kubectl cordon minikube-m02

Image description

Now our minikube-m02 node is restricted from having new pods scheduled on it.

Use kubectl describe node minikube-m02 to check if this is true.

Image description

Pay attention to the output,unshedulable now says true.

Get it to run new pods by executing kubectl uncordon minikube-m02

Image description

Drain Nodes

Next on our lineup is kubectl drain. If you ever need to remove all pods from a node, then kubectl drain is the man for the job.

It helps you prepare a node for maintenance by moving all the tasks and applications to other nodes. Let us see it in action.

In your terminal, type kubectl drain minikube-m03 --ignore-daemonsets --force

Before we press enter, let me explain what the above command does.

  1. kubectl drain is the main command that tells Kubernetes to prepare a particular node for maintenance.
  2. minikube-m03 is our particular node for maintenance.
  3. --ignore-daemonsets : this tells Kubernetes not to move certain essential tasks called daemonsets to other nodes.
  4. --force : the force flag tells Kubernetes not to wait for resources to terminate gracefully.

Now hit enter.
Image description

From the above output, we can see that the drain command does 2 things.

  • It cordons or stops the node from having new pods scheduled on it.
  • It then drains the node of existing pods.

Delete Nodes

With our minikube-m03 node drained, we are now ready to delete the node. Run this command

kubectl delete node minikube-m03

The screenshot below shows us that our minikube-m03 node has been deleted.

Image description

Cluster Management

It is advisable to regularly inspect the cluster API versions, as each new release of Kubernetes introduces new API versions and may eliminate older ones. To obtain a list of available APIs, execute the following command:

kubectl api-versions
Image description
The above output returns a list of API versions available that we can make use of.

Kubectl also provides a way to check the API resource list.

To get the available API resource list run kubectl api-resources
Image description

Our command returns the accessible resources, their short names, the API group to which a resource is affiliated, whether it is namespace-specific or not, and the specific KIND type.

Application Management

In this section, we will look at application management with Kubectl. Navigate to the kubectl_practice folder.

Let’s start with creating a deployment.

Create Deployment

In the kubectl_practice folder, create a file named practice-deployment.yaml with the provided content.



apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
        resources:
          limits:
            cpu: "0.5" 
            memory: "512Mi"  
          requests:
            cpu: "0.2"  
            memory: "256Mi"


Enter fullscreen mode Exit fullscreen mode

Run kubectl apply -f practice-deployment.yaml to deploy using the configuration in the practice-deployment.yaml file.

The above command will present you with the console output below :

Image description

Let's check the status of our deployment by running kubectl get deployments

Image description

Create A Service

Services expose Pods to the network within or outside the cluster. Let’s check out how to create services with Kubectl .

I will create a file in kubectl_practice folder and name it practice-service.yaml with the below as the content of this file:



apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP


Enter fullscreen mode Exit fullscreen mode

Next, let's apply the configuration.

Type kubectl apply -f practice-service.yaml in your terminal and hit the enter key.

The screenshot below shows that our service was created.

Image description
You may check the status of the service by running kubectl get services which displays the output below

Image description

Nice, our service is running.

Create Pods

Creating pods directly in Kubernetes seems convenient but brings challenges in scalability, resilience, updates, and resource management. Using higher-level abstractions like Deployments and ReplicaSets ensures easier management, automatic healing, streamlined updates, and optimized resource use for a more efficient Kubernetes experience. For the above, avoid creating pods directly in Kubernetes but instead, use deployments.

In the kubectl_practice folder, create a file named practice-pod.yaml with the following content:



apiVersion: v1
kind: Pod
metadata:
  name: practice-pod-1
spec:
  containers:
  - name: my-container
    image: nginx:latest
    resources:
      limits:
        memory: "200Mi"
        cpu: "500m"   
      requests:
        memory: "120Mi"
        cpu: "250m"

---

apiVersion: v1
kind: Pod
metadata:
  name: practice-pod-2
spec:
  containers:
  - name: container-1
    image: nginx:latest
    resources:
      limits:
        memory: "150Mi"
        cpu: "300m"   
      requests:
        memory: "100Mi"
        cpu: "200m"


Enter fullscreen mode Exit fullscreen mode

Now run this command kubectl apply -f practice-pod.yaml

If you follow everything correctly, the screenshot below should be the output on your terminal.
Image description

With our practice-pod.yaml file we created 2 pods. Let’s confirm this by running kubectl get pods

Image description

Get rid of these pods by running kubectl delete pods practice-pod-1 practice-pod-2

Image description

Updating And Deleting Application

Updating

There are many methods to deploy a new application version. Here, we will be focusing on two methods:

  • kubectl apply
  • kubectl set image

Open the practice-deployment.yaml file and change the docker image from nginx:latest to nginx:stable-perl.

Save the file and run the following command kubectl apply -f practice-deployment.yaml

Image description

Let’s run a quick command to get a description of our deployment.

In your terminal, type kubectl describe deployment my-deployment

Image description

In the above screenshot, did you notice that the container image changed from nginx:latest tag to nginx:stable-perl?

Let's use kubectl set image to change the container image tag to another version. Jump back into the terminal and type: ****

kubectl set image deployment my-deployment my-container=nginx:mainline

Image description

Get the description of our deployment by running kubectl describe deployment my-deployment

Image description

Exposing Application To The Internet

To make your application available on the internet, go into the practice-service.yaml file and change the type from clusterIP to LoadBalancer.

Apply the changes by running kubectl apply -f practice-service.yaml

Then run the get service command by typing kubectl get service

The below screenshot should be similar to the output on your console.
Image description

If you are using a cloud-based Kubernetes cluster, It might take minutes for your cloud provider to set you up. If you are using Minikube, you will need to start the Minikube tunnel to expose the External-IP.

On a separate terminal, run minikube tunnel

Then get back and run kubectl get service

By now the external IP status should change from pending to showing an external IP like so.
Image description

Copy the EXTERNAL-IP, and open it in a browser.
Image description

You have successfully exposed your application to the internet. Great job.

Deleting Application

Let us get information about our deployment and our service.

Run kubectl get service command to get our service.

Image description
Let’s delete my-service with kubectl delete service my-service

Image description

Try to get my-service with kubectl get service and you will notice it is no longer there.

Image description

Get the name of our deployment with kubectl get deployments and run kubectl delete deployment my-deployment.

Image description

Try to get our deployment with kubectl get deployments and you will get the below output:

Image description

Debugging Application

Sometimes things might not go as planned and you have to get into the pods to fix things. To demonstrate this, let’s create a fresh deployment.

In the kubectl_practice folder, create a file called myDatabase-deployment.yaml and paste the below content.



apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-sql
        image: mysql:oracle
        #env goes here
        resources:
          requests:
            cpu: "0.4"
            memory: "800Mi"
          limits:
            cpu: "0.8"
            memory: "900Mi"


Enter fullscreen mode Exit fullscreen mode

Get into the terminal and type kubectl apply -f myDatabase-deployment.yaml

The above command gives the output below.

Image description

Try to get our deployment with kubectl get deployments and you will be presented with the output below.

Image description

For some reason,my-database deployment is not ready. Let’s get the pods in our deployment

Run kubectl get pods

Image description

From the above output, we can see that my-database— pod has the status of CrashLoopBackOff.What could this be?

Let's get a log of the pods, run kubectl logs my-database-7c44d9bcb4-h9h54
Image description

The preceding command shows a log of the pods. Line 3 of the logs is of concern to us where it displays that "Database is uninitialized and password option is not specified You need to specify one of the following as an environment variable:"
This means that we need to set a password for the database. To fix this, get into myDatabase-deployment.yaml file, under containers, add the below content:



env:
         - name: MYSQL_ROOT_PASSWORD
           value: secret-password


Enter fullscreen mode Exit fullscreen mode

Next, get back to the terminal and run kubectl apply -f myDatabase-deployment.yaml
Confirm if our pod is running by executing kubectl get pods

Image description

Awesome our pods are running.
Finally, let's show how to use kubectl exec to run a terminal inside a container. I will be using Windows Powershell to demonstrate this.
If you are using Windows OS, open Powershell and navigate to our kubectl_practice folder.
First I will run kubectl get pods

Image description
Second I will get the pod name and exec into the container with
kubectl exec -it my-database-7c8c774899-jdqth -- /bin/bash

Image description
Let's get a list of directories/folders inside the container by running ls which stands for lists.

Image description
The above output shows the Linux directory structure inside our my-sql container.
Let's run mysql -p which will prompt for the password to be entered.

Image description
Remember we set the password to secret-password. Type it in and you will be presented with an output similar to this:

Image description

You may leave the container by running exit.

Conclusion

And there you have it, your journey into the world of Kubectl. We covered node and cluster management, application management, and updating and deleting applications, and even went as far as debugging your applications. Remember, mastering Kubectl takes practice but every command you learn brings you a step closer to becoming a Kubernetes master.
Keep this guide handy as you continue your Kubernetes exploration, and don't hesitate to experiment. The world of Kubernetes is dynamic and ever-expanding and Kubectl is your key to unlocking its full potential.

Top comments (2)

Collapse
 
gbhorwood profile image
grant horwood

good article and definitely bookmarked for future ref. only issue i see is in the linux install instructions it says:

sudo apt-get update && sudo apt-get

which is missing an important word.

Collapse
 
fizy_hector profile image
Otuekong Arthur

Thanks, @gbhorwood for taking the time to point out this error. I have changed the Linux install instructions to only use Snap which is more straight to the point.