From a variation of yea, itself from Middle Englishya, ye, from Old Englishġēa (“yes”), from Proto-Germanic*ja (“yes; thus, so”), from Proto-Indo-European*yē (“already”). Cognate with Dutch ja, German ja, Danish ja, Bokmål ja, Nynorsk ja and Swedish ja. Interestingly, modern "yeah" maintains nearly the same pronunciation as its Old English ancestor (Old English "ġēa" being /jæːɑ/, Modern English "yeah" being [jɛə̯] or [jæə̯]) and consequently has really no other words that rhyme with it in rhotic dialects. The reason behind its real lack of pronunciation shift is unknown, as other words that had similar pronunciations in Old English did shift in pronunciation. It is possible that, due to its constant use (and its never being accepted as a formal term), its pronunciation has remained rigidly in place. Compare father which oddly has a pronunciation almost identical to its Proto-Germanic ancestor.
Alternative (but less likely) etymology derives yeah from a drawling pronunciation of yes. For further etymology, see yes.