Home Mastering Art of Kubernetes
Post
Cancel

Mastering Art of Kubernetes

K8s Configuration Best Practices and Tips

Table of Contents

Building Small Containers

Most developers make the mistake of using the base image out-of-the-box, which may have up to 80% of packages and libraries they don’t need.

Always use smaller container images as it helps you to create faster builds. As a best practice, you should:

  • Go for Alpine Images, as they are 10x smaller than the base images
  • Add necessary libraries and packages as required for your application. Smaller images are also less susceptible to attack vectors due to a reduced attack surface.

Organizing Kubernetes with Namespaces

  • By default, there are three different namespaces in Kubernetes in the beginning: default, kube-public and kube-system. For example, you should create different namespaces for development, testing and production teams. This way, the developer having access to only the development namespace won’t be able to make any changes in the production namespace, even by mistake.
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
  name: development
  namespace: development  
  labels:
    image: development01
spec:
  containers:
    - name: development01
    image: nginx

Health Checks with Readiness and Liveness Probes

How Kubernetes Probes Work

In Kubernetes, probes are managed by the kubelet. The kubelet performs periodic diagnostics on containers running on the node. Unlocking the full potential of a Kubernetes probe demands the application’s compatibility with any of the renderers enumerated below:

  • ExecAction handler—runs an internal command in the container, and success hinges on the command’s completion with status code 0.
  • TCPSocketAction handler—checks for an open port by attempting a TCP connection to the pod’s IP address on the specified port, and the diagnostic is deemed successful when the connection is established.
  • HTTPGetAction handler—performs an HTTP GET request, using the IP address of the pod, a specific port, and a specified path. The diagnostic succeeds if the response code returned is between 200–399.
  • gRPC handler-In the latest Kubernetes release, v1.24, there’s an exciting update: the kubelet now supports leveraging the gRPC Health Checking Protocol for application liveness checks. To make use of this feature, all you need to do is enable the GRPCContainerProbe feature gate.

What are the Three Types of Kubernetes Probes?

  • Readiness probe A readiness probe indicates whether the application running on the container is ready to accept requests from clients:
    • If it succeeds, services matching the pod continue sending traffic to the pod
    • If it fails, the endpoints controller removes the pod from all Kubernetes Services matching the pod
  • Liveness probe A liveness probe indicates if the container is operating:
    • If it succeeds, no action is taken and no events are logged
    • If it fails, the kubelet kills the container, and it is restarted in line with the pod restartPolicy
  • Startup probe A startup probe indicates whether the application running in the container has fully started:
    • If it succeeds, other probes start their diagnostics. When a startup probe is defined, other probes do not operate until it succeeds
    • If it fails, the kubelet kills the container, and is restarted in line with the pod restartPolicy

In this example, the probe pings an application to check if it is still running. If it gets the HTTP response, it then marks the pod as healthy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: Deployment
metadata:
  name: readiness-example
spec:
  ...
    spec:
      containers:
      - name: readiness-example
        image: dbdock/readiness-example:1.0.0
        ...
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 40
          timeoutSeconds: 2
          periodSeconds: 3
          failureThreshold: 2
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 100
          timeoutSeconds: 2
          periodSeconds: 8
          failureThreshold: 1

initialDelaySeconds : How much time after health checks will be start

timeoutSeconds : How long to wait for the response of your request

periodSeconds : How long will these requests be forwarded for testing

successThreshold : After how many successful requests will it be considered successful

failureThreshold : After hoy many failed requests will it be considered unsuccessful

Setting Resource Requests and Limits

  • Occasionally deploying an application to a production cluster can fail due limited resources available on that cluster. This is a common challenge when working with a Kubernetes cluster and it’s caused when resource requests and limits are not set. Without resource requests and limits, pods in a cluster can start utilizing more resources than required. If the pod starts consuming more CPU or memory on the node, then the scheduler may not be able to place new pods, and even the node itself may crash.

  • Resource requests specify the minimum amount of resources a container can use

  • Resource limits specify the maximum amount of resources a container can use.

In this example, we have set the limit of CPU to 800 millicores and memory to 256 mebibytes. The maximum request which the container can make at a time is 400 millicores of CPU and 128 mebibyte of memory.

1
2
3
4
5
6
7
8
9
10
containers:
  - name: container1
    image: busybox
    resources:
      requests:
        memory: “128Mi”
        cpu: “400m”
      limits:
        memory: “256Mi”
        cpu: “800m”
  • The CPU is known as a compressible resource, so when your application withstands these CPU limits, k8s will start throttling the application’s CPU usage, so that only the performance of the application will decrease. The application will not be terminated.

  • However, since Memory is not a compressible resource, the application will be terminated when it reaches or exceeds the given limit.

Use Labels

  • For example, let’s say you are running two instances of one type of application. Both are similarly named, but each application is used by different teams (e.g., development and testing). You can help your teams differentiate between the similar applications by defining a label which uses their team’s name to demonstrate ownership.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
  name: ops-pod
  labels:
    environment: operations
    team: ops01
spec:
  containers:
    - name: ops01
      image: "Ubuntu"
      resources:
        limits:
          cpu: 1
This post is licensed under CC BY 4.0 by the author.