Hi Chris,

Am 07.07.2022 um 00:59 schrieb Christopher Schultz:
Stefan,

On 7/6/22 18:50, Stefan Mayr wrote:
Am 05.07.2022 um 23:36 schrieb Pawel Veselov:
Christopher, Stephan,

On Tue, Jul 5, 2022 at 11:18 PM Christopher Schultz
<ch...@christopherschultz.net> wrote:

Stefan,

On 7/2/22 09:45, Stefan Mayr wrote:
Hi,

Am 01.07.2022 um 17:10 schrieb Christopher Schultz:
Thomas,

On 6/30/22 13:52, Thomas Meyer wrote:
Sadly currently Tomcat startup relies on shell script to bootstrap
JVM process.

In the light of distroless images (e.g.
https://blog.chainguard.dev/introducing-apko-bringing-distroless-nirvana-to-alpine-linux/)


What are you thoughts on packaging tomcat in distroless base OCI
images that doesn't even contain any shell anymore?

Would it be possible to provide an alternative start mechanism which
directly starts JVM process which setup/prepare env like the current
catalina.sh shell script does?

What are your thoughts on above topic?

Speaking for myself, here, of course.

The Tomcat team doesn't package anything other than the "standard
distributions" such as the source and the pre-built Java binaries, plus
the Windows binaries for various things. We don't package anything
specific like Docker base containers, etc. and I don't think we want to
get into that business.

If someone in the community wants to do something like that: go for it.
But we have enough to do already and don't want to play favorites.

The only reason catalina.sh exists is to figure out what's going on with the hosting environment. If you want to build a launch-process that is
integrated into a specific environment, then you don't need all that
tooling to figure out what is what: you can just write one big command
line and launch the JVM with all the necessary arguments.

I agree with that. In my opinion this part of environment detection is
not necessary in a container because a container is immutable. So it
should be enough to run Tomcat the way you want to have it and copy &
paste the java command line into our container image generation manifest
(e.g. Dockerfile).

To use Tomcat in a more container friendly way you should consider also
some other things too:
- because containers are static there is no need to explode WAR files or scan the directory for changes. The extracted application can be copied
into the image and server.xml can be tuned to disable those features.
- you should avoid logging into files and tune the logging configuration
to log everything to stdout and stderr

Logging to stdout and stderr is a sure way to get oneself into a
serious bottleneck.

Maybe, but this is the convention most have agreed on for stateless (container) applications. It is factor #11 of the 12 factor app principles (https://12factor.net/logs). As always, your choices depend on the infrastructure you have. Runnning on a single docker host with an image customized for your needs? Then you can always mount the local filesystem into your container to write your logs on. Is this an image you deliver to your customers or that will run in kubernetes? So don't log into files and stick to the defaults: log to stdout and stderr

This is something that I really don't understand about containerized
applications running like this. Maybe I'm too old-skool and think that
application logs go into application-log files and access-logs go into
access-log files.

Assuming an ideal case, where should all of these things go if your
choices are "stdout" or "stderr"?

1. HTTP Access logs
2. HTTP access logs from multiple virtual hosts (or is the idea that one
container ~= 1 virtual host)
3. Server logs (e.g. DEBUG/INFO/WARN coming from the app server)
4. Application logs (e.g. DEBUG/INFO/WARN coming from the application)
5. Application logs for applications other than the primary (e.g. Tomcat
Manager)

They don't go to files. They get sent to a logging router instead
(e.g., Fluentd), which send them to logging aggregators (e.g.,
Graylog)

And because it is very hard to parse those logs in a sensible way it is becoming increasingly popular for container apps to use a json based log format. This is "ugly" but still somewhat readable for human users and almost all central logging solutions have a built-in json parser. No regex-vodoo to parse multiline output required (e.g. Stacktraces). Switching from raw text to a structed log format also improves the posibilities for your search queries a lot.

Addressing questions 2 and 5: it is best practice to have only one application in your container and remove everything also. So having multiple applications would usually result in multiple different containers. They might share the same (Java+Tomcat) baseimage but include different apps. A container image is an immutable artefact. As such they should have a bit of "hardening" and I would not expect something like the manager app in a container. Changes should result in new images.

We use JMX extensively for our applications, including for monitoring and management. We use the Tomcat Manager JMXProxyServlet for that purpose. It *must* be run in the same JVM as the actual application. Currently, a user-database is deployed with the Manager and localhost-only access is required. Committing the user database to revision control is pretty much a no-go, so I would probably look into k8s or similar as a ham-fisted user-store for that purpose. Or even go full JDBC.

Using the Manager application this way can be a valid reason to include it in the container image. But going the container route requires us to rethink some operational aspects. This will often need some different solutions. Most of the times things will be more complicated than before.
Why are so many people doing this? In my opinion there are three reasons:
1. better portability: no need to care if this runs on Mac/Windows/Linux/OnPrem/the Cloud (simplified, there are some stumbling blocks). You always have the some application runtime: Java, Tomcat, libraries, etc. 2. scalability: if you do your container right it should be easier to scale it from 1 to n instances. But this comes with an additional cost of complexity when you do it for the first time. 3. everyone does it. What was the hipster technology of your time ;-) To become serious again: somehow the industry has agreed on this as a defacto standard. Many vendors don't deliver their classic software artefacts anymore - the provide containers. I think mostly because of reason #1 to reduce support complexity.

Speaking of surprises: you mention localhost-only access. But what is your context of localhost? If you run a container in a regular Docker or kubernetes setup each container gets its own "network". Most times a private RFC1918 IP address and its own loopback interface. Traffic in and out of the container is nat-ted on your containerhost. So localhost on your container host != localhost in your container. Having something localhost-only accessible is only accessible from inside of your container. I guess your monitoring and management tools will have to change. Either the tools itself or the way they are used.

Your user database is the next good example: there should not be any configuration or secrets in a container. This is environment specific and should always be provided from the outside to make this image be usable in all environments. Following the 12 factor principles - environment variables are back (https://12factor.net/config). You need something that does not really work in an enviroment variable? A common technique is to base64 encode it. In kubernetes you also have configmaps and secrets. They can be mounted as files into your container. Back to your database: if it is a small file it might work as a base64 encoded secret. If it is larger or can not be properly encoded you might go the JDBC route and provide only the JDBC credentials (drivername, url, username, password) as environment variables/configmap/secret.

Containers have their uses and advantages. But operational complexity is definitly one of the downsides. In this thread we are just scratching on the surface. There is more work further down the rabbit hole.

Regards,

- Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to