One concrete cause of centralization in today's Internet is a difference in programming costs between a closed centralized solution and an open decentralized one. Let's say we're writing a tic-tac-toe app. In the centralized design, the game board is one data structure. Your score and mine are two variables. You'll be done in a couple of hours.
As an open decentralized solution, you're building a federated system. You need a standard protocol for communicating tic-tac-toe moves. Maybe you should work through the IETF to write an RFC for OTTTP: the Open Tic-Tac-Toe Protocol. You might be done in 2018. When solving a problem the wrong way takes two hours, and solving it the right way takes two years, it's going to get solved the wrong way.
https://www.youtube.com/watch?v=g1qroWiZF90
Note that I don't endorse the particular solution in this video - MirageOS is perhaps a more viable alternative.