Search
left arrowBack
Pavel Rykov

Pavel Rykov

July 31, 2023 ・ Kubernetes

Implementing an app to run in Kubernetes efficiently

Kubernetes is a container-orchestration system for automating deployment, scaling and management of applications running on containers. It provides an efficient and powerful way to manage containerized applications and services across multiple clusters. This makes it attractive to developers and DevOps teams who want to quickly deploy and manage applications on a distributed infrastructure.

In this article, we will discuss the steps involved in implementing an app to run in Kubernetes efficiently. We will go over best practices for setting up a development environment, developing the application, and setting up the cluster for deploying it. Additionally, we will take a look at some best practices for monitoring and managing application lifecycle in the Kubernetes environment.

Understand the Basics

Before jumping into running an application in Kubernetes, it’s important to familiarize yourself with the basics. Understand the concepts of Pods, Deployments, Services, and Ingress.

Then, learn the kubectl commands you will use most frequently. To start running an application, create your Kubernetes deployment files like the Pod, Deployment, Service and Ingress. Start by running the kubectl create or kubectl apply commands to apply your configurations. Monitor their status using the kubectl get command, and ensure all of your resources and components are created successfully. Once you’ve confirmed everything is in place, use kubectl expose to open up necessary ports and endpoints for external access. Finally, use kubectl scale to adjust the compute resources based on your performance needs.

Have a Plan

Before deploying an application to Kubernetes, have a well thought-out plan. Think through resource requirements, scalability needs, and best practices for availability and redundancy.

Make sure that you have adequate monitoring and logging systems in place, and that you’re aware of any security requirements that you need to address. If you’re deploying to a managed platform such as Google Kubernetes Engine or Amazon Elastic Kubernetes Service, ensure that you understand their specific requirements. Lastly, ensure that you have a good backup strategy in place in case of any unexpected problems.

Security

Kubernetes provides several tools for securing applications. These include namespaces, security contexts, network policies, and authentication and authorization. Plan ahead for these when running an app in Kubernetes.

Namespaces provide segmentation for applications within a Kubernetes cluster. Example of security namespace:

---
apiVersion: v1
kind: Namespace
metadata:
  name: security

Security contexts can be set for each container in a pod for fine grain control of which processes and or users can access each resource. Example of app-security security context in security namespace:

---
apiVersion: v1
kind: SecurityContext
metadata:
  name: app-security
  namespace: security
spec:
  fsGroup: 2000
  runAsUser: 1000

Network policies securely control traffic with rules to set up which pods can communicate with each other. Example of deny all traffic rule as network policy:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-traffic
  namespace: security
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      application: web-application
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0

Authentication and authorization enables requests to the Kubernetes API to be authenticated and authorized. Example of web-application-user service account:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: web-application-user
  namespace: security

Admission controllers can be used to control access to resources such as namespaces, pods, and services. Role settings of web-application-user service account:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: web-application-user
  namespace: security
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Attaching service account to role:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: web-application-user-binding
  namespace: security
subjects:
- kind: ServiceAccount
  name: web-application-user
  namespace: security
roleRef:
  kind: Role
  name: web-application-user
  apiGroup: rbac.authorization.k8s.io

Monitor Performance and Utilization

Kubernetes provides various tools that help you monitor resource utilization. It includes the kubectl command-line tool, the kubectl top command, a dashboard and monitoring tools like, Prometheus and Grafana.

Example output of kubectl top:

NAME                                 CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
deployment/my-app-deployment          32m         0%    546Mi           57%
replicaset/my-app-deployment-f7gcp    0m          0%    27Mi            3%

Example of Grafana Dashboard:

image

kubectl top is used to track resource utilization, while Prometheus in combination with Grafana can help you to analyze performance metrics and detect any issues. You can also use the Kubernetes Dashboard to view real-time resource utilization and detect performance issues. By leveraging these approaches, you can ensure that your Kubernetes clusters are running optimally.

Allocate Resources Appropriately

Kubernetes offers many tools for managing resources, including resource quotas, limits, and autoscaling. Use these tools to ensure optimal performance of the application running in the cluster.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
spec:
  replicas: 5 # number of replicas for the application
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        resources:
          requests: # requests defines the minimum resources required for the container
            memory: "50Mi"
            cpu: "200m"
          limits: # limits defines the max resources the container will use 
            memory: "100Mi"
            cpu: "500m"

Resource quotas are used to limit the amount of resources available to users of the cluster and to ensure that important resources are used fairly and efficiently. Resource limits provide boundaries to the amount of resources that can be used by any pod or deployment. Autoscaling is a process used to automatically adjust the number of pods running in a deployment to ensure that the desired resources are available. This helps optimize the utilization of resources in the cluster and avoids over-provisioning or under-provisioning. With these tools, users can maintain optimal performance of their Kubernetes application.

Leverage Kubernetes Services

Kubernetes provides many services that can be leveraged in the application, such as Ingress, Config Maps, Secrets and Kubernetes Operators. Utilize these services where appropriate.

Ingress

Ingress is a set of routing rules designed to handle external requests and define how they access the applications running in the cluster. It can be used to configure load balancing, SSL termination, and name-based virtual hosting.

---
apiVersion: v1
kind: Ingress
metadata:
  name: default-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: "/"
        backend:
          serviceName: frontend-service
          servicePort: 80

Config Maps

ConfigMap is a store of configuration information that is accessible across pods and services. It can be used to store application configuration across deployments, making application deployments more robust.

--- 
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config-map
data:
  config-key1: config-value1
  config-key2: config-value2

It is worth noting that you can generate ConfigMap in runtime while deploying.

Example of usage in Deployment:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image
        ports:
        - containerPort: 8080
        envFrom:
          - configMapRef:
              name: app-config-map

Secrets

Secrets provide secure storage of sensitive information used by applications. Values in Secrets can stay encrypted in the cluster and will only be decrypted and made available to the application when needed.

---
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  username: admin
  password: supersecret

Example of usage in Deployment:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  template:
    spec:
      containers:
        - name: myapp
          image: myapp:v1
          env:
            - name: USERNAME 
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: username
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: password

Kubernetes Operator

Operators are applications specifically written to manage other applications running in the cluster. They automate provisioning, maintenance, and operation tasks for the applications, making them easier to scale, deploy, and configure.

---
apiVersion: operators.coreos.com/v1
kind: Operator
metadata:
  name: ops-operator
spec:
  image: local/ops-operator:latest
  deploymentName: ops-operator-deployment
  platform: 
    kubernetes:
      resources: 
        limits:
          cpu: 500m
          memory: 512MB
      serviceAccountName: ops-operator-sa

Detailed information about the Kubernetes Operator can be found via the provided link.

Separate Data and Application State

Separating application state from the data stored in the application helps to keep the application and data separate and manageable.

It allows the application to store and manage the data, while the application state can be changed to reflect changes in both data and users of the application. Keeping the application state and data separate allows for easier analysis of the data and changes to the application as needed. This separation also allows for easier data updates, as all changes are made to the application state, which can be easily tracked and updated.

Use Storage Classes

To maximize performance, you should use Kubernetes Storage Classes to ensure that the correct storage options are allocated to your application.

Storage classes allow you to specify the type of storage to be used and also allows you to set the disk size and other elements of storage. This allows you to make sure that the application has the correct mount points and amount of available storage for the application to run.

Storage Classes also support dynamic provisioning, which allows the system to automatically create the storage for your application and remain at a predefined level to either meet the current needs of the app or to promote scalability.

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  replication-type: regional-pd
  zones:
    - <zones-eur-1>
    - <zones-eur-2>  
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Test and Validate

Test the application thoroughly before deploying it to the Kubernetes cluster. This can help to identify any issues that may arise.

Tools such as Codeception can be used to perform integration, acceptance, and performance testing of the application. Such testing should also be done on a regular basis during the CI/CD cycle to ensure the application will respond correctly in the production environment.

In conclusion, before deploying an application on a Kubernetes cluster, it is important to thoroughly test it to ensure it meets the requirements and will respond correctly in production. Automated testing and security checks should be performed, along with regular testing during the CI/CD cycle.

Automate Deployments

Kubernetes allows for automating deployments. Use tools such as Helm and Kubernetes Operators to simplify deploying and managing applications on the cluster.

Helm is a package manager for deploying applications on a Kubernetes cluster. It helps to package, distribute, version, and manage your applications on the Kubernetes cluster. Kubernetes Operators are tools that help to manage stateful applications like databases and queues, automate common tasks, and automate updates. Together Helm and Operators provide an easy way to deploy applications on a Kubernetes cluster. Other tools like GoCD, Jenkins or Weave Flux can help automate deployment of the applications. Ansible can be used to orchestrate complex deployments.

Conclusion

The use of a Kubernetes cluster for running apps is an increasingly popular choice for many organizations. Implementing an app in a Kubernetes cluster may seem daunting, but with the right approach, it can be done successfully and efficiently. The most important steps to consider when implementing an app in Kubernetes cluster are understanding the basics, having a plan, managing security, monitoring performance, allocating resources appropriately, leveraging Kubernetes services, separating data and application state, using storage classes, testing and validating, and automating deployments. Following these steps can help ensure the successful and efficient implementation of an app in a Kubernetes cluster.

By having a clear plan for the implementation of the app, organizations can develop, deploy, and maintain their app more effectively. Additionally, leveraging the services provided by Kubernetes can further optimize the performance of the app and streamline the development process. Finally, creating appropriate automation steps can help reduce the time-to-market of the app.

In conclusion, proper implementation of an app in a Kubernetes cluster requires organizational planning and execution. Organizations should invest the necessary time and resources for setting up a successful infrastructure. Following the above steps can help ensure the successful and efficient implementation of an app in a Kubernetes cluster.

  • Kubernetes
  • Basics