- Install software onto your machines
Package managers, thousands of them.
- Start services
SysVinit, and if shell is too complicated for you, you can write totally not-complicated unit files for SystemD. For most services, they already exist.
- Configure your virtual machines to listen on specific ports
Chef, Puppet, Ansible, other configuration tools, literally hundreds of them etc.
- have a load balancer directing traffic to and watching the health of those ports
Any commercial load balancer.
- a system to re-start processes when they exit
Any good init system will do this.
- something to take the logs of your systems and ship them to a centralized place so you can analyze them.
Syslog has had this functionality for decades.
- A place to store secrets and provide those secrets to your services.
A problem that is unique to kubernetes and serverless. Remember the days of assuming that your box was secure without having to do 10123 layers of abstraction?
- A system to replace outdated services with newer versions ( for either security updates, or feature updates ).
Package managers.
- A system to direct traffic to allow your services to communicate with one another. ( Service discovery )
This is called an internal load balancer.
- A way to add additional instances to a running service and tell the load balancer about them
Most load balancers have built up processes for these.
- A way to remove instances when they are no longer needed due to decreased load.
maybe the only thing you may need to activelly configure, again in your load balancer.
None of this really needs to be written itself, and these assumptions come from a very specific type of application architecture, which, no matter how much people try to make it, is not a one-size-fits-all solution.