Using the trick discussed in a similar question here and also here, we can define a helper method to point our local Y axis exactly in a particular direction, while turning our local Z axis to face (as close as possible) toward another direction.
Quaternion TurretLookRotation(Vector3 approximateForward, Vector3 exactUp)
{
Quaternion rotateZToUp = Quaternion.LookRotation(exactUp, -approximateForward);
Quaternion rotateYToZ = Quaternion.Euler(90f, 0f, 0f);
return rotateZToUp * rotateYToZ;
}
Now we can use that in Update to face toward our target:
void Update() {
// Form the direction we want to look towards
Vector3 offsetToTarget = target.position - transform.position;
// Preserve our current up direction
// (or you could calculate this as the direction away from the planet's center)
Vector3 up = transform.up;
// Form a rotation facing the desired direction while keeping our
// local up vector exactly matching the current up direction.
Quaternion desiredOrientation = TurretLookRotation(offsetToTarget, up);
// Move toward that rotation at a controlled, even speed regardless of framerate.
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
desiredOrientation,
maxDegreesPerSecond * Time.deltaTime
);
}