I was where you are now, not too long ago, so maybe I can explain it from the perspective of a noob.
When you are preparing to render a frame on the GPU using Vulkan, you'll need to perform those drawing operations into some chunk of memory on the GPU. Those memory chunks are called images. To render things on the GPU, you use Shader programs. Those shader programs need to know into which memory chunk they will draw -- in other words, into which image. A shader can draw to more than one image. In the fragment shader, it would be something like:
layout(location 0) out vec4 imgA;
layout(location 1) out vec4 imgB;
vec4, in this case, is the amount of channels each pixel of the image has (RGBA, for example). Thus, you woud write 4 components to each pixel. Each location means a different image.
So, each (fragment) shader can write to 1 or more images. BUT also, shaders can READ from images passed to them. This is usuful to build images as series of steps, which you then composite together later on. Imagine something like Adobe Photoshop image, which is made up of a series of layers. Different Passes/Renderpasses/Subpasses kindof represent a new layer or effect. If the fragment shader writes to 1 output image, then that's like 1 new layer. If it writes to 2 output images, then it's like 2 layers for that shader, and so on. Those images can be be passed as inputs to subsequent shaders within the same frame. At some final step in the frame building process, you grab all those previously made images and combine them into a final image, and (usually) display it to the screen by writing it to a swapchain image.
So, a VkFramebuffer is a structure, similar to a list, for us to organize the set of images that we will provide to the shaders for their drawing operations. Some of those images will be used as inputs, others as outputs, etc.
When you create a VkRenderpass object, you tell it that there will be X amount of input images, color images, depth images, etc. But you don't tell it which actual images to use (as in, the actual RAM to use for those images). The VkFramebuffer is where you bind the actual images (Memory/RAM) to the VkRenderpass.
So, VkFramebuffer is a way to bind actual images to the placeholders in the VkRenderpass.
A swapchain is a premade series of memory chunks (images) on the GPU. It has special qualities that writing to it is like writing directly to the Window surface (kind of). Because they are just images (albeit, with special requirements), they can be bound to VkFramebuffers, and thus written to by shaders.