What's the relationship between ContainerD and Docker?
Containerd is a daemon for running containers.  The Docker blog has a nice write up explaining how this fits into Docker.  While containerd is used in Docker, it can also be used as a daemon for other container solutions.  Containerd requires runc in order to function.

runc as defined by the project is a "CLI tool for spawning and running containers according to the OCI specification".

These tools are designed to follow the Open Container Initiative (OCI) specifications.  This has become a standard and defines how Docker and other tooling interacts with containerd and runc.

When you look at most Kubernetes diagrams they will not show containerd or runc as they are abstracted away into the container engine you use (e.g., Docker, rkt).  Because Kubernetes uses containerd, it will also use runc.  This is what allows multiple container solutions that follow OCI specifications to integrate with Kubernetes.

So yes, you could break down how part of Kubernetes is built by looking at runc, containerd, and the container engine.