For many simple applications, an aws autoscaling group and application load balancer is as good as k8s and far simpler.
If you're running microservices (to the point where you have so many small services that having an asg per service), than the above strategy does waste resources compared to k8s I guess... But you'd need a lot of microservices to justify the significant overhead k8s has.
But now you have to manage those VM's, the OS lifecycle, different distributions, application deployment, configuration and dependencies. And we're back at containers. Or you have to go towards lambda.
For K8s you need to manage the vm's/os as well but that part is mostly trivial as it's highly focussed on immutable/disposable infrastructure.
If you're running microservices (to the point where you have so many small services that having an asg per service), than the above strategy does waste resources compared to k8s I guess... But you'd need a lot of microservices to justify the significant overhead k8s has.