# part-1# Kubernetes Design Patterns Pattern? - A pattern describes a repeatable solution to a problem - Kubernetes can help developers write cloud-native apps, and it provides a library of application programing interfaces (APIs) and tools for building applications. - However, Kubernetes doesn’t provide developers and architects with guidelines for how to use these pieces to build a complete system that meets business needs and goals. - Patterns are a way to reuse architectures. Instead of completely creating the architecture yourself, you can use existing Kubernetes patterns, which also ensure that things will work the way they’re supposed to. - Think of a pattern like a blueprint; it shows you the way to solve a whole class of similar problems. A pattern is more than just step-by-step instructions for fixing one specific problem. Ref: https://www.redhat.com/en/topics/cloud-native-apps/introduction-to-kubernetes-patterns ![k8s design patterns](https://i.imgur.com/afSYWTl.png) ### There are 21 patterns devided into 4 groups 1. Foundational Pattern 2. Behaviour Pattern 3. Structural Pattern 4. Configuration Pattern - `Foundational patterns` cover the core concepts of Kubernetes. These patterns are the underlying principles and practices for building container-based cloud-native applications. - `Behavioral patterns` describe the patterns that sit on top of foundational patterns and add granularity to concepts for managing various types of container and platform interactions. - `Structural patterns` are related to organizing containers within a Kubernetes pod. - `Configuration patterns` are used for the various ways application configuration can be handled in Kubernetes. These patterns include the specific steps for connecting applications to their configuration. Advanced patterns include advanced concepts, such as how the platform itself can be extended or how to build container images directly within the cluster. We are going to focus on top 10 --- # :fire: Problem :fire: - Suppose you have built container for application - Let's call it WebApp - Application require initilization before you run it - How you will solve this problem? --- ### Initilization like: - Database schema setup - Pull require data - Setup permissions on filesystem - Delay startup until an external dependency is satisfied --- # What's the Solution? ### :bulb: You also have to think about seperation of concern --- #### Solution :sparkles: init container :sparkles: --- ### Init Containers - Enable separation of concerns - Provides separate lifecycle for initialization-related tasks distinct from the main application containers - Init Containers in Kubernetes are part of the Pod definition --- ## Pod lifecycle ![](https://i.imgur.com/M7XQM6r.png) *Ref: openshift.com* --- ### Use case 1# Pull require data from Github - Http server will serve data from git repository - git repository needs to be pull before http server startup. --- ### Practical --- ### Things to note: - All containers within Pod share resource limit, volumes and security settings - There is no rediness check for init container. - If init container failed then whole Pod will restart - Init container must terminate successfully, so that actual application will run. - First, init containers run a sequence, then all application containers run in parallel --- ### Use case 2# Delay startup until an external dependency is satisfied - Create Pod defination with initContainer and app using busybox:1.28.4 image - init container will do dns lookup to `db.default.svc.cluster.local` until it get resolves - then app container should start using busybox:1.28.4 image and add sleep command to keep container running --- ### Structural Pattern - Init Container is part of SP --- # Sidecar --- ### App logging ![](https://i.imgur.com/zGRgjUy.png) --- ## With Sidecar ![](https://i.imgur.com/3wD55M0.png) --- ## Sidecar - Extends and enhances the functionality of a preexisting container without changing it - Allows us to combine multiple con‐ tainers into a single unit. ### Example: ```yaml metadata: name: simple-webapp labels: app: webapp spec: containers: - name: main-application image: nginx volumeMounts: - name: shared-logs mountPath: /var/log/nginx - name: sidecar-container image: busybox command: ["sh","-c","while true; do cat /var/log/nginx/access.log; sleep 30; done"] volumeMounts: - name: shared-logs mountPath: /var/log/nginx volumes: - name: shared-logs emptyDir: {} ``` ```yaml apiVersion: v1 kind: Pod metadata: name: sidecar spec: containers: - name: server image: httpd ports: - containerPort: 80 volumeMounts: - mountPath: /usr/local/apache2/htdocs/ name: source - name: sync image: alpine/git command: - "sh" - "-c" - "git clone https://github.com/gabrielecirulli/2048 . && watch -n 30 git pull" workingDir: /source volumeMounts: - mountPath: /source name: source volumes: - emptyDir: {} name: source ``` --- # Configuration Design Pattern All applications require configuration, and although storing configurations in the source code is an easy option, it doesn’t give you the flexibility to adapt configuration without recreating the app image. External configuration allows you to adapt based on the environment. Configuration patterns will help you to customize and adapt your apps with external configurations for different development, integration, and production environments. - EnvVar - ConfigMaps --- # Introspective Pattern Applications that run on bare-metal clusters know precisely where they are running, the specification of the system, and their network information. This information helps them to work in a self-aware environment. For instance, these applications can align their resource usage, enhance their logs with more data, or send their node-related metric data. In the microservice architecture, applications are considered ephemeral with less dependency than the environment they are running on. However, self-awareness about runtime information, namely the introspective pattern, could increase the utility and discoverability of applications in distributed systems. In Kubernetes, the Downward API ensures that the following environment and runtime data is provided for the pods: ``` Environment: Node name, namespace, CPU, and memory limitations. Networking: Pod IP. Authorization: Service account. ``` In the following activity, a simple but self-aware Kubernetes application will be created and installed. The application has all of the runtime information, which is provided by Kubernetes as environment variables. Being a single application, it logs all of these variables to the console. However, the pod definition that's developed throughout this activity shows you how to use the Downward API inside containers to implement an introspective pattern in Kubernetes. ### Activity: Injecting Data into Applications Scenario: You are assigned the task of making a Kubernetes installation for a simple application with self-awareness. In this installation, the application should collect all the runtime information from Kubernetes and write to its logs. Aim: With the successful deployment, there should be a pod running in Kubernetes with only one container. In this container, all available runtime information should be injected as environment variables. Also, the application should log runtime information. Prerequisites Use the Kubernetes Downward API to collect runtime information. Steps for Completion - Create a pod definition with one container: - Define the environment variables from the Downward API. - Create a shell script to write the environment variables. - Deploy the pod. - Check the status of the pod. - Check the logs of the container. ```yaml apiVersion: v1 kind: Pod metadata: name: inject spec: containers: - name: app image: busybox command: [ "sh", "-c"] args: - while true; do echo -en '\n'; echo My node name is $MY_NODE_NAME and living in namespace $MY_POD_NAMESPACE; echo Pod IP is $MY_POD_IP and my service account is $MY_POD_SERVICE_ACCOUNT; echo Running with the memory limit of $MY_MEM_LIMIT and request of $MY_MEM_REQUEST; echo Running with the CPU limit of $MY_CPU_LIMIT and request of $MY_CPU_REQUEST; sleep 10; done; resources: requests: memory: "32Mi" cpu: "125m" limits: memory: "64Mi" cpu: "250m" env: - name: MY_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: MY_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: MY_POD_SERVICE_ACCOUNT valueFrom: fieldRef: fieldPath: spec.serviceAccountName - name: MY_CPU_REQUEST valueFrom: resourceFieldRef: resource: requests.cpu - name: MY_CPU_LIMIT valueFrom: resourceFieldRef: resource: limits.cpu - name: MY_MEM_REQUEST valueFrom: resourceFieldRef: resource: requests.memory - name: MY_MEM_LIMIT valueFrom: resourceFieldRef: resource: limits.memory ``` Ref: - https://www.packtpub.com/product/kubernetes-design-patterns-and-extensions/9781789619270 - https://github.com/TrainingByPackt/Kubernetes-Design-Patterns-and-Extensions-eLearning/tree/master/Lesson01
{"metaMigratedAt":"2023-06-15T16:21:19.276Z","metaMigratedFrom":"YAML","title":"Kubernetes Design Patterns part-1","breaks":true,"description":"k8s Demo","contributors":"[{\"id\":\"b228d871-c4d8-45ba-b8ba-cb14b1769868\",\"add\":10384,\"del\":2680}]"}
    366 views