I would argue that if you have services then the right place to put encryption and authentication is at the service level. Building secure channels between IP addresses is all good, but do you really want to map roles/identities/privileges to specific IP addresses if those roles/identities/privileges really represent services?
What if you end up spinning more than one container for that service?
How are these containers getting the different secrets they need to identify themselves? Are you attaching IAM roles to them to get secrets from some secret store?
Said it twice before: differently complex. There are plenty of potential “solutions” to the specific scenario you’re describing, but my original comment was more “generally consider X instead of Y so you don’t have to care about Z” rather than “use X in this specific way and it will simply solve every problem with Y”.
Well, there are encrypted CNIs like Weave. I've used Calico over ZeroTier to similar effect. The network is 'encrypted' and there isn't much effort required past initial configuration.
But that's not really the issue. You still have a big plaintext network with a bunch of random stuff talking, no mutual auth and no security controls other than segmentation. That's the tricky problem that mTLS and service meshes attempt to solve.
First, I’ll respond this w.r.t. k8s CNI specifically: all inter-node traffic is encrypted, the only plaintext is localhost. If you’re worried about network snooping on localhost you’ve got bigger problems. As for security controls, that’s what Network Policies are for.
Outside of k8s (where one has greater control over how specifically e.g. Wireguard is deployed). Again, there is no plaintext outside of localhost. Wireguard is mutual auth, I’m not sure why you think it isn’t. Wireguard + firewall is security control since, well, you have mutual auth so rules can be applied per-client.