Descriptor Set Layouts defines the contents of a descriptor set - what types of resources (descriptors) given set contains. When You need several descriptor sets with a single uniform buffer, You can create all of these descriptor sets using the same layout (layout is only a description, a specification). This way You just tell the driver: "Hey, driver! Give me 3 descriptor sets. But all of them should be exactly the same".
But because they are created from the same layout it doesn't mean they must contain the same resource handles. All them (in Your case) must contain a uniform buffer. But what resource will be used for this uniform buffer depends on You. So each descriptor set can be updated with separate buffer.
Now when You want to use 3 buffers one after another in three consecutive frames, You can do it in several different ways:
- You can have a single descriptor set. Then in every frame, before You start preparing command buffers, You update the descriptor set with the next buffer. But when You update a descriptor set, it cannot be used by any submitted (and not yet finished) command buffers. So this would require additional synchronization and wouldn't be that much different than using a single buffer. This way You also cannot "pre-record" command buffers.
- You can have a single descriptor set. To change its contents (use a different buffer in it) You can update it through functions added in the VK_KHR_descriptor_update_template extension. It allows descriptor updates to be recorded in command buffers so synchronization should be a bit easier. It should allow You to pre-record command buffers. But it needs an extension to be supported so it's not an option on platforms that do not support it.
- Method You probably thought of - You can have 3 separate descriptor sets. All of them allocated using the same layout with a uniform buffer. Then You update each descriptor set with a different buffer (You can use 1st buffer with 1st descriptor set, 2nd buffer with 2nd descriptor set and 3rd buffer with 3rd descriptor set). Now during recording a command buffer, when You want to use a first buffer then You just bind the first descriptor set. In the next frame, You just bind a second descriptor set and so on.
The method 3 is probably the easiest to implement as it requires no synchronization for descriptors (only per frame-level synchronization is required if You have such). It also allows You to pre-record command buffers and it doesn't require any additional extensions to be enabled. But as You noted, it requires more resources to be created and managed.
Don't forget that You need to create a descriptor pool that is big enough to contain 3 uniform buffers but at the same You must also specify that You want to allocate 3 descriptor sets from it (one uniform buffer per descriptor set).
You can read more about descriptor sets in Intel's API without Secrets: Introduction to Vulkan - Part 6 tutorial.
As for Your questions:
Do I need to create 3 VkDescriptorSetLayout - one for every frame?
No - a single layout is enough (as soon as all descriptor sets contain the same types of resources in the same bindings.
Next do I need to allocate and update corresponding descriptor set
with a corresponding buffer?
As per option 3 - yes.
And after this do I need to create 3 different command buffers where I
should specify corresponding descriptor set.
It depends whether You re-record command buffers every frame or if You pre-record them up front. Usually command buffers are re-recorded each frame. But as having a single command buffer requires waiting until its submission is finished, You probably may need a set(s) of command buffers for each frame, that correspond to Your framebuffer images (and descriptor sets). So in frame 0 You use command buffer #0 (or multiple command buffers reserved for frame 0). In frame 1 You use command buffer #1 etc.
Now You can record a command buffer for a given frame and during recording You provide a descriptor set that is associated with a given frame.