Kubernetes Patterns
Foundational Patterns
- The patterns describe here will help as foundational building blocks of distributed container based k8s native applications
- Predictable Demands
- Declarative Deployment
- Health Probe
- Managed Lifecycle
- Automated Placement
Predictable Demands
- This pattern indicates how we should declare application requirements (hard runtime dependencies or resource requirements)
Problem
- Kubereneces can manage applications developed in different programming languages as long as they are containerized.
- Different languages have different resource requirements
- Besides resource requirements, application runtimes also have dependencies on platform managed capabilities like data storage or application configuration.
Solution
- Figure out dependencies
- Dependency on a Persistent Volume
- Dependency on container port to be mapped to specific port on the host system through hostPort
- Configurations are another type of dependency
- Resource Profiles:
- Compute resources in the contenxt of k8s are defined as something that can be request by, allocated to and consumed from a container. The resources are categorized as
- compressible (such as cpu, network bandwidth) can be throttled
- incompressible (such as memory) cannot be throttled
- Ensure we have request limits specified
- Compute resources in the contenxt of k8s are defined as something that can be request by, allocated to and consumed from a container. The resources are categorized as
- In request and limits section we can use the following keys
- memory:
- This type is for heap memory demands of your application including volumes of type
emptyDir
with configurationmedium: Memory
- This type is for heap memory demands of your application including volumes of type
- cpu: It is recommended that you set request for the CPU resource but no limits so that they can benifit from all excess CPU resources that otherwise would be wasted.
- ephemeral-storage
- hugepage-size
- memory:
- Depending on Whether you specify request, the limits or both, the platform offers three types of Quality of Service (QoS)
- Best-Effort: request or limits not specified
- Burstable: Pods which have unequal amount of requests and limits are tagged as burstable
- Guaranteed: Pods which have same request and limit resources belongs to Guranteed Qos
- In the case when node is under incompressible resource pressure. The priority of killing is
- Best-Effort
- Burstable
- Guranteed
- Recommendation
- For memory always set request equal to limits
- For CPU set request but no limits
- Refer Here for interesting article on why CPU should not have limits Refer Here for recommended memory settings
- PodPriority allows us to indicate the importance of Pod relative to other pods which affects the order in which pods are schedule
- Refer Here this for official k8s docs
- Project Resources: Use Resource quotas
- Refer Here for Limit range
Declarative Deployment
Problem
- Provisioning isolated environments as namespaces in a self service manner and place the application in these environments with minimal human intervention through scheduler.
- But with a growing number of microservices, continuously updating and replacing them with newer versions becomes an increasing burden.
Solution
- Using concept opf deployment has automated application upgrades.
- A Deployment can be fully managed by updating the k8s resources files howeever
kubectl rollout
comes in very handy- kubectl rollout status
- kubectl rollout pause
- kubectl rollout resume
- kubectl rollout undo
- kubectl rollout history
- kubectl rollout restart
- Rolling Deployment: This ensures zero downtime deployment during update
- FixedDeployment: Recreate
- Blue Green: Refer Here
- Canary: Refer Here
Health Probe
Problem
- k8s regularly checks the container porcess status and restarts it if issues are detected.
- This is not enough and we need reliable way to check the health of applications
Solution
- Process Health Checks
- Liveness Probes
- Readiness Probes
- Readiness Gates: Refer Here Refer Here
Managed Lifecycle
- Refer Here here for life cycle and Refer Here
Automated Placements
- This is about where to place new pods
- nodeSelctor
- node Affinity
- Pod Affinitiy and Anti Affinity
- Taints and Tolerations
Behavioral Patterns
- These patterns are focused on communciations and interactions between Pods and the managing Platoform
- Batch Job
- Periodic Job
- Daemon Service
- Singleton Service
- Stateless Service
- Stateful Service
- Service Discovery (with service mesh)
- Self Awareness (with service mesh)
Singleton Service
Problem
- k8s can easily scale applications. In some cases, only one instance of the service is allowed to run at a time
Solution
- This can be implemented by locking
- PodDisruptionBudget
Structural Patterns
- These patterns are focused on structuring and organizing containers in Pod to satisfy different usecases
- Init Containers
- Sidecar
- Adapter
- Ambassador
Adapter
Problem
- Containers allows us to package and run applications written in different languages in a unified way.
- This heterogenous components can cause difficulties when all components have to treated in a unified way by other systes.
Solution
- Adapter pattern offers a solution by hiding the complexity of system and providing a unified access to it
Ambassador
Problem
- Containerized services dont exist in isolation an very often they have to access other services.
- The difficulty in acecssing other services may be due to changing address, unreliable protocol etc