New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a new layer for loader classes #20529
Comments
At the moment, if |
Yeah, you're absolutely right (I misread some documentation). Upon re-examination with the proper layout, I think that they only change to my observation would be that the duplication probably wouldn't matter if the application layer was vastly larger than ~346K most of the time. Do you have any feel for how large the application-contributed classes would be in a typical Spring Boot application. |
Good question. I don't but someone else on the team might. Flagging for team attention so that we can decide if we want to do anything about this. |
I can offer some anecdata. Sagan's I suspect plenty of apps would have more than ~346KB in the application layer. That said, we'd also have plenty of apps where it's almost empty as pretty much everything's either in the It feels intuitive to me for the loader classes to go in the dependencies layer by default. That's where other Boot jars will go and the loader classes will change at the same frequency as those jars. We probably also need to consider some changes to the Maven XML and Gradle DSL to allow users to move the loader classes to a different layer if they wish. |
The dependencies layer feels right to me as well as the loader is tied strongly to the version of Boot, which strongly influences the rate of change of the dependencies layer. Note, the loader is particularly troublesome for Boot's current layering mechanism because it builds layers by moving files and those are immovable. So, if this turns out to be a bear to implement/configure it probably won't be worth it. |
The Maven XML and Gradle DSL determines where something ends up in the layered jar. I'm not sure if we can do anything about the loader classes in that case since they are at the root of the jar rather than nested in |
We going to place everything in |
@wilkinsona How will that work given the classpath implications? |
There shouldn't be any classpath implications. The stuff in |
We talked about this today and concluded that we'd like the index file to contain more information about where the content of each layer can be found. Rather than the hardcoded assumption that the content of a layer named Such an index might look something like this for the currently proposed default layers:
The top-most layer (the bottom layer in the index) does not specify a location for its content. This implies that it contains everything not included in any of the preceding layers. A limitation of this is that it means that it's only the top-most layer that can capture everything not included in any of the other layers but we think that is sufficient for our current purposes. In a customized scenario, the index may look like this:
In this case the loader will be included in the |
@wilkinsona At the risk of it becoming a bit complicated, you might take a look at the slicing definition we have for CNBs. Effectively:
So a pseudo example, (excuse the YAML):
One of the benefits to a more complex design like this is that slicing no longer requires relocation. If boot created a resolved version of this kind of index (e.g. listing every single JAR path rather than using wildcards), iterating over the list would give you enough information to slice in place with a Dockerfile. |
Thanks, @nebhale. We'd like the index file to be in a format that can be easily written and parsed by Java code with no dependencies and parsed by Go code in the buildpack. I'm not sure that TOML meets those requirements. If we can agree upon a format that does while also conveying, useful information, then we should definitely consider it.
We're a bit torn on this one in the Boot team. It came up recently and I initially found the idea very appealing but Phil (IIRC) raised some concerns about the size of the file, particularly for jars with lots of entries. Perhaps we should do some work to quantify that. I suspect it would zip quite efficiently. |
I'm confused. Why would we need those rules in the |
This one is an observation for discussion rather than a requirement for improvement. At this time, Spring Boot's default OCI image layering strategy describes four layers:
dependencies
snapshot-dependencies
resources
application
There is, however, an implicit fifth layer containing (in a typical case):
META-INF/MANIFEST.MF
META-INF/maven/**
BOOT-INF/classpath.idx
BOOT-INF/layers.idx
org/springframework/boot/loader/**
My observation is that this final implicit layer mixes lifecycles. The contents of
META-INF/MANIFEST.MF
,META-INF/maven/**
, andBOOT-INF/classpath.idx
are broadly application-specific and change for every tagged version of an application whileBOOT-INF/layers.idx
andorg/springframework/boot/loader/**
are much more stable, and generally would be duplicate even across applications within an enterprise (given consistent versions of Boot).The concrete result of this is that every single version of an application using this layering would end up with a layer that isn't de-duplicatable but contains (at the current time) 364K of duplicated files and 12K of unique files. I think we can all agree that this isn't the biggest inefficiency in a typical enterprise deployment system, but there is room for a big win both in cumulative storage and cumulative data transfer (i.e. deployment speed) if these files can be de-duped in a registry and cached at edge nodes.
The text was updated successfully, but these errors were encountered: