As much as I like the structured container approach, "content injection" can get unwieldy. As a balance between authoring needs, Experience Manager features, and maintainable development, consider CPs for the first level tabs and embedded schemas for the nested tabs. Use containers if you need re-use.
Main Tabs as CPs
Consider at least Component Presentations (CPs) on-the-page for the the first-level tabs. This simplifies content creation, enables drag-and-drop in Experience Manager (XPM), and gives you flexibility to change the CP layout from the page template (or view, if you will). Each component is also re-usable.
I outlined this approach in this post about CP-driven navigation.
Sub-Tabs as Embedded Schemas
For the second level of tabs, consider using embedded schemas. The typical "paragraph" or "body" embedded schema helps create the repeating sets of markup, which could display as tabs based on a template selection (or your view).
I describe the flexibility in using embedded schemas in this post on TridionDeveloper.
Containers for Re-use
If you need to re-use the individual sub-sub-tabs as separate components, then include the basic container approach. In Experience Manager, authors can still open the container in form view to add, remove, and re-order the individual components.
For the "ultimate" approach, consider configurable regions. A component presentation could create the JSON format needed to allow drag-and-drop in Experience Manager. Your page template or view logic must place CPs into their matching regions.
The best practice really depends on a given organization. I've seen teams disagree with having any page logic (authors had "ultimate flexibility" to create what they want at the CP level). I've also
had some seen many authors struggle with containers.
So you'll likely need to adjust any best practice suggestions into a "best fit." My current "professional recommendation" is to test out some authoring scenarios with at least your power editors before committing to an approach.