There are ways to switch glibc other than "rewrite every binary" and "full-on containers".
In particular, if you need to replace not just glibc, but also a bunch of system libraries (pretty common case for complex apps), it's often easier to unshare(CLONE_NEWNS), followed by bind-mounting over new /lib64 and /usr/lib to override specific directories. This is much lighter than full-on containers, and allows overriding any specific directories - for example if your app looks at /usr/share/appname, you can override it too.
This method has a bunch of upsides: you can use binaries unmodified, subprocesses work, and hard-coded data locations can be taken care of as well.
> In particular, if you need to replace not just glibc, but also a bunch of system libraries (pretty common case for complex apps), it's often easier to unshare(CLONE_NEWNS), followed by bind-mounting over new /lib64 and /usr/lib to override specific directories. This is much lighter than full-on containers
Doesn't that mean you need all the app's library dependencies installed into your alternate libdirs that you bind mount over top the "real" libdirs? Not just the ones you want to override?
I feel like for this, LD_LIBRARY_PATH is usually sufficient. Just seems like glibc is the special case.
> Doesn't that mean you need all the app's library dependencies installed into your alternate libdirs that you bind mount over top the "real" libdirs? Not just the ones you want to override?
You can also create a temp directory with symlinks as a poor mans overlay fs. You bind mount the original dir in an out of the way location so you can link to it and bind the temp dir over the standard location.
I believe thats what Nix's bubblewrap based FHSenv was doing last I checked.
In particular, if you need to replace not just glibc, but also a bunch of system libraries (pretty common case for complex apps), it's often easier to unshare(CLONE_NEWNS), followed by bind-mounting over new /lib64 and /usr/lib to override specific directories. This is much lighter than full-on containers, and allows overriding any specific directories - for example if your app looks at /usr/share/appname, you can override it too.
This method has a bunch of upsides: you can use binaries unmodified, subprocesses work, and hard-coded data locations can be taken care of as well.