What you're dealing with is an effect called Mach Bands. They come from our visual system highlighting the perceived contrast where two different greys meet, or where a gradient changes direction:
The linear interpolation used by the gradient node makes a sharp corner at each colour key, and our visual system highlights that first derivative discontinuity as a bright or dark line - even though it's not actually that much brighter or darker than the pixels next to it.
So, we need to smooth-out this corner so our brains' local contrast detection sees it as a gradual rounded shape instead of a sharp corner to highlight.
Here are a few different ways you can solve it:
Top Row: More Keys
You've already started down this road. You just need more. In this example my keys go...
- 0%: 0
- 40%: 230
- 45%: 252
- 50%: 255
- 55%: 252
- 60%: 230
- 100%: 0
You can see how this rounds-out the peak to minimize the perceived corner:
For the next two solutions, I use some math to put the curving bend into the input parameter, rather than into the gradient. So we can switch to a simple one-sided linear gradient - we'll mirror it in our input math.
Middle Row: SmoothStep
Here I take our 0...1 gradient parameter and subtract 0.5, so it goes -0.5...0...0.5
Taking the absolute value of this gives us a V shape, 0.5...0...0.5
Then we run this through a node called "SmoothStep" - this takes an input parameter and remaps it using a min/max range, so that values at/below the min map to 0, values at/above the max map to 1, and smoothes the values in-between.
It's a kind of "ease-in-out" function, that slows the rate of change of the input as it reaches the extremes, so it comes to a gradual stop at the min/max instead of slamming into them at full speed.
You can see as a consequence, this also increases the amount of dark fringes you get at the left and right sides of the gradient, as we spend a bit more time slowly easing into the dark extreme.
Bottom Row: Quadratic
Like before, we'll subtract 0.5 to get into the range -0.5...0...0.5
But instead of taking the absolute value to mirror the input at zero, we could instead multiply our parameter by itself, squaring it to get a positive number.
Unlike the absolute value function that makes a sharp corner at zero, this gives us a parabola that's smooth and flat at its vertex. We just need to multiply it by 2 first (or 4 afterward), to keep the output in the 0...1 range we want.
This both mirrors the gradient AND smoothes the corner in one step, but it has the opposite problem as SmoothStep: it spends most of its time in the bright values in the middle of our gradient, and just barely touches dark greys as it rushes to black at the edges.
You can of course adjust for both these artifacts by nudging your gradient keys around.
Or, if you're just using this for a white-to-black shading, you can skip the gradient sampling entirely and just subtract from 1 to get your output, with pure math. I show that for each of solutions 2 and 3 in the rightmost column. Note that this doesn't apply the gamma adjustment used by the gradient sampling, so you get a different pattern of light and dark this way, but you can tweak your coefficients to bring this to the shape you want.
Here's a summary of the curves for each of these solutions (plus a bonus "hybrid" that's just averaging the SmoothStep and Quadratic outputs)