Accelerating Java Applications on Azure Kubernetes Service with CRaC
Overview
Packaging a Java Application
1. Clone the Repository and build the Application:
cd spring-petclinic
<groupId>org.crac</groupId>
<artifactId>crac</artifactId>
<version>1.4.0</version>
</dependency>
2. Create a Dockerfile:
FROM azul/zulu-openjdk:17-jdk-crac-latest as builder
WORKDIR /home/app
ADD . /home/app/spring-petclinic
RUN cd spring-petclinic && ./mvnw -Dmaven.test.skip=true clean package
FROM azul/zulu-openjdk:17-jdk-crac-latest
WORKDIR /home/app
EXPOSE 8080
COPY –from=builder /home/app/spring-petclinic/target/*.jar petclinic.jar
ENTRYPOINT [“java”, “-XX:CRaCCheckpointTo=/test”, “-jar”, “petclinic.jar”]
3. Build the Docker Image:
Creating a Deployment on Azure Kubernetes Service
1. Create an AKS Cluster:
2. Push the Docker Image to Azure Container Registry (ACR):
docker push <acr-name>.azurecr.io/spring-petclinic:crac
3. Create an image pull secret to your ACR
4. Create Azure File to mount to the deployment
az storage share-rm create –resource-group myResourceGroup –storage-account mystorageaccount –name myfileshare
az storage account keys list –resource-group myResourceGroup –account-name mystorageaccount
kubectl create secret generic azure-secret –from-literal=azurestorageaccountname=mystorageaccount –from-literal=azurestorageaccountkey=<storage-account-key>
5. Create a Kubernetes Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
– name: myapp
image: <acr-name>.azurecr.io/spring-petclinic:crac
ports:
– containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: # The two capabilities are required to to checkpoint
– SYS_PTRACE
– CHECKPOINT_RESTORE
privileged: false
volumeMounts:
– name: crac-storage
mountPath: /test
volumes:
– name: crac-storage
csi:
driver: file.csi.azure.com
volumeAttributes:
secretName: azure-secret
shareName: myfileshare
mountOptions: ‘dir_mode=0777,file_mode=0777,cache=strict,actimeo=30,nosharesock,nobrl’
imagePullSecrets:
– name: regcred
6. Deploy to AKS:
7. Check start up logs and duration:
| _,,,–,,_
/,`.-‘`’ ._ -;;,_
_______ __|,4- ) )_ .;.(__`’-‘__ ___ __ _ ___ _______
| | ‘—”(_/._)-‘(__) | | | | | | | | |
| _ | ___|_ _| | | | | |_| | | | __ _ _
| |_| | |___ | | | | | | | | | |
| ___| ___| | | | _| |___| | _ | | _|
| | | |___ | | | |_| | | | | | | |_ ) ) ) )
|___| |_______| |___| |_______|_______|___|_| |__|___|_______| / / / /
==================================================================/_/_/_/
:: Built with Spring Boot :: 3.3.0
2024-09-26T14:59:41.464Z INFO 129 — [ main] o.s.s.petclinic.PetClinicApplication : Starting PetClinicApplication v3.3.0-SNAPSHOT using Java 17.0.12 with PID 129 (/home/app/petclinic.jar started by root in /home/app)
2024-09-26T14:59:41.470Z INFO 129 — [ main] o.s.s.petclinic.PetClinicApplication : No active profile set, falling back to 1 default profile: “default”
2024-09-26T14:59:42.994Z INFO 129 — [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-09-26T14:59:43.071Z INFO 129 — [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 66 ms. Found 2 JPA repository interfaces.
2024-09-26T14:59:44.125Z INFO 129 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-09-26T14:59:44.134Z INFO 129 — [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-09-26T14:59:44.135Z INFO 129 — [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.24]
2024-09-26T14:59:44.176Z INFO 129 — [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-09-26T14:59:44.178Z INFO 129 — [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2595 ms
2024-09-26T14:59:44.560Z INFO 129 — [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Starting…
2024-09-26T14:59:44.779Z INFO 129 — [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 – Added connection conn0: url=jdbc:h2:mem:131e3017-7e28-4a31-b704-5d3840cd46d6 user=SA
2024-09-26T14:59:44.781Z INFO 129 — [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Start completed.
2024-09-26T14:59:45.011Z INFO 129 — [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2024-09-26T14:59:45.073Z INFO 129 — [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.5.2.Final
2024-09-26T14:59:45.113Z INFO 129 — [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2024-09-26T14:59:45.451Z INFO 129 — [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2024-09-26T14:59:46.466Z INFO 129 — [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set ‘hibernate.transaction.jta.platform’ to enable JTA platform integration)
2024-09-26T14:59:46.468Z INFO 129 — [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit ‘default’
2024-09-26T14:59:46.826Z INFO 129 — [ main] o.s.d.j.r.query.QueryEnhancerFactory : Hibernate is in classpath; If applicable, HQL parser will be used.
2024-09-26T14:59:48.666Z INFO 129 — [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoints beneath base path ‘/actuator’
2024-09-26T14:59:48.778Z INFO 129 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ‘/’
2024-09-26T14:59:48.810Z INFO 129 — [ main] o.s.s.petclinic.PetClinicApplication : Started PetClinicApplication in 8.171 seconds (process running for 8.862)
Creating a Checkpoint with CRaC
1. Create the Checkpoint:
Restoring from the Checkpoint
1. Update deployment to restore Image in AKS:
– command:
– java
– -XX:CRaCRestoreFrom=/test
kubectl apply -f deployment.yaml
2. Check startup time
2024-09-26T15:01:42.400Z INFO 129 — [Attach Listener] o.s.c.support.DefaultLifecycleProcessor : Restarting Spring-managed lifecycle beans after JVM restore
2024-09-26T15:01:42.396Z WARN 129 — [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 – Thread starvation or clock leap detected (housekeeper delta=4m9s910ms846?s988ns).
2024-09-26T15:01:42.473Z INFO 129 — [Attach Listener] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ‘/’
2024-09-26T15:01:42.474Z INFO 129 — [Attach Listener] o.s.c.support.DefaultLifecycleProcessor : Spring-managed lifecycle restart completed (restored JVM running for 1009 ms)
Performance Comparison
1. Measure Startup Time:
2. Compare Results:
Conclusion
Microsoft Tech Community – Latest Blogs –Read More