In terms of being fault-tolerant I think the modern approach with (micro)services is quite similar, one can have multiple services running and communicating using something like protobuf, having restart strategies, fallbacks and so on. From my experience Erlang doesn't offer any killer features in this case, does it?
This means that the processes can be much, much more lightweight than kubernetes pods and containers. Cheaper to kill and restart. Can provide concurrency and fault tolerance at a far more granular level. Much simpler to write and deploy than Docker images. Etc. etc.
At least that's my understanding (significant work experience with kubernetes, no real production experience with Erlang/Elixir).
Restarting your docker image every time someone sends a malformed packet to your webserver is going to make for a trivial not even D-DOS attack. Killing the individual process that spins up to handle that particular packet/connection, though, is simply best practice.
Kubernetes is just better than Erlang for process managment because it does more and is completely language agnostic, imagine you can't build some part of your system in Erlang but you need the same kind of functionality what do you do?
In my experience in non-Erlang setups while doing requests to other services you have to check the response status and add some code handling it, so it's not really a complete afterthought. The only difference I see here is that Erlang handles failure in a real-time way, but it also can be done using some periodic task to query important services. And implementing in outside of Erlang gives more flexibility (think of Erlang cluster size and network limitations)
- It wasn't designed to crash on failure. It uses thread pools with no supervision trees. We had to add in liveliness probes to check if it is alive. I've only had to use readiness checks for Elixir
- No REPL. With a REPL in production, we can debug things live, even try patches to see if those work. Can't do that with Dotnet. That's also something that contributes to reliability
Now, cluster size do matter. The way Erlang and BEAM was designed were for vertical scaling. You can minimize cluster size by biasing towards vertical scaling. That's what we do on our systems. There's a way to do that with Kubernetes so that we scale vertically during our daily traffic cycle.
At some point though, you start looking at partial clustering topology for BEAM, or use one of the many process registeries that are better suited for dynamic membership. (The one bitwalker wrote comes to mind).
Yes the killer feature in this case (relative to microservices) is a sane deployment, single codebase, unified language, being able to do integration tests without a full DevOps team, etc.