Why it matters
Before YARN, Hadoop 1 had a monolithic JobTracker that combined resource management, job scheduling, task tracking, and failure recovery for MapReduce. It worked, but it did not scale past a few thousand nodes and it could not schedule anything but MapReduce. Spark, HBase, and everything modern would have been forced to duplicate that infrastructure or run on separate clusters.
YARN split the JobTracker into two: a cluster-wide ResourceManager and a per-application ApplicationMaster. This scales far better, supports any framework that speaks the YARN API, and lets one cluster serve many workloads simultaneously.
The architecture
The ResourceManager (RM) is a single cluster-wide process (with an HA standby) that tracks total cluster resources, schedules them across competing applications, and coordinates the lifecycle of ApplicationMasters. It is the closest thing YARN has to a control plane.
The NodeManager (NM) runs on every worker host. It reports the host's available resources to the RM, launches containers when directed, and monitors their resource usage. If a container exceeds its resource limits, the NM kills it.
How it works end to end
When a client submits a job, the flow is: client contacts RM to request submission; RM allocates a container for the application's ApplicationMaster on some NM; NM launches the AM in that container. The AM then contacts the RM to negotiate additional containers for the job's actual work (map tasks, executors, whatever). The RM schedules those containers based on available resources and configured queues. As containers get allocated, the AM tells the corresponding NMs what to launch inside them.
Progress reporting flows in reverse: containers report to their AM, AM reports to the RM. When work completes, the AM releases containers back to the RM and eventually shuts itself down. Every application gets its own AM instance so a crashed AM only kills its own job, not the cluster.
Containers are the atomic unit of resource allocation: an amount of memory, an amount of CPU (called vcores), and optionally GPU or other resources. Every process YARN runs, including the AM itself, runs inside a container.