Top 10 Kubernetes Tricks and Tips

Top 10 Kubernetes Tricks and Tips

There is a lot of reference literature on the Internet, but sometimes the simplest tips are the most valuable. Team Kubernetes aaS from Mail.ru translated a selection of ten tricks and tips, which the author of the article has collected after a year of work with Kubernetes. Tips are not sorted by importance, but we think that everyone will find something useful for themselves.

The easiest command to use with Kubernetes

To get started, perhaps the simplest and most useful step in working with Kubernetes. The following command enables command completion kubectl in bash shell:

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

Autocomplete kubectl will be written to the .bashrc file and will be automatically activated every time the shell is started. This speeds up typing long commands and options like all-namespaces. Read more in Kubernetes bash help.

Namespace Memory and CPU Default Limits

If an application is written incorrectly, such as opening a new database connection every second but never closing it, then the cluster will leak memory. And if the application does not have a memory limit during deployment, this can lead to a node failure.

To prevent this, Kubernetes allows you to set default limits for each namespace. They are written in the yaml file for a specific namespace. Here is an example of such a file:

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container

Create such yaml and apply to any namespace. For example, to the namespace limit-example. Now, any container deployed in this namespace will have a 512Mi limit, unless another individual limit is additionally set for this container.

Garbage collection in older versions of Kubernetes

Kubelet starts garbage collection by default when var/lib/docker occupies 90% of the available disk space. This is great, however, prior to Kubernetes 1.7, there was no default limit on the number of inodes used, which correspond to the number of files in the file system.

Potentially your container var/lib/docker can only use 50% of the disk space, but it can run out of inodes, which will cause problems for the workers.

In older versions of kubelet from 1.4 to 1.6, you will have to add the following flag:

--eviction-hard
=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%

In 1.7 and later, this flag is set by default. However, previous versions do not enforce the inode limit.

Minikube… small but powerful local Kubernetes

Minikube is the easiest way to run a local Kubernetes cluster. It is launched with a simple command:

minikube start

This command will result in a real Kubernetes cluster running on your machine.

Top 10 Kubernetes Tricks and Tips
Illustration source

The trick is how to build the application and run it locally on this cluster. Unless otherwise specified, the Docker image will be built on your machine, not on the cluster.

To force Docker to push the image to the local Kubernetes cluster, the following command is given to the docker machine:

eval $(minikube docker-env)

Now we can build applications on a local Kubernetes cluster.

Don't share kubectl access with everyone

This seems obvious, but if multiple teams are using the same cluster for their applications (which is what Kubernetes was created for), don't just issue them all in a row kubectl. It is better to separate the commands, giving each of them its own namespace and delimiting access with RBAC policies.

You can get confused by assigning rights to access, read, create, delete, and other operations for each pod. But the main thing is to restrict access to secrets, allowing it only to administrators. This is how we distinguish between those who can administer the cluster and those who can simply deploy to it.

Manage Pod Budgets

How to ensure that there is no downtime for an application in a Kubernetes cluster? PodDisruptionBudget and again PodDisruptionBudget.

Clusters are periodically updated and nodes are emptied. Nothing stands still, that's the reality. Every deployment with more than one instance must include a PDB (PodDisruptionBudget). It is created in a simple yaml file which is applied to the cluster. The scope of a particular PDB is determined by label selectors.

Note: The PDB budget is taken into account only in case of a reversible budget violation (voluntary disruption). In situations like hardware failures, PDB won't work.

PDB example:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: app-a-pdb
spec:
  minAvailable: 2
  selector:
      matchLabels:
        app: app-a

The two main parameters are matchLabels ΠΈ minAvailable. The first parameter specifies which applications the budget applies to. For example, if I have deployments with tags app: app-a ΠΈ app: app-b, then this PDB will only apply to the first one.

Parameter minAvailable taken into account when emptying (clearing) the node. For example, in our example, all instances are evicted during devastation app: app-aexcept for two.

This allows you to control how many instances of the application should be running at any one time.

Application health monitoring

Such monitoring is possible in two ways: using Readiness or Liveness tests.

The first probe (readiness) determines whether the container is ready to receive traffic.

The second (liveness) indicates whether the container is healthy or needs to be restarted.

The relevant configurations are simply added to the yaml for deployment. There you can specify timeouts, delay time and number of retries. See more about them Kubernetes documentation.

Labels everywhere

Labels are one of the fundamental concepts in Kubernetes. They allow objects to freely communicate with each other, as well as create requests based on labels. In Kubernetes, you can even go to the client and watch events for specific labels.

Almost anything can be done with labels, but a good example would be to create multiple environments to run programs on the same cluster.

Let's say you use the same cluster for dev ΠΈ qa. This means that you can have an application app-a, simultaneously working in both environments qa ΠΈ dev. In this case, we can access the application instance separately in a specific environment by specifying the appropriate parameter environment. For example, app: app-a ΠΈ environment: dev for one environment, and app: app-a ΠΈ environment: qa for the second.

This allows you to access both instances of the application, for example, to test at the same time.

Put things in order

Kubernetes is a very powerful system, but any system can eventually get bogged down in a large number of processes. Kubelet runs all the processes and checks you specify, as well as its own.

Of course, one orphan service will not slow down the system, and Kubernetes is designed to scale from the very beginning. But if instead of one service a million appears, kubelet starts to choke.

If for some reason you are deleting a deployment (container, image, whatever), just make sure to clean it up completely.

Get to know Go

We've saved our top tip for last. Learn the Go programming language.

Kubernetes is developed in Go, all extensions are written in Go, and the client-go library is also officially supported.

It can be used for different and interesting things. For example, to extend the Kubernetes system to your taste. For example, you can use your own programs to collect data, deploy applications, or simply clean up containers.

Learning the Go programming language and mastering client-go is perhaps the most important piece of advice that can be given to novice Kubernetes users.

Translated with the support of Mail.ru Cloud Solutions

What else to read:

  1. Three levels of autoscaling in Kubernetes and how to use them effectively.
  2. Kubernetes Worker Nodes: Many Small or Few Large?
  3. 25 Useful Tools for Deploying and Managing Kubernetes.

Source: habr.com

Add a comment