A user doesn't need to know the complexity of how it makes the coffee, just that they need to insert a coffee pods and press a button.
You've already hit the nail on the head. Abstraction is about removing irrelevant details of implementation in order to focus on the relevant details. It goes the the distinction you're describing.
In the real world, such irrelevant detail quickly goes to molecules, studies of chemistry, physics, etc... when all we're interested in is the cup of coffee.
In programming, it is a bit different, since we're dealing with information manipulation rather than molecules, so it goes to how we distance the details of the algorithms and state needed to accomplish the result — which may be a cup of coffee object being created, or may be an espresso machine controller that coordinates the making of coffee in the real world.
Fundamentally, in programming abstraction goes to the separation of the interface that the client uses/sees and the underlying implementation that is provided to make these things happen — which is a bit different from the real world, since we are manipulating state instead of molecules. By separating the interface from the implementation we both focus on the relevant (as the author sees fit) and de-focus on the implementation.
Generalization is a refactoring that allows one interface to work across several different scenarios (as in finding what common ground there is among different types objects). It is closely related to abstraction as generalization also focuses attention on relevant while holding off on the irrelevant, though it is done with a particular focus on the common ground vs. the specializations.
Encapsulation is enclosing internal details of something with the objective of limiting/controlling/hiding how the object can be interacted with from the outside world. So, encapsulation also hides implementation details while focusing on the relevant interface for the consumer, but it goes somewhat more to the intent of preventing incorrect update/modification/usage of an encapsulated entity rather than abstractions focus on the interface.
All of these arguably have overlap, and go together in OOP.
Abstraction can be done via a single function which is an interface of sorts (often called a signature in OOP), or a group related of functions (often called an interface in OOP, also goes to the class construct), or a forest of interfaces/classes (often done using a namespace in OOP).
In some languages these are formal constructs, though these approaches can also be done in languages that don't offer (one or more of) these as formal constructs.
Generalization goes to the class and interface hierarchy, in that typically we have a base class or an interface representing the common ground among several concepts, and then specializations (concrete implementations of interfaces, or subclasses of base classes) that offer the differentiating for these concepts. So, abstraction on several levels.
While encapsulation's objective is to foster appropriate usage and deny inappropriate usage by information and capability hiding using private vs. public, for example.