Building applications for Kubernetes is both a challenge and an opportunity―a challenge because the options and complexity to develop for Kubernetes are evolving rapidly, an opportunity because, if done right, your applications will go into production quicker, scale easier, and run smoother.
This book outlines the impact of Containers and Kubernetes on modern software development and discusses the application frameworks to pick from, how to design an application, and how to develop for and on Kubernetes. You are guided through the application life cycle: development, build, and deployment into the runtime phase. In each phase, you see how it ties to Kubernetes and how to leverage its manifold capabilities. Applications will be more lightweight, easier to maintain, and simpler to operate by just focusing on the business logic.
This book provides a strong technical foundation in modern software development and operations. Practical examples show you how to apply the concepts and teach you the full potential of Kubernetes.
What You Will Learn
- Get hands-on experience developing, building, and deploying software to Kubernetes
- Develop your software to get the best out of Kubernetes
- Focus on business logic while leveraging Kubernetes services
- Design application components of different granularity from application server-based services to lightweight services
- Automate deployments and Day 2 operations
Who This Book Is ForDevelopers who want to close the gap between development and the production environment in order to gain high delivery performance in terms of throughput and stability. This book also targets application operations and DevOps engineers.
Author(s): Benjamin Schmeling, Maximilian Dargatz
Publisher: Apress
Year: 2022
Language: English
Pages: 416
Table of Contents
About the Authors
About the Technical Reviewer
Acknowledgments
Introduction
Foreword
Chapter 1: The Impact of Kubernetes on Development
Objective and Prerequisites
How to Read This Book?
Kubernetes Basics
What is Kubernetes?
Getting Started with Kubernetes
The Kubernetes Architecture
Node Types
Master Node Components
Etcd
Kube-apiserver
Kube-Controller-Manager
Kube-Scheduler
Worker Node Components
Kubelet
Container Runtime
Kube-Proxy
Basic Concepts in Kubernetes
Container
How to Use It?
What Is Different?
Pod
How to Use It?
What Is Different?
ReplicaSet
How to Use It?
What Is Different?
Deployment
How to Use It?
What Is Different?
Job, Service, and Ingress
What Is a Job?
What Is a Service?
NodePort
What Is an Ingress?
What Is Different?
Persistent Volumes and Persistent Volume Claims
How to Use Them?
What Is Different?
ConfigMaps and Secrets
What Is a ConfigMap?
How to Use It?
What Is a Secret?
How to Use It?
What Is Different?
Namespaces
What Is a Namespace?
What Is Different?
Other Concepts
Wrapping It Up
Chapter 2: Application Design Decisions
The Local News Application
Architectural Decisions
Dividing the Application into Subcomponents
Hexagonal Architecture – How to Structure Our Source Code?
Domain-Driven Design – The Road to Microservices?
Microservices – A Perfect Match?
Independence of Services
Size of a Service
Technology Decisions
Language, Runtime, and Frameworks
Language – Does It Really Matter?
General-Purpose Languages
Domain-Specific Languages (DSL)
Polyglot Programming – Mixing Programming Languages at Different Levels
Runtimes – Which Role Do They Play?
Application Servers – Does Kubernetes Make Them Obsolete?
Frameworks – What Impact Could They Have?
Standards
Startup Time
Container Deployment
Health Checks
Application Metrics
Packaging Approaches
Image Hierarchies
Application-Specific Images
Self-Contained Executables
Web Archives
Multilayered Application Images
Excursion: Discussing Non-functional Requirements for Kubernetes-Native Applications
Scalability – Following the Demand
Response Time and Availability
Optimizing Process Startup Time
Optimizing Pull Time
Security – What Is Inside Our Image?
Modularity – Separation of Concerns
Transparently Integrated Platform Services
Contractually Integrated Platform Services
Interface Integrated Platform Services
Tightly Integrated Platform Services
Platform Independence – Decoupling Applications from Kubernetes
Cleaning Up
Wrapping It Up
Chapter 3: Developing on and with Kubernetes
One Size Fits All?
Revisiting the Local News Application
The Journey to Kubernetes-Native Development
1: Docker-Less
Considerations
Coding Example
Advantages to Be Preserved
Challenges
2: Dev-to-Docker
Considerations
Coding Examples
Running the News-Frontend in Your Local Container
Running the Whole Local News Application with Compose
Optimizing the Approach
Advantages
Challenges
3: Dev-to-K8s
Considerations
Coding Examples
Manual Deployment to Kubernetes
Cleaning Up
Local Development – Execution on Kubernetes
Using Odo to Develop the News-Backend Component
Deploying with Helm
Cleaning Up
Local Development – Hybrid Execution
Installing the Application with Helm
Intercepting Traffic from the Location-Extractor Component
Cleaning Up
Development on Kubernetes – Execution on Kubernetes
Installing Eclipse Che
Setting Up a Workspace for the Local News Application
Optimizing Your Workspace for One Component
Cleaning Up
Wrapping It Up
Chapter 4: Writing Kubernetes-Native Applications
The Kubernetes Downward API – Who Am I? And If So, How Many?
How Can Our Application Access This Information?
Cleaning Up
Interacting with the Kubernetes API
The RESTful Kubernetes API
Using Client Libraries to Access the API
Authenticate and Authorize Against the API
Cleaning Up
Defining Our Own Kubernetes Resource Types
The Custom Resource Definition (CRD) – Schema for Your Custom Resource
Kubectl vs. User Interface
Attempt 1 – Let the Backend Do the Job
Attempt 2 – Extending the Feed-Scraper
Attempt 3 – Writing a Custom Controller
Attempt 4 – Let the Kubernetes Job Do the Job
Cleaning Up
What Is a Kubernetes-Native Application?
Everything Is a Resource – So Treat It Like That
Don’t Reinvent the Wheel – Make Use of Kubernetes’ Capabilities Whenever Possible
Wrapping It Up
Chapter 5: Kubernetes-Native Pipelines
Deployment Environments
Development
Integration
Test
Preproduction
Production
Deployment Environments in Kubernetes
Kubernetes Cluster per Environment
Kubernetes Namespace per Environment
Clusters or Namespaces per Environment
Container Builds
Why Is Kubernetes a Good Fit for Container Builds?
Kubernetes Pipelines
What Is a Pipeline?
Why Is Kubernetes a Good Fit to Run Pipelines?
What Is Tekton?
How Do We Install Tekton?
Building a Pipeline for the News-Backend
What Is a Tekton Task?
Assembling the Pipeline
Fork the Git Repository and Configure the Pipeline
Cloning the Sources
Packaging the Sources
Building the Image and Pushing It
Helm Deploy
Role-Based Access Control and Authentication
Configure Your Own Secrets to Authenticate
Run the Pipeline
Triggering the Pipeline with a Git Push
Installing Tekton Triggers
Cleaning Up
Generic vs. Specific Pipelines
GitOps
Adapting the Pipeline for GitOps
Set Up the GitOps Tool ArgoCD
Running the Full GitOps Workflow
Cleaning Up
Wrapping It Up
Chapter 6: Operations As Code with Kubernetes Operators and GitOps
Kubernetes Operators – How to Automate Operations
What Is an Operator?
The Operator Design Pattern
Kubernetes Operators
Operator Capabilities
Installation
Upgrade
Backup and Restore
Reconfigure/Repair
Collect Metrics
(Auto)scale
What Is a Capability Level?
Level 1 – Basic Install
Level 2 – Seamless Upgrades
Level 3 – Full Lifecycle
Level 4 – Deep Insights
Level 5 – Autopilot
Develop Your Own Operator
Helm-Based Operator with the Operator SDK
Initializing the Project
Running Our Operator
Create an Instance of the Application
Modifying the CRD by Adding Helm Parameters
Modifying Resources Owned by the Operator
Deleting the CRD
One Chart to Rule Them All?
Cleaning Up
Deploying Our Operator to Kubernetes
Cleaning Up
Advanced: Go-Based Operator with Operator SDK
Implementing Our CRD with Go Structs
Writing the Controller Reconciliation Logic
Deleting Managed Resources Using Owner References
Setting the Status Field
Raising the Capability Level
Choosing the Right Type of Operator
Advanced: The Operator Lifecycle Manager – Who Manages the Operators?
The OLM Packaging Format
Deploying Our Operator via OLM
Generating the OLM Bundle for Our Own Operator
Building and Pushing the OLM Bundle Image
Installing the OLM Bundle
What Happened to Our Bundle?
How Does the OLM Install Our Operator?
Cleaning Up
Deploying Operators via OLM Without Operator SDK
Operators Love GitOps
Local News Loves GitOps and Operators
Wrapping It Up
Closing Words and Outlook
Index