A interrupt is when the processor goes and executes some pre-determined code based on some event. This is done so that, with the cooperation of the specially executed code, the processor can return to executing the original code in such a way that its operation is not affected other than some additional time taken.
That's all it is, but there's a lot behind this relatively short definition. For example, the event is usually some hardware completing a task (so that the software now needs to "service" it) or a external event, but can also be caused internally in the CPU. Examples of the latter in some processors are when a unrecognized opcode is encountered for execution, a divide by 0, attempt to reference non-existant memory, or even a condition deliberately set by the software. There is great variation between processors in the details of how interrupts are handled. Saying something as simplistic as the program counter is pushed onto the stack and the interrupt code is executed is missing many important issues and is downright wrong for some processors. Not all processors even have a stack, for example.
Since the interrupt envolves interrupting the existing code to execute something else, and the processor must be able to resume the existing code, some state has to be saved as part of the interrupt mechanism. At the very least, this requires saving the PC (program counter). The mechanism for storing the PC and then later restoring it to resume execution of the original code is usually done similarly to how subroutines are handled on that processor. For example, the PC could be stored in a special place, special register, pushed on a stack, etc. All these and more have been done historically.
Since it must be possible for interrupts to be transparent to the interrupted code (other than a delay between two instructions), this usually means some other state must be saved and restored on entry and exit of the interrupt routine. What state needs to be restored, and whether hardware mechanisms are provided to do this or facilitate this is highly dependent on the processor architecture. For example, old style PICs save the PC on the hardware stack for you, and the rest is up to the interrupt code. Anything it uses must be saved first so that it can be restored later. For example, on these PICs you can't do much without using the W register, so just about any useful interrupt routine would need to save the W register early on and then restore is shortly before exiting the interrupt code.
More high end processors might provide a whole set of "shadow" registers just for use during interrupts. The hardware switches to using these alternate registers automatically upon interrupt and switches back on return from interrupt. In this case, the interrupt code can just use registers normally without worrying about trashing them from the interrupted code's point of view.
There are many many processor architectures out there, and the details of how interrupts are handled can vary significantly between architectures. Some processors have a single location execution goes on interrupt. Others have a different location for each posssible interrupt condition. On processors with virtual memory or protection mechanism to handle hostile processes, it gets more complicated. Multiple threads of execution makes things complicated (which process' context does the interrupt code run with, for example?). Then there are interrupt priorities, or not. You generally don't want the same interrupt condition to be able to interrupt the interrupt code that is trying to handle it.
There are many many details and many many schemes have been devised to implement interrupts, but they all conform to the definition in the first paragraph.
The best way to learn how interrupts work is to understand them on one specific machine. For starters, pick a simple one, like a original PIC 16. Once you understand that, it will be easier to understand the extra wrinkles added by higher end processors.