Cloud Native Spring in Action: With Spring Boot and Kubernetes
1617298425, 9781617298424
Build and deliver production-grade cloud-native apps with Spring framework and Kubernetes.
In Cloud Native Spring in A
682
140
11MB
English
Pages 664
Year 2023
Report DMCA / Copyright
DOWNLOAD EPUB FILE
Table of contents :
Cloud Native Spring in Action
brief contents
contents
foreword
preface
acknowledgments
about this book
Who should read this book?
How this book is organized: A road map
About the code
liveBook discussion forum
Other online resources
about the author
about the cover illustration
Part 1—Cloud native fundamentals
1 Introduction to cloud native
1.1 What is cloud native?
1.1.1 The Three Ps of Cloud Native
1.2 The cloud and the cloud computing model
1.2.1 Infrastructure as a Service (IaaS)
1.2.2 Container as a Service (CaaS)
1.2.3 Platform as a Service (PaaS)
1.2.4 Function as a Service (FaaS)
1.2.5 Software as a Service (SaaS)
1.3 Properties of cloud native applications
1.3.1 Scalability
1.3.2 Loose coupling
1.3.3 Resilience
1.3.4 Observability
1.3.5 Manageability
1.4 Culture and practices supporting cloud native
1.4.1 Automation
1.4.2 Continuous delivery
1.4.3 DevOps
1.5 Is the cloud your best option?
1.5.1 Speed
1.5.2 Resilience
1.5.3 Scale
1.5.4 Cost
1.6 Cloud native topologies
1.6.1 Containers
1.6.2 Orchestration
1.6.3 Serverless
1.7 Architectures for cloud native applications
1.7.1 From multi-tiered to microservices architectures and beyond
1.7.2 Service-based architecture for cloud native applications
Summary
2 Cloud native patterns and technologies
2.1 Cloud native development principles: 12 Factors and beyond
2.1.1 One codebase, one application
2.1.2 API first
2.1.3 Dependency management
2.1.4 Design, build, release, run
2.1.5 Configuration, credentials, and code
2.1.6 Logs
2.1.7 Disposability
2.1.8 Backing services
2.1.9 Environment parity
2.1.10 Administrative processes
2.1.11 Port binding
2.1.12 Stateless processes
2.1.13 Concurrency
2.1.14 Telemetry
2.1.15 Authentication and authorization
2.2 Building cloud native applications with Spring
2.2.1 Overview of the Spring landscape
2.2.2 Building a Spring Boot application
2.3 Containerizing applications with Docker
2.3.1 Introducing Docker: Images and containers
2.3.2 Running a Spring application as a container
2.4 Managing containers with Kubernetes
2.4.1 Introducing Kubernetes: Deployments, Pods, and Services
2.4.2 Running a Spring application on Kubernetes
2.5 Polar Bookshop: A cloud native application
2.5.1 Understanding the requirements of the system
2.5.2 Exploring patterns and technologies used in the project
Summary
Part 2—Cloud native development
3 Getting started with cloud native development
3.1 Bootstrapping a cloud native project
3.1.1 One codebase, one application
3.1.2 Dependency management with Gradle and Maven
3.2 Working with embedded servers
3.2.1 Executable JARs and embedded servers
3.2.2 Understanding the thread-per-request model
3.2.3 Configuring the embedded Tomcat
3.3 Building a RESTful application with Spring MVC
3.3.1 REST API first, business logic later
3.3.2 Implementing a REST API with Spring MVC
3.3.3 Data validation and error handling
3.3.4 Evolving APIs for future requirements
3.4 Testing a RESTful application with Spring
3.4.1 Unit tests with JUnit 5
3.4.2 Integration tests with @SpringBootTest
3.4.3 Testing REST controllers with @WebMvcTest
3.4.4 Testing the JSON serialization with @JsonTest
3.5 Deployment pipeline: Build and test
3.5.1 Understanding the commit stage of the deployment pipeline
3.5.2 Implementing the commit stage with GitHub Actions
Summary
4 Externalized configuration management
4.1 Configuration in Spring: Properties and profiles
4.1.1 Properties: Key/value pairs for configuration
4.1.2 Profiles: Feature flags and configuration groups
4.2 Externalized configuration: One build, multiple configurations
4.2.1 Configuring an application through command-line arguments
4.2.2 Configuring an application through JVM system properties
4.2.3 Configuring an application through environment variables
4.3 Centralized configuration management with Spring Cloud Config Server
4.3.1 Using Git to store your configuration data
4.3.2 Setting up a configuration server
4.3.3 Making the configuration server resilient
4.3.4 Understanding the configuration server REST API
4.4 Using a configuration server with Spring Cloud Config Client
4.4.1 Setting up a configuration client
4.4.2 Making the configuration client resilient
4.4.3 Refreshing configuration at runtime
Summary
5 Persisting and managing data in the cloud
5.1 Databases for cloud native systems
5.1.1 Data services in the cloud
5.1.2 Running PostgreSQL as a container
5.2 Data persistence with Spring Data JDBC
5.2.1 Connecting to a database with JDBC
5.2.2 Defining persistent entities with Spring Data
5.2.3 Enabling and configuring JDBC auditing
5.2.4 Data repositories with Spring Data
5.3 Testing data persistence with Spring and Testcontainers
5.3.1 Configuring Testcontainers for PostgreSQL
5.3.2 Testing data persistence with @DataJdbcTest and Testcontainers
5.3.3 Integration tests with @SpringBootTest and Testcontainers
5.4 Managing databases in production with Flyway
5.4.1 Understanding Flyway: Version control for your database
5.4.2 Initializing a database schema with Flyway
5.4.3 Evolving a database with Flyway
Summary
6 Containerizing Spring Boot
6.1 Working with container images on Docker
6.1.1 Understanding container images
6.1.2 Creating images with Dockerfiles
6.1.3 Publishing images on GitHub Container Registry
6.2 Packaging Spring Boot applications as container images
6.2.1 Preparing Spring Boot for containerization
6.2.2 Containerizing Spring Boot with Dockerfiles
6.2.3 Building container images for production
6.2.4 Containerizing Spring Boot with Cloud Native Buildpacks
6.3 Managing Spring Boot containers with Docker Compose
6.3.1 Using Docker Compose to manage the container life cycle
6.3.2 Debugging Spring Boot containers
6.4 Deployment pipeline: Package and publish
6.4.1 Building release candidates in the commit stage
6.4.2 Publishing container images with GitHub Actions
Summary
7 Kubernetes fundamentals for Spring Boot
7.1 Moving from Docker to Kubernetes
7.1.1 Working with a local Kubernetes cluster
7.1.2 Managing data services in a local cluster
7.2 Kubernetes Deployments for Spring Boot
7.2.1 From containers to Pods
7.2.2 Controlling Pods with Deployments
7.2.3 Creating a Deployment for a Spring Boot application
7.3 Service discovery and load balancing
7.3.1 Understanding service discovery and load balancing
7.3.2 Client-side service discovery and load balancing
7.3.3 Server-side service discovery and load balancing
7.3.4 Exposing Spring Boot applications with Kubernetes Services
7.4 Scalability and disposability
7.4.1 Ensuring disposability: Fast startup
7.4.2 Ensuring disposability: Graceful shutdown
7.4.3 Scaling Spring Boot applications
7.5 Local Kubernetes development with Tilt
7.5.1 Inner development loop with Tilt
7.5.2 Visualizing your Kubernetes workloads with Octant
7.6 Deployment pipeline: Validate Kubernetes manifests
7.6.1 Validating Kubernetes manifests in the commit stage
7.6.2 Automating Kubernetes manifests validation with GitHub Actions
Summary
Part 3—Cloud native distributed systems
8 Reactive Spring: Resilience and scalability
8.1 Asynchronous and non-blocking architectures with Reactor and Spring
8.1.1 From thread-per-request to event loop
8.1.2 Project Reactor: Reactive streams with Mono and Flux
8.1.3 Understanding the Spring reactive stack
8.2 Reactive servers with Spring WebFlux and Spring Data R2DBC
8.2.1 Bootstrapping a reactive application with Spring Boot
8.2.2 Persisting data reactively with Spring Data R2DBC
8.2.3 Implementing the business logic with reactive streams
8.2.4 Exposing a REST API with Spring WebFlux
8.3 Reactive clients with Spring WebClient
8.3.1 Service-to-service communication in Spring
8.3.2 Understanding how to exchange data
8.3.3 Implementing REST clients with WebClient
8.4 Resilient applications with Reactive Spring
8.4.1 Timeouts
8.4.2 Retries
8.4.3 Fallbacks and error handling
8.5 Testing reactive applications with Spring, Reactor, and Testcontainers
8.5.1 Testing REST clients with a mock web server
8.5.2 Testing data persistence with @DataR2dbcTest and Testcontainers
8.5.3 Testing REST controllers with @WebFluxTest
Summary
9 API gateway and circuit breakers
9.1 Edge servers and Spring Cloud Gateway
9.1.1 Bootstrapping an edge server with Spring Cloud Gateway
9.1.2 Defining routes and predicates
9.1.3 Processing requests and responses through filters
9.2 Fault tolerance with Spring Cloud Circuit Breaker and Resilience4J
9.2.1 Introducing circuit breakers with Spring Cloud Circuit Breaker
9.2.2 Configuring a circuit breaker with Resilience4J
9.2.3 Defining fallback REST APIs with Spring WebFlux
9.2.4 Combining circuit breakers, retries, and time limiters
9.3 Request rate limiting with Spring Cloud Gateway and Redis
9.3.1 Running Redis as a container
9.3.2 Integrating Spring with Redis
9.3.3 Configuring a request rate limiter
9.4 Distributed session management with Redis
9.4.1 Handling sessions with Spring Session Data Redis
9.5 Managing external access with Kubernetes Ingress
9.5.1 Understanding Ingress API and Ingress Controller
9.5.2 Working with Ingress objects
Summary
10 Event-driven applications and functions
10.1 Event-driven architectures
10.1.1 Understanding the event-driven models
10.1.2 Using the pub/sub model
10.2 Message brokers with RabbitMQ
10.2.1 Understanding AMQP for messaging systems
10.2.2 Using RabbitMQ for publish/subscribe communications
10.3 Functions with Spring Cloud Function
10.3.1 Using the functional paradigm in Spring Cloud Function
10.3.2 Composing and integrating functions: REST, serverless, data streams
10.3.3 Writing integration tests with @FunctionalSpringBootTest
10.4 Processing messages with Spring Cloud Stream
10.4.1 Configuring the integration with RabbitMQ
10.4.2 Binding functions to message channels
10.4.3 Writing integration tests with a test binder
10.4.4 Making messaging resilient to failures
10.5 Producing and consuming messages with Spring Cloud Stream
10.5.1 Implementing event consumers, and the problem of idempotency
10.5.2 Implementing event producers, and the problem of atomicity
Summary
11 Security: Authentication and SPA
11.1 Understanding the Spring Security fundamentals
11.2 Managing user accounts with Keycloak
11.2.1 Defining a security realm
11.2.2 Managing users and roles
11.3 Authentication with OpenID Connect, JWT, and Keycloak
11.3.1 Authenticating users with OpenID Connect
11.3.2 Exchanging user information with JWT
11.3.3 Registering an application in Keycloak
11.4 Authenticating users with Spring Security and OpenID Connect
11.4.1 Adding the new dependencies
11.4.2 Configuring the integration between Spring Security and Keycloak
11.4.3 Basic Spring Security configuration
11.4.4 Inspecting the authenticated user context
11.4.5 Configuring user logout in Spring Security and Keycloak
11.5 Integrating Spring Security with SPAs
11.5.1 Running an Angular application
11.5.2 Controlling the authentication flow
11.5.3 Protecting against Cross-Site Request Forgery
11.6 Testing Spring Security and OpenID Connect
11.6.1 Testing OIDC authentication
11.6.2 Testing CSRF
Summary
12 Security: Authorization and auditing
12.1 Authorization and roles with Spring Cloud Gateway and OAuth2
12.1.1 Token relay from Spring Cloud Gateway to other services
12.1.2 Customizing tokens and propagating user roles
12.2 Protecting APIs with Spring Security and OAuth2 (imperative)
12.2.1 Securing Spring Boot as an OAuth2 Resource Server
12.2.2 Role-based access control with Spring Security and JWT
12.2.3 Testing OAuth2 with Spring Security and Testcontainers
12.3 Protecting APIs with Spring Security and OAuth2 (reactive)
12.3.1 Securing Spring Boot as an OAuth2 Resource Server
12.3.2 Testing OAuth2 with Spring Security and Testcontainers
12.4 Protecting and auditing data with Spring Security and Spring Data
12.4.1 Auditing data with Spring Security and Spring Data JDBC
12.4.2 Testing data auditing with Spring Data and @WithMockUser
12.4.3 Protecting user data with Spring Security and Spring Data R2DBC
12.4.4 Testing data auditing and protection with @WithMockUser and Spring Data R2DBC
Summary
Part 4—Cloud native production
13 Observability and monitoring
13.1 Logging with Spring Boot, Loki, and Fluent Bit
13.1.1 Logging with Spring Boot
13.1.2 Managing logs with Loki, Fluent Bit, and Grafana
13.2 Health probes with Spring Boot Actuator and Kubernetes
13.2.1 Defining health probes for Spring Boot applications using Actuator
13.2.2 Configuring health probes in Spring Boot and Kubernetes
13.3 Metrics and monitoring with Spring Boot Actuator, Prometheus, and Grafana
13.3.1 Configuring metrics with Spring Boot Actuator and Micrometer
13.3.2 Monitoring metrics with Prometheus and Grafana
13.3.3 Configuring Prometheus metrics in Kubernetes
13.4 Distributed tracing with OpenTelemetry and Tempo
13.4.1 Managing traces with Tempo and Grafana
13.4.2 Configuring tracing in Spring Boot with OpenTelemetry
13.5 Application management and monitoring with Spring Boot Actuator
13.5.1 Monitoring Flyway migrations in Spring Boot
13.5.2 Exposing application information
13.5.3 Generating and analyzing heap dumps
Summary
14 Configuration and secrets management
14.1 Configuring applications on Kubernetes
14.1.1 Securing the configuration server with Spring Security
14.1.2 Refreshing configuration at runtime with Spring Cloud Bus
14.1.3 Managing secrets with Spring Cloud Config
14.1.4 Disabling Spring Cloud Config
14.2 Using ConfigMaps and Secrets in Kubernetes
14.2.1 Configuring Spring Boot with ConfigMaps
14.2.2 Storing sensitive information with Secrets (or not)
14.2.3 Refreshing configuration at runtime with Spring Cloud Kubernetes
14.3 Configuration management with Kustomize
14.3.1 Using Kustomize to manage and configure Spring Boot applications
14.3.2 Managing Kubernetes configuration for multiple environments with Kustomize
14.3.3 Defining a configuration overlay for staging
14.3.4 Customizing environment variables
14.3.5 Customizing ConfigMaps
14.3.6 Customizing image name and version
14.3.7 Customizing the number of replicas
Summary
15 Continuous delivery and GitOps
15.1 Deployment pipeline: Acceptance stage
15.1.1 Versioning release candidates for continuous delivery
15.1.2 Understanding the acceptance stage of the deployment pipeline
15.1.3 Implementing the acceptance stage with GitHub Actions
15.2 Configuring Spring Boot for production
15.2.1 Defining a configuration overlay for production
15.2.2 Configuring CPU and memory for Spring Boot containers
15.2.3 Deploying Spring Boot in production
15.3 Deployment pipeline: Production stage
15.3.1 Understanding the production stage of the deployment pipeline
15.3.2 Implementing the production stage with GitHub Actions
15.4 Continuous deployment with GitOps
15.4.1 Implementing GitOps with Argo CD
15.4.2 Putting it all together
Summary
16 Serverless, GraalVM, and Knative
16.1 Native images with Spring Native and GraalVM
16.1.1 Understanding GraalVM and native images
16.1.2 Introducing GraalVM support for Spring Boot with Spring Native
16.1.3 Compiling Spring Boot applications as native images
16.2 Serverless applications with Spring Cloud Function
16.2.1 Building serverless applications with Spring Cloud Function
16.2.2 Deployment pipeline: Build and publish
16.2.3 Deploying serverless applications on the cloud
16.3 Deploying serverless applications with Knative
16.3.1 Setting up a local Knative platform
16.3.2 Deploying applications with the Knative CLI
16.3.3 Deploying applications with the Knative manifests
Summary
appendix A—Setting up your development environment
A.1 Java
A.2 Docker
A.3 Kubernetes
A.4 Other tools
A.4.1 HTTPie
A.4.2 Grype
A.4.3 Tilt
A.4.4 Octant
A.4.5 Kubeval
A.4.6 Knative CLI
appendix B—Kubernetes in production with DigitalOcean
B.1 Running a Kubernetes cluster on DigitalOcean
B.2 Running a PostgreSQL database on DigitalOcean
B.3 Running Redis on DigitalOcean
B.4 Running RabbitMQ using a Kubernetes Operator
B.5 Running Keycloak using a Helm chart
B.6 Running Polar UI
B.7 Deleting all cloud resources
index
Symbols
Numerics
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
Y
Z