Closed salaboy closed 2 years ago
@philwebb I love the tag for: team-meeting
, let me know how that goes I would love to hear feedback about this. Or pointers to alternatives
Thanks for the suggestion, @salaboy. We've discussed this today and agreed that this level of integration with K8S is out of scope for Spring Boot. We feel that it's better handled as part of a software supply chain built with something like Cartographer.
@wilkinsona while I understand that a decision was made on this issue, it will be great to document the reasons here instead of just pointing to Cartographer which is a specific tool to do way more than what was described here.
IMHO, there is still a gap in the developer experience for spring boot users, that can be fixed by following an approach similar to the one provided by google/ko
.
If we are going to delegate tasks like applying the descriptors to a Kubernetes cluster, we should also avoid building container images (using buildpacks that I love) with the spring-boot:build-image
goal, as this can also be done by Cartographer and it will be going against that approach as well.
Can you please share the reasons for not building such integration? Is it too much work? Is the outcome or benefits not clear enough? Is a developer not supposed to deploy their containers to Kubernetes for development purposes? I am just trying to understand the Spring Boot team logic behind the decision.
Our build pack support is intended as an on-ramp to tools like pack
, kpack
and the like and we believe it fulfils that purpose in its current form.
As I said above, we do not want to build further integration in Spring Boot itself as we believe it to be out of scope. The benefits are clear but it's not our place to provide them.
The Spring Boot Maven plugin is great and using buildpacks for
mvn spring-boot:build-image
is a great feature, but I would love to see deeper integration with Kubernetes development lifecycles.I was looking at JKube (I don't like that it uses fabric8 libraries to create the YAML resources)
Which generates manifests and can be used in conjunction with
mvn spring-boot:build-image
but still, the integration is not as good asgoogle/ko
which is almost 5 years old.What I will be looking for in a Maven Spring Boot Kubernetes plugin will be to do something like this:
Build, as it is today, but instead of using the Artifact Version, it should use a SHA for tagging the container image, hence consecutive builds will generate a new SHA that can be used to run the container that we just build. I would also include a push to registry function in the build image, as the image locally, in the context of Kubernetes doesn't make much sense. In
google/ko
this is done by just setting an env variable (export SB_DOCKER_REPO=salaboy) and it will use the docker credentials to push.This command should output in some way the SHA that was just created so it can be piped to another command.. for example:
Now on the Kubernetes side, because we are creating containers that are tagged with their SHA we can scan Kubernetes manifests and replace where the image that we are building is referenced.
For example, if we have a deployment that looks like this (inside a directory
config/
omanifests/
): deployment.yaml:We can use an expression that we can replace for the container that we are building:
Where
sb://org.salaboy:my-service
makes reference to the artifact that we are building and can be replaced by the container image that we just created which probably will look like:salaboy/my-service-7ddfb3e035b42cd70649cc33393fe32c@sha256:d4f1d0bfa27f13ab7d80969d18eef1883a8bf23591f92c3ca42f91ad761048e1
Running a command
mvn spring-boot:k8s-resolve -f config/
should do this replacement in all files inside the directory specified and give you the YAML files to apply to the cluster. Doing this replacement and outputting back YAML files is good for CI scenarios, but we can go a step further and apply this to the cluster by running a command like this:This command should aggregate all the steps described before: Build Container, Push Container, Replace reference in YAML files and
kubectl apply -f
to the cluster. Because every time we make a change the container image SHA will be different, every time that we run this command should trigger a deployment update to the latest container image that was just pushed.In contrast with JKube, I wouldn't focus too much on generating manifests but more on the lifecycle of the containers that are built and how new changes are applied to a remote or local cluster.
I am happy to provide more info or details if needed. Apologies for the long issue.