Both starters spun magnificent outings in advance of their regular season debuts, as Edinson Volquez survived five hits spread over four innings by striking out seven to wiggle out of a couple early jams.
"He executed all his pitches, so I was really pleased," manager Ned Yost said. "Had his fastball 94 to 96 [mph] and kept the change and curveball down in the zone all game, so he's ready to go."
Astros righty Scott Feldman nearly matched him, but he couldn't survive the fifth unscathed when an error and Lorenzo Cain's RBI single sandwiched around a run-scoring double play gave the Royals a 2-0 lead.
The lead ballooned late, as Kansas City rocked Houston bullpen addition Pat Neshek for three runs.
Eric Hosmer laced his fourth homer of the spring -- a two-run job -- and Brett Eibner followed with a monster shot to left-center field. Mike Moustakas started the eighth-inning rally with a shift-beating bunt and he scored three runs while going 3-for-4, including an RBI double.
"He's been working on [his swing] all spring and it's getting more and more natural," Yost said. "Three hits, all the opposite way -- that's pretty impressive."
Omar Infante's two-run double highlighted a six-run ninth inning to blow the game wide open, while Evan Gattis, who was 2-for-4, homered off Greg Holland in the bottom half for the Astros.
Up next: Veteran left-hander Jason Vargas will make his final preseason start when the Royals and Astros meet at 3:05 p.m. CT on Saturday. Watch all of the action with a free MLB.TV exclusive webcast.
Chris Abshire is a contributor to MLB.com. This story was not subject to the approval of Major League Baseball or its clubs.