Sadly enough it's all YAML, but at least it's all YAML and not random mostly undocumented arcane configuration formats...
Those were simpler days for sure.
1) Set up multiple fileservers w/ DRDB or some sort of clustered filesystem like glusterfs 2) Set up multiple database servers in a cluster 3) Set up multiple web servers, all of which can connect to the NAS and DB 4) Optionally set up a cache layer like Varnish 5) Set up a hardware load balancer (or even varnish/nginx/haproxy)
Autoscaling on bare metal wasn't really a thing for most DCs, but setting up HA environments has been possible for a long time. Things were actually a lot less complicated because there weren't as many options imo. You'd generally overprovision to handle your peak loads, or maybe buy a few more servers before busy seasons/days and cancel them later.
Managing a bare metal kubernetes installation feels like it has a lot more moving pieces and ways that it can break. Cloud providers and managed services do take away a lot of the burden though.
Newer companies just push this onto their application developers, expecting them to figure this stuff out on top of being developers, "full-stack" now meaning you need to understand everything down to filesystems, overlay networks, container runtimes. This is not a reasonable expectation. Nobody can be an expert in everything.
Of course, I'm not sure full automation can really replace human expertise, either.
You don't really need a resident storage expert in every company, since most companies have similar needs.
There are basically entire industries dedicated to stopping programming languages from doing bad things (static analysis vendors, auditing consultancies, formal verification tool vendors, etc.) and to stopping OSes from doing bad things (application-focused monitoring tools, security-focused intrusion detection tools, policy enforcement / device management vendors, etc.), and we don't really say "Wow, something is wrong with C++" or "Wow, something is wrong with Linux." We understand that they are high-power tools and you do want additional tools to focus that power.
(Well, to be fair, I say something is wrong with C++, but my preferred solution to that is even more complicated programming languages :) )
I can't give a coherent and detailed analysis of it yet[1] - but I have this growing feeling that we're drowning in accidental complexity all across the board, at every abstraction layer. Like an inverse iceberg - where we see this whole, humongous mountain of tooling required to build and maintain software systems, but you can't shake the impression that we should be able to do the job with just the bit that's sticking above the waterline.
Speaking of k8s being "of the level of complexity of a programming language or an OS", I bet there's some formal way to show some isomorphism here - them being different incarnations of the same abstract structure. It's another kind of feeling I get when jumping up and down the software stack[2]. Maybe one day we'll figure it all out.
--
[0] - https://news.ycombinator.com/item?id=28568053
[1] - But I am collecting observations and trying to mull the problem over in my subconscious mind.
[2] - Like e.g. code is data is code; your config parser is an interpreter of a programming language. Often enough, it grows to look like a typical PL, then gets replaced by one[3]. If your config happens to describe infrastructure, at some point you might realize you're writing "function calls" for business logic that are implemented in terms of spinning clusters up and down. Or e.g. the realization that DCOM is essentially microservices, so for some two decades or more, every Windows installation had something similar to k8s deep inside its bowels.
[3] - https://mikehadlow.blogspot.com/2012/05/configuration-comple...
K8s basically implements a distributed OS that schedules across machines instead of CPU cores
Not-too-long-ago AWS had a significant outage due to misconfigured ulimits (Linux os)