Karns missed all of last year with an elbow injury after having his 2017 season with Kansas City cut short by surgery.
He's the first major league free agent secured by first-year general manager Mike Elias, who hopes Karns can fill out the back end of the rotation.
The 31-year-old Karns can earn an additional $200,000 in performance bonuses for innings: $50,000 each for 25, 50, 75 and 100. He would receive $50,000 for being an All-Star and $25,000 if voted comeback player of the year.
Karns made his debut in 2013 with Washington before pitching for Tampa Bay and Seattle. In 63 career games, he's is 16-11 with a 4.37 ERA. His best season was in 2015, when Karns went 7-5 with a 3.67 ERA in 27 games, including 26 starts.
To make room on the 40-man roster, Baltimore designated infielder Jake Reinheimer for assignment on Thursday.