Shanaka (1-22) got the breakthrough before Kohli arrived at the crease and batted almost to the end of the innings.
It was Kohli’s ninth ODI hundred against Sri Lanka, overtaking Sachin Tendulkar’s record of eight centuries for India against the same opposition. Kohli is also now four short of Tendulkar’s all-time record of 49 ODI hundreds. Overall, it was Kohli’s 73rd international century.
“I was hitting the ball nicely. It was close to the template I play with,” Kohli said. “I am in a comfortable career space now and playing for the right reasons.”
Kohli scored 12 fours and a six as India crossed 200 in 27 overs. He brought up his 50 off 47 balls.
India lost Shreyas Iyer (28) in the 30th over. Kohli then added 90 runs for the fourth wicket with Lokesh Rahul (39) to take India past the 300 mark. India added 79 runs in the final 10 overs.
Sri Lanka faltered against disciplined fast bowling. Mohammed Siraj (2-30) struck early blows, removing Avishka Fernando (5) and Kusal Mendis (0).
Umran Malik (3-57) dismissed Charith Asalanka (23) to reduce Sri Lanka to 64-3 in 14 overs. Pathum Nissanka helped to hold the innings together with 72 off 80 balls, including 11 fours.
Sri Lanka was down to 206-8 but Shanaka was unperturbed in a run-a-ball half-century.
He hit 12 fours and three sixes to accelerate to a second ODI hundred. He added 100 runs off 73 balls for the unbroken ninth wicket with Kasun Rajitha only contributing 9 runs as the pair reduced the scale of defeat for Sri Lanka.
The second ODI is on Thursday at Kolkata.
Most ODI hundreds
49 - Sachin Tendulkar, India
45 - Virat Kohli, India
30 - Ricky Ponting, Australia/ICC
29 - Rohit Sharma, India
28 - Sanath Jayasuriya, Sri Lanka/Asia
27 - Hashim Amla, South Africa
25 - Kumar Sangakkara, Sri Lanka/Asia/ICC
25 - AB de Villiers, South Africa/Africa
25 - Chris Gayle, West Indies/ICC