Instead of passing a `run_func` argument, which is clumsy, we create a BaseRunner from which local and k8s runners can inherit.
Configuration loading was overly complex. Here, we simplify it drastically with reasonable defaults. Hacky additional variables are unncessary now that we use custom jinja2 filters.