How to allow admins to create a sidebar from the admin

Create a function that register sidebars, using register_sidebar, starting from an option:

add_action('widgets_init', 'my_custom_sidebars');

function my_custom_sidebars() {
  $sidebars = get_option('my_theme_sidebars'); // get all the sidebars names
  if ( ! empty($sidebars) ) {
    // add a sidebar for every sidebar name
    foreach ( $sidebars as $sidebar ) {
      if ( empty($sidebar) ) continue;
        register_sidebar(array(
          'name' => $sidebar,
          'id' => sanitize_title($sidebar),
          'before_title' => '<h1>',
          'after_title' => '</h1>'
        ));
    }
  }
}

Now you have to save an option 'my_theme_sidebars' that contain an array of sidebars name.
Here I’m posting post the code that create a page with 10 text inputs where add the sidebar name. (I’ll use add_theme_page) You can improve it adding javascript to dynamic add fields..

add_action('admin_menu', 'my_custom_sidebars_page');

function my_custom_sidebars_page() {
  add_theme_page(
    'Sidebars',
    'Sidebars',
    'edit_theme_options',
    'my_custom_sidebars',
    'my_custom_sidebars_page_print'
   );
  // save the form if submitted
  $nonce = filter_input(INPUT_POST, 'my_custom_sidebars_nonce', FILTER_SANITIZE_STRING);
  if ( ! empty($nonce) && wp_verify_nonce($nonce, 'my_custom_sidebars') ) {
     $sidebars =  (array) $_POST['custom_sidebars'];
     update_option('my_theme_sidebars', $sidebars);
     add_action('admin_notices', 'my_custom_sidebars_notice');
  }
}

function my_custom_sidebars_page_print() {
  if (! current_user_can('edit_theme_options') ) return;
  ?>
  <div class="wrap">
    <h2>Sidebars</h2>
    <form id="sidebars" method="post">
    <?php
    wp_nonce_field('my_custom_sidebars', 'my_custom_sidebars_nonce');
    $saved = get_option('my_theme_sidebars');
    for ($i=0; $i<10; $i++) {
      $value = isset( $saved[$i] ) ? esc_attr($saved[$i]) : '';
    ?>
    <input type="text" name="custom_sidebars[]" value="<?php echo $value;?>" />
    <?php } ?>
    <p class="submit">
      <input name="submit" class="button button-primary" value="Save" type="submit">
    </p>
    </form>
  </div>
  <?php
}

function my_custom_sidebars_notice() {
  echo '<div class="updated"><p>Updated.</p></div>';
}

Now, you have you let users select the sidebars for a specific page.
You can add a metabox for that. (See add_meta_box docs).

add_action( 'add_meta_boxes', 'my_custom_sidebar_metabox' ); 

function my_custom_sidebar_metabox() {
  $screens = array( 'post', 'page' ); // add the metabox for pages and post
  foreach ( $screens as $screen ) {
    add_meta_box('my_custom_sidebar', 'Select a Sidebar','my_custom_sidebar_box', $screen);
  }
}

function my_custom_sidebar_box( $post ) {
  $sidebars = get_option('my_theme_sidebars'); // get all the sidebars names 
  if ( empty($sidebars) ) {
    echo 'No custom sidebars registered.';
    return;
  }
  wp_nonce_field( 'my_custom_sidebar', 'my_custom_sidebar_box_nonce' );
  $value = get_post_meta( $post->ID, '_custom_sidebar', true ); // actual value
  echo '<label>Select a Sidebar</label> ';
  echo '<select name="custom_sidebar">';
  // default option
  echo '<option value=""' . selected('', $value, false) . '>Default</option>';
  // an option for every sidebar
  foreach ($sidebars as $sidebar) {
     if ( empty($sidebar) ) continue;
     $v = sanitize_title($sidebar);
     $n = esc_html($sidebar);
     echo '<option value="' . $v . '"' . selected($v, $value) .'>' .$n .'</option>';
  }
  echo '<select>';
}

Then add the function to save the metabox:

add_action( 'save_post', 'my_custom_sidebar_metabox_save' );

function my_custom_sidebar_metabox_save( $post_id ) {
  // If this is an autosave, our form has not been submitted, do nothing.
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
  // check nonce
  $nonce = filter_input(INPUT_POST, 'my_custom_sidebar_box_nonce', FILTER_SANITIZE_STRING);
  if ( empty($nonce) || ! wp_verify_nonce( $nonce, 'my_custom_sidebar' ) ) return;
  $type = get_post_type($post_id);
  // Check the user's permissions.
  $cap = ( 'page' === $type ) ? 'edit_page' : 'edit_post';
  if ( ! current_user_can( $cap, $post_id ) ) return;
  $custom = filter_input(INPUT_POST, 'custom_sidebar', FILTER_SANITIZE_STRING);
  // Update the meta field in the database.
  if ( empty($custom) ) {
     delete_post_meta( $post_id, '_custom_sidebar');
  } else {
    update_post_meta( $post_id, '_custom_sidebar', $custom );
  }
}

In this way your users can choose a custom sidebar for every post or page. It is saved in the meta field ‘_custom_sidebar'.

To display the custom sidebar, your sidebar.php should contain something like:

// change the following according to your defaults sidebar if exists
$sidebar="main_sidebar"; 
// if in singular post/page check for saved custom sidebar
if ( is_singular() ) {
  $id = get_queried_object_id(); // get current post/page id
  $custom = get_post_meta( $id, '_custom_sidebar', true ); // get selected sidebar
  if ( ! empty($custom) ) $sidebar = $custom;
}
if ( is_active_sidebar( $sidebar ) ) {
?>
<ul id="sidebar"><?php dynamic_sidebar( $sidebar ); ?></ul>
<?php } ?>

Finally in your pages and posts just call get_sidebar(); as usual.