A pod restarts every few minutes and the logs end normally.
Look at the previous container, not the current one: kubectl logs pod --previous. A clean ending plus a restart usually means OOMKilled, which shows in kubectl describe pod under Last State. Memory limits are the first thing to check, requests the second.
Should requests equal limits?
For memory, yes: memory is incompressible, so a limit above the request means the pod gets killed rather than throttled. For CPU, set requests and leave limits off unless you need hard isolation, because CPU limits throttle in ways that look like random latency.
Deploys cause a handful of 502s every time.
The old pod stops accepting before the proxy stops sending. Add a readiness probe and a preStop sleep of a few seconds:
lifecycle:
preStop:
exec:
command: ["sleep", "5"]
That gap gives the endpoint controller time to remove the pod before the process exits.