Whalecome, dear reader, to the first issue of Dear Moby — my new advice column where I, Moby Dock, will be answering real developer questions from you, the Docker community. Ever hear of the Dear Abby column? Well, this one is better, because it’s just for developers.
Since we announced this column (and its video counterpart with my friends, Kat and Shy), we’ve received a tidal wave of questions. (You can submit your own questions here!)
Despite my whaleth of knowledge and passion for all things app development, I’m only one whale — and I don’t have all the answers! Many, but not all. So, I’ve commissioned a crew of fellow Docker experts to voyage alongside me in pursuit of the answers you seek.
So without further ado, let’s dive into the fray…
Our first question comes from shaileshb who asks:
“Hey! I’m creating a CronJob for my Kubernetes cluster. Currently, I am confused as to whether I should put database connection strings and the main logic inside the CronJob itself, or whether those should exist in an API that the CronJob calls.”
Today’s commissioned experts: Director of Engineering Shawn Axsom and Principal Software Engineer Josh Newman
The best approach depends on your specific circumstances, but there are important considerations around performance and security you have to take into account with every deployment to a cluster you create.
Whether you use an additional API or not, you should secure connection strings and other secrets.
You want to keep it secret and keep it safe, so try these best practices:
- Don’t put connection strings in environmental variables that someone could access while breaching the container or inspecting container or pod metadata.
- Set identity access management policies based on the Principle of Least Privilege. (More about PoLP here.)
- Consolidate database access to a single service or limited subset.
- Consider a secrets manager, regardless of what deployment approach you take. (Take a deep dive into Kubernetes secret storage with this post from Conjur!)
Next, when it comes to performance, it really depends on your circumstance. Either approach can give you good performance, but your choice needs to take into account things like how often the CronJob runs, whether it runs in parallel, whether caching is involved, etc. And if designing for scale, you’ll want to consider connection limits and connection pooling.
When going the CronJob route, we suggest considering an external connection pool — but be sure it’s set up properly to avoid exhausting it. This might be an advantage of the API route. Depending on your tech stack and usage, you can get better connection pooling within the API service. If you want to brush up on your connection pooling considerations, check out this Stack Overflow article.
In the long run, simplicity is a virtue and will always reign supreme.
An understandable, secure, and scalable system is a one with a cohesive design that isn’t over-engineered. It’s often best to start small (and also consider existing services that may benefit from the functionality) and keep the code contained in one location where secrets are stored securely — especially if there aren’t performance or scalability concerns (or a need to reuse it). And if these concerns do rear their ugly heads, that simplicity makes it easier to refactor. Truth be told, after observing the code in production (or getting feedback), you might even opt for a different approach, so the simpler you start, the easier you make things for yourself later.
Above all else, it’s always good to design for resiliency and extensibility. If best practices aren’t put in place from the start, make sure to design the CronJob or API in a modular and composable way so these practices can be put into practice later without a rewrite.
Well, that does it for our first issue of Dear Moby! Many thanks to Josh and Shawn.
Have another question for me and the Docker dev team to tackle? Submit it here!
Until next time,
0 thoughts on "Dear Moby: CronJobs and Kubernetes and Ocean Puns, Oh My!"