This is an old revision of the document!
https://spring.io/guides/gs/spring-boot-kubernetes
To build the jar use:
$ ./gradlew bootJar --args='--server.port=8888' Starting a Gradle Daemon, 1 busy and 1 stopped Daemons could not be reused, use --status for details BUILD SUCCESSFUL in 11s 4 actionable tasks: 1 executed, 3 up-to-date
To run
$ java -jar build/libs/demo-0.0.1-SNAPSHOT.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.2.3) 2024-03-04T22:46:38.269+01:00 INFO 47724 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 17.0.4 with PID 47724 (/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot/build/libs/demo-0.0.1-SNAPSHOT.jar started by skip in /mnt/d/1PROJEKTE/Kubernete-tutorials-springboot) 2024-03-04T22:46:38.282+01:00 INFO 47724 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default" ^X^C2024-03-04T22:46:40.721+01:00 INFO 47724 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator' 2024-03-04T22:46:41.296+01:00 INFO 47724 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 8080 2024-03-04T22:46:41.311+01:00 INFO 47724 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 4.003 seconds (process running for 4.858)
Building the image:
$ ./gradlew bootBuildImage [creator] Adding label 'io.buildpacks.project.metadata' [creator] Adding label 'org.opencontainers.image.title' [creator] Adding label 'org.opencontainers.image.version' [creator] Adding label 'org.springframework.boot.version' [creator] Setting default process type 'web' [creator] Saving docker.io/library/demo:0.0.1-SNAPSHOT... [creator] *** Images (b57e814aa8fb): [creator] docker.io/library/demo:0.0.1-SNAPSHOT [creator] Adding cache layer 'paketo-buildpacks/syft:syft' [creator] Adding cache layer 'buildpacksio/lifecycle:cache.sbom' Successfully built image 'docker.io/library/demo:0.0.1-SNAPSHOT' BUILD SUCCESSFUL in 1m 6s 5 actionable tasks: 1 executed, 4 up-to-date skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE paketobuildpacks/run-jammy-base latest ddb21b4d22de 6 days ago 111MB gcr.io/k8s-minikube/kicbase v0.0.42 dbc648475405 3 months ago 1.2GB gcr.io/k8s-minikube/kicbase v0.0.30 1312ccd2422d 2 years ago 1.14GB demo 0.0.1-SNAPSHOT b57e814aa8fb 44 years ago 307MB paketobuildpacks/builder-jammy-base latest d00577c76e33 44 years ago 1.46GB
Running
docker run -p 8080:8080 demo:0.0.1-SNAPSHOT Setting Active Processor Count to 20 Calculating JVM memory based on 30175084K available memory For more information on this calculation, see https://paketo.io/docs/reference/java-reference/#memory-calculator Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx29783343K -XX:MaxMetaspaceSize=84540K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 30175084K, Thread Count: 50, Loaded Class Count: 12512, Headroom: 0%) Enabling Java Native Memory Tracking Adding 137 container CA certificates to JVM truststore Spring Cloud Bindings Enabled Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -XX:+ExitOnOutOfMemoryError -XX:ActiveProcessorCount=20 -XX:MaxDirectMemorySize=10M -Xmx29783343K -XX:MaxMetaspaceSize=84540K -XX:ReservedCodeCacheSize=240M -Xss1M -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -Dorg.springframework.cloud.bindings.boot.enable=true . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.2.3)
Generate deployment config
kubectl create deployment demo --image=springguides/demo --dry-run -o=yaml > deployment.yaml echo --- >> deployment.yaml kubectl create service clusterip demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml
Manifests are YAML files containing multiple resources separated by the “—” separator.
- Service in Kubernetes: A service acts as an abstraction layer for a set of Pods, providing a network identity for them. This allows other applications within the cluster to discover and connect to these Pods using the service's name and port instead of individual Pod IPs.
- ClusterIP Service Type: When you use clusterip, you're creating a service that has a virtual IP address assigned within the cluster. This IP address is only accessible from within the cluster and cannot be directly accessed from the outside world.
- Benefits: ClusterIP services are useful for applications that only need to communicate with other services or Pods within the cluster.
skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ kubectl get all NAME READY STATUS RESTARTS AGE pod/demo-86795d784d-2bc82 0/1 ImagePullBackOff 0 91m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demo ClusterIP 10.101.245.55 <none> 8080/TCP 91m service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/demo 0/1 1 0 91m NAME DESIRED CURRENT READY AGE replicaset.apps/demo-86795d784d 1 1 0 91m
Now you need to be able to connect to the application, which you have exposed as a Service in Kubernetes. One way to do that, which works great at development time, is to create an SSH tunnel:
kubectl port-forward svc/demo 8080:8080
Kubernetes usually uses REMOTE images from repo. To fix:
Step1:
Artificially add the image to the minikube cache.
Achtung: work around bug https://github.com/kubernetes/minikube/issues/18021
skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ docker image save -o image.tar springguides/demo:latest skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ minikube image load image.tar
Step2:
Use eval $(minikube docker-env)
to switch to container cache within minikube.
After taht docker images
will show you minikube containers.
skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ eval $(minikube docker-env) skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker latest e5fbe8997fd9 11 days ago 348MB k8s.gcr.io/kube-apiserver v1.23.3 f40be0088a83 2 years ago 135MB k8s.gcr.io/kube-controller-manager v1.23.3 b07520cd7ab7 2 years ago 125MB k8s.gcr.io/kube-scheduler v1.23.3 99a3486be4f2 2 years ago 53.5MB k8s.gcr.io/kube-proxy v1.23.3 9b7cc9982109 2 years ago 112MB k8s.gcr.io/etcd 3.5.1-0 25f8c7f3da61 2 years ago 293MB k8s.gcr.io/coredns/coredns v1.8.6 a4ca41631cc7 2 years ago 46.8MB k8s.gcr.io/pause 3.6 6270bb605e12 2 years ago 683kB kubernetesui/dashboard v2.3.1 e1482a24335a 2 years ago 220MB kubernetesui/metrics-scraper v1.0.7 7801cfc6d5c0 2 years ago 34.4MB gcr.io/k8s-minikube/storage-provisioner v5 6e38f40d628d 2 years ago 31.5MB springguides/demo latest b57e814aa8fb 44 years ago 307MB
Now finally you can run a container with image 'image: springguides/demo'
skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ kubectl apply -f deployment.yaml deployment.apps/demo created service/demo created skip@desktop:/mnt/d/1PROJEKTE/Kubernete-tutorials-springboot$ kubectl get all NAME READY STATUS RESTARTS AGE pod/demo-6f64658b59-swj5z 1/1 Running 0 3s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demo ClusterIP 10.97.44.9 <none> 8080/TCP 3s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/demo 1/1 1 1 3s NAME DESIRED CURRENT READY AGE replicaset.apps/demo-6f64658b59 1 1 1 3s