Exact requirements for a salt depend on the password hashing algorithm, but for the usual methods (bcrypt, PBKDF2...) the only requirement is that the salt is unique. Or at least as unique as is practical; the odd collision is not a big issue as long as it does not happen often and cannot be forced from the outside.
Uniqueness is worldwide; it is not sufficient for salts to be unique in a given server. Two distinct servers, using the same hashing algorithm, should have distinct salts too.
A relatively common and cheap way to get worldwide uniqueness is to generate salts from a cryptographically strong PRNG, with sufficient length (16 random bytes are sufficient). That's what bcrypt does. If the PRNG is biased, then you need a somewhat longer salt to achieve uniqueness. If the PRNG is weak because of too small a seed or internal state, then uniqueness will not be satisfactorily obtained that way. The user name is not a good salt, for two reasons:
- The same user name can occur in several servers (e.g. each server might have an "Administrator" account, under that exact name);
- The user does not change his name when he changes his password, leading to salt reuse.
In this answer, a fringe scenario is evoked: an attacker learns the salt beforehand, prepares a big precomputed table, then enacts the actual attack which reveals the password hash. This does not make it easier for the attacker to break the password; in fact, this increases his effort (he has to produce a full table instead of stopping when the password is found, so that's double cost on average; if the table is of the rainbow persuasion, an additional 1.7 factor enters for table generation; and there are storage costs). What it changes is the dynamics: this shortens the time between the break-in (the hash value is stolen) and the password recovery. This is an edge case, so don't sweat it. If you use password hashing for storage in an authentication protocol, where hashing occurs server-side, then you just store the salt with the hash value and the salts will be as confidential as the hash values themselves, and that's good. In other cases (e.g. password-based file encryption), salts will be more "public", but that's not critical in any way, so don't go about adding extra complexity to keep the salts secret (extra complexity is bad, and much worse than public salts).