With captain Sergio Ramos unavailable, Real welcomed back Karim Benzema and handed a start to Ferland Mendy and Rodrygo.
Madrid sprung the early chance four minutes in when Marco Asensio struck the inside post from close-range following a cross-field pass from the left-side by Benzema.
Junior Moraes became a casualty for the hosts' right at the midway mark after a collision with Raphael Varane left the Brazilian limping uncomfortably before making way for Dentinho.
Asensio caused more problems for the hosts on the half-hour mark when a shot from the near side led Anatoliy Trubin to a one-hand palm before Martin Odegaard left a defensive error unpunished.
Madrid went close again five minutes into the second half when a low shot from the edge of the area from Benzema forced Trubin to go down and parry.
Another chance went the Champions League record holders' way seconds later, as Nacho headed a floating ball from the right over before Taison brought Thibaut Courtois to work at the other end.
Los Blancos were punished on 57 minutes when substitute Dentinho latched onto a loose ball in the area to bundle in the top corner with the visitors caught in disarray at the back.
Shakhtar pushed a second goal towards the remaining quarter of the match, but Madrid replied with strong resistance and eagerness to complete a turnaround.
As Los Blancos pushed for the equaliser eight minutes from time, Shakhtar grabbed a second after Manor Solomon carved the slightest of angles from the near side to pick the bottom-corner.
Madrid didn't throw in the towel towards full-time and pushed for a late turnaround, which failed to arrive as Shakhtar secured victory to go second in Group B.