Yes, it is possible to read the content of the storage without ether.
Each peer of the network has a local copy of the entire blockchain and of the state, therefore also of each contract's storage. You can get more details in this answer.
One can read the raw data contained in a contract's storage with the web3 API function eth.getStorageAt.
To facilitate the read of the data (with a pre-defined interface) one can write solidity functions marked as
view (i.e., they promise not to modify the state) and
public (i.e., they can be called with a tx). With the web3 API you can call this type of functions locally without a transaction.