The solution is actually a combination of two of these answers by Andrey Nelyubin and user 3250006.
First, to get CKEditor to keep your own HTML and class attributes, you need the configuration allowedContent = true . After that, to actually see the formatting in the editor, you need to add an additional path to contentsCss (perhaps your main CSS file or a subset that includes only Bootstrap).
So the following works for me:
CKEDITOR.replace('editor1', { contentsCss: [CKEDITOR.basePath + 'contents.css', '/path/to/custom.css'], allowedContent: true, });
source share