You are probably looking for something like:
while IFS= read -r host
do {
printf "%s\n" "$host"
ssh -t -- "$host" '
for i in a b
do
printf "%s\n" "Volume: /dev/sd$i"
sudo smartctl -a "/dev/sd$i" | grep -Ei "model|serial"
done'
} 0<&3
done 3<&0 <hostlist
I am assuming hosts are listed in the hostlist file, one per line. IFS= and -r are probably unnecessary here, because host names are unlikely to contain blank characters or backslashes; they should not hurt, though. Similarly, reading your hostlist in a for loop is probably fine in this case, but using while loops for that is a good habit. See Why does my shell script choke on whitespace or other special characters? for more on this.
For each host, ssh is invoked with the -t option to force the allocation of a pseudo-terminal on the remote host, needed to type in the password that sudo will ask you (unless you configured it not to).
A new file descriptor is opened (3<&0), duplicating that of the outer standard input, to make the latter available to the body of the loop (which is wrapped in { } for this reason). ssh would otherwise read from hostlist and be unable to interact with you (for instance, when sudo requires your password).
I replaced echo with printf because the latter is more robust (even if, again, it was not strictly necessary here). And I replaced egrep with grep -E because (looking at the GNU manual) the former is deprecated and only provided for backward compatibility.
Finally, I replaced the brace expansion ({a..b}) with a b to make the script able to run in any POSIX shell, including those that do not support that feature (e.g. dash).