diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 8ddeb1759e66703d14f87074881711018e667dba..a3ae42d05aceb1d0e6f369b39548f485813c5c26 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -530,12 +530,8 @@ public function discoverServiceProviders() {
         }
       }
     }
-    if ($container_yamls = Settings::get('container_yamls')) {
-      $this->serviceYamls['site'] = $container_yamls;
-    }
-    $site_services_yml = $this->getSitePath() . '/services.yml';
-    if (file_exists($site_services_yml) && is_readable($site_services_yml)) {
-      $this->serviceYamls['site'][] = $site_services_yml;
+    if (!$this->addServiceFiles(Settings::get('container_yamls'))) {
+      throw new \Exception('The container_yamls setting is missing from settings.php');
     }
   }
 
@@ -1295,4 +1291,21 @@ protected static function setupTrustedHosts(Request $request, $hostPatterns) {
 
     return TRUE;
   }
+
+  /**
+   * Add service files.
+   *
+   * @param $service_yamls
+   *   A list of service files.
+   *
+   * @return bool
+   *   TRUE if the list was an array, FALSE otherwise.
+   */
+  protected function addServiceFiles($service_yamls) {
+    if (is_array($service_yamls)) {
+      $this->serviceYamls['site'] = array_filter($service_yamls, 'file_exists');
+      return TRUE;
+    }
+    return FALSE;
+  }
 }
diff --git a/core/lib/Drupal/Core/Installer/InstallerKernel.php b/core/lib/Drupal/Core/Installer/InstallerKernel.php
index 4063611b44bbe19421a3db29f36327118a338e9d..41e8cbe9cdc2d88a6fecd3ac03672206c9df4e2f 100644
--- a/core/lib/Drupal/Core/Installer/InstallerKernel.php
+++ b/core/lib/Drupal/Core/Installer/InstallerKernel.php
@@ -40,4 +40,11 @@ public function resetConfigStorage() {
     $this->configStorage = NULL;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function addServiceFiles($service_yamls) {
+    // In the beginning there is no settings.php and no service YAMLs.
+    return parent::addServiceFiles($service_yamls ?: []);
+  }
 }
diff --git a/core/lib/Drupal/Core/Test/TestRunnerKernel.php b/core/lib/Drupal/Core/Test/TestRunnerKernel.php
index a6dc573c0795ffe632971e25b88c29f955c9be7d..fa9fd51f20e9800224e9e7fd5d57cf753dcaac2a 100644
--- a/core/lib/Drupal/Core/Test/TestRunnerKernel.php
+++ b/core/lib/Drupal/Core/Test/TestRunnerKernel.php
@@ -55,6 +55,7 @@ public function boot() {
     if (!Settings::getAll()) {
       new Settings(array(
         'hash_salt' => 'run-tests',
+        'container_yamls' => [],
         // If there is no settings.php, then there is no parent site. In turn,
         // there is no public files directory; use a custom public files path.
         'file_public_path' => 'sites/default/files',
diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php
index e5d076aca4db729c10ab705abf5806fc605be5aa..d2c53412faf8e81a3315ce111034722765cce80d 100644
--- a/core/modules/simpletest/src/KernelTestBase.php
+++ b/core/modules/simpletest/src/KernelTestBase.php
@@ -135,11 +135,16 @@ protected function prepareConfigDirectories() {
   protected function setUp() {
     $this->keyValueFactory = new KeyValueMemoryFactory();
 
+    // Back up settings from TestBase::prepareEnvironment().
+    $settings = Settings::getAll();
+
     // Allow for test-specific overrides.
     $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSite . '/testing.services.yml';
     if (file_exists($settings_services_file)) {
       // Copy the testing-specific service overrides in place.
-      copy($settings_services_file, DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml');
+      $testing_services_file = DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml';
+      copy($settings_services_file, $testing_services_file);
+      $this->settingsSet('container_yamls', [$testing_services_file]);
     }
 
     // Create and set new configuration directories.
@@ -149,8 +154,6 @@ protected function setUp() {
     // @todo Remove the indirection; implement ServiceProviderInterface instead.
     $GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\simpletest\TestServiceProvider';
 
-    // Back up settings from TestBase::prepareEnvironment().
-    $settings = Settings::getAll();
     // Bootstrap a new kernel. Don't use createFromRequest so we don't mess with settings.
     $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
     $this->kernel = new DrupalKernel('testing', $class_loader, FALSE);
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 92598452a8208a9bef3604b4cdf05753481536a1..b4901af4314e3b742570032459b69a40750d1618 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -1210,6 +1210,7 @@ private function prepareEnvironment() {
     new Settings(array(
       // For performance, simply use the database prefix as hash salt.
       'hash_salt' => $this->databasePrefix,
+      'container_yamls' => [],
     ));
 
     drupal_set_time_limit($this->timeLimit);
diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php
index 59ee3f34dc0d6fc1e50cf5a42204a3f9b045628d..cc2138d84a7949293eaff42378a6cab0d7270143 100644
--- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php
+++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\DrupalKernel;
 
+use Drupal\Core\Site\Settings;
 use Drupal\simpletest\KernelTestBase;
 
 /**
@@ -20,6 +21,9 @@ class DrupalKernelSiteTest extends KernelTestBase {
    * Tests services.yml in site directory.
    */
   public function testServicesYml() {
+    $container_yamls = Settings::get('container_yamls');
+    $container_yamls[] = $this->siteDirectory . '/services.yml';
+    $this->settingsSet('container_yamls', $container_yamls);
     $this->assertFalse($this->container->has('site.service.yml'));
     // A service provider class always has precedence over services.yml files.
     // KernelTestBase::buildContainer() swaps out many services with in-memory
diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
index 44ae20fd96f56a7ce144bce05e9650e657fadfe2..af8ce27481af16cf67b8109ad820673c6e911d8a 100644
--- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
@@ -54,6 +54,7 @@ protected function getTestKernel(Request $request, array $modules_enabled = NULL
     // Manually create kernel to avoid replacing settings.
     $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
     $kernel = DrupalKernel::createFromRequest($request, $class_loader, 'testing');
+    $this->settingsSet('container_yamls', []);
     $this->settingsSet('hash_salt', $this->databasePrefix);
     if (isset($modules_enabled)) {
       $kernel->updateModules($modules_enabled);
@@ -169,6 +170,7 @@ public function testRepeatedBootWithDifferentEnvironment() {
 
     foreach ($environments as $environment) {
       $kernel = DrupalKernel::createFromRequest($request, $class_loader, $environment);
+      $this->settingsSet('container_yamls', []);
       $this->settingsSet('hash_salt', $this->databasePrefix);
       $kernel->boot();
     }
diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php b/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..31e0b9d409989e8572b3f70821dec73d13f43b34
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\DrupalKernel\DiscoverServiceProvidersTest.
+ */
+
+namespace Drupal\Tests\Core\DrupalKernel;
+
+use Drupal\Core\DrupalKernel;
+use Drupal\Core\Site\Settings;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\DrupalKernel
+ * @group DrupalKernel
+ */
+class DiscoverServiceProvidersTest extends UnitTestCase {
+
+  /**
+   * Tests discovery with user defined container yaml.
+   *
+   * @covers ::discoverServiceProviders()
+   */
+  public function testDiscoverServiceCustom() {
+    new Settings(array(
+      'container_yamls' => array(
+        __DIR__ . '/fixtures/custom.yml'
+      ),
+    ));
+
+    $kernel = new DrupalKernel('prod', new \Composer\Autoload\ClassLoader());
+    $kernel->discoverServiceProviders();
+
+    $expect = array(
+      'app' => array(
+        'core' => 'core/core.services.yml',
+      ),
+      'site' => array(
+        __DIR__ . '/fixtures/custom.yml',
+      ),
+    );
+
+    $this->assertAttributeSame($expect, 'serviceYamls', $kernel);
+  }
+
+  /**
+   * Tests the exception when container_yamls is not set.
+   *
+   * @covers ::discoverServiceProviders()
+   * @expectedException \Exception
+   */
+  public function testDiscoverServiceNoContainerYamls() {
+    new Settings([]);
+    $kernel = new DrupalKernel('prod', new \Composer\Autoload\ClassLoader());
+    $kernel->discoverServiceProviders();
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml b/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3950896fb4107bde43f65f9efb7095fefcc5ada5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml
@@ -0,0 +1,3 @@
+parameters:
+  test.config:
+    test: true
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 7cc10be7260ccade7699c9d7831d6328f6b770d4..8a3dfa494dda815ef0588bd4414fb27be1e338ba 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -594,6 +594,11 @@
 # $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i';
 # $config['system.performance']['fast_404']['html'] = '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>';
 
+/**
+ * Load services definition file.
+ */
+$settings['container_yamls'][] = __DIR__ . '/services.yml';
+
 /**
  * Load local development override configuration, if available.
  *