diff --git a/docker/services/neutron-dhcp.yaml b/docker/services/neutron-dhcp.yaml
index b0c79d44bf..73a2de7514 100644
--- a/docker/services/neutron-dhcp.yaml
+++ b/docker/services/neutron-dhcp.yaml
@@ -14,6 +14,15 @@ parameters:
     default: ['nofile=1024']
     description: ulimit for Neutron DHCP Agent Container
     type: comma_delimited_list
+  NeutronEnableDnsmasqDockerWrapper:
+    description: Generate a dnsmasq wrapper script so that neutron launches
+                 dnsmasq in a separate container.
+    type: boolean
+    default: true
+  NeutronEnableHaproxyDockerWrapper:
+    description: Generate a wrapper script so neutron launches haproxy in a separate container.
+    type: boolean
+    default: true
   EndpointMap:
     default: {}
     description: Mapping of service endpoint -> protocol. Typically set
@@ -56,6 +65,8 @@ parameters:
 conditions:
 
   internal_tls_enabled: {equals: [{get_param: EnableInternalTLS}, true]}
+  dnsmasq_wrapper_enabled: {equals: [{get_param: NeutronEnableDnsmasqDockerWrapper}, true]}
+  haproxy_wrapper_enabled: {equals: [{get_param: NeutronEnableHaproxyDockerWrapper}, true]}
 
 resources:
 
@@ -90,6 +101,12 @@ outputs:
             - internal_tls_enabled
             - tripleo::certmonger::neutron::postsave_cmd: "true" # TODO: restart the container here
             - {}
+          - tripleo::profile::base::neutron::dhcp_agent_wrappers::enable_dnsmasq_wrapper: {get_param: NeutronEnableDnsmasqDockerWrapper}
+            tripleo::profile::base::neutron::dhcp_agent_wrappers::dnsmasq_process_wrapper: '/var/lib/neutron/dnsmasq_wrapper'
+            tripleo::profile::base::neutron::dhcp_agent_wrappers::dnsmasq_image: {get_param: DockerNeutronDHCPImage}
+            tripleo::profile::base::neutron::dhcp_agent_wrappers::enable_haproxy_wrapper: {get_param: NeutronEnableHaproxyDockerWrapper}
+            tripleo::profile::base::neutron::dhcp_agent_wrappers::haproxy_process_wrapper: '/var/lib/neutron/dhcp_haproxy_wrapper'
+            tripleo::profile::base::neutron::dhcp_agent_wrappers::haproxy_image: {get_param: DockerNeutronDHCPImage}
       logging_source: {get_attr: [NeutronBase, role_data, logging_source]}
       logging_groups: {get_attr: [NeutronBase, role_data, logging_groups]}
       service_config_settings: {get_attr: [NeutronBase, role_data, service_config_settings]}
@@ -128,7 +145,29 @@ outputs:
               owner: neutron:neutron
             - path: /etc/pki/tls/private/neutron.key
               owner: neutron:neutron
+      docker_config_scripts: {get_attr: [ContainersCommon, docker_config_scripts]}
       docker_config:
+        step_2:
+          create_dnsmasq_wrapper:
+            start_order: 1
+            detach: false
+            net: host
+            pid: host
+            user: root
+            command: # '/docker_puppet_apply.sh "STEP" "TAGS" "CONFIG" "DEBUG"'
+              list_concat:
+                -
+                  - '/docker_puppet_apply.sh'
+                  - '4'
+                  - 'file'
+                  - 'include ::tripleo::profile::base::neutron::dhcp_agent_wrappers'
+            image: {get_param: DockerNeutronDHCPImage}
+            volumes:
+              list_concat:
+                - {get_attr: [ContainersCommon, docker_puppet_apply_volumes]}
+                -
+                  - /run/openvswitch:/run/openvswitch
+                  - /var/lib/neutron:/var/lib/neutron
         step_4:
           neutron_dhcp:
             start_order: 10
@@ -151,6 +190,17 @@ outputs:
                   - /run/openvswitch:/run/openvswitch
                   - /var/lib/neutron:/var/lib/neutron
                   - /run/netns:/run/netns:shared
+                  - /var/lib/openstack:/var/lib/openstack
+                -
+                  if:
+                    - dnsmasq_wrapper_enabled
+                    - - /var/lib/neutron/dnsmasq_wrapper:/usr/local/bin/dnsmasq:ro
+                    - null
+                -
+                  if:
+                    - haproxy_wrapper_enabled
+                    - - /var/lib/neutron/dhcp_haproxy_wrapper:/usr/local/bin/haproxy:ro
+                    - null
                 -
                   if:
                     - internal_tls_enabled
diff --git a/docker/services/neutron-l3.yaml b/docker/services/neutron-l3.yaml
index dc39799cc7..f676ab3d19 100644
--- a/docker/services/neutron-l3.yaml
+++ b/docker/services/neutron-l3.yaml
@@ -14,6 +14,27 @@ parameters:
     default: ['nofile=1024']
     description: ulimit for Neutron L3 Agent Container
     type: comma_delimited_list
+  NeutronEnableKeepalivedWrapper:
+    description: Generate a wrapper script so neutron launches keepalived processes in a
+                 separate container.
+    type: boolean
+    default: true
+  NeutronEnableHaproxyDockerWrapper:
+    description: Generate a wrapper script so neutron launches haproxy in a separate container.
+    type: boolean
+    default: true
+  NeutronEnableDibblerDockerWrapper:
+    description: Generate a wrapper script so neutron launches the dibbler client in a separate
+                 container.
+    type: boolean
+    default: true
+  NeutronEnableRadvdDockerWrapper:
+    description: Generate a wrapper script so neutron launches radvd in a separate container. Note
+                 that is currently disabled by default pending availability of a fix to radvd
+                 (see https://bugzilla.redhat.com/show_bug.cgi?id=1564391). It will be enabled by default
+                 once the fix to radvd is generally available across target distributions.
+    type: boolean
+    default: false
   ServiceData:
     default: {}
     description: Dictionary packing service data
@@ -45,6 +66,12 @@ parameters:
     description: Flag to indicate undercloud upgrade process is being run.
     default: false
 
+conditions:
+  keepalived_wrapper_enabled: {equals: [{get_param: NeutronEnableKeepalivedWrapper}, true]}
+  haproxy_wrapper_enabled: {equals: [{get_param: NeutronEnableHaproxyDockerWrapper}, true]}
+  dibbler_wrapper_enabled: {equals: [{get_param: NeutronEnableDibblerDockerWrapper}, true]}
+  radvd_wrapper_enabled: {equals: [{get_param: NeutronEnableRadvdDockerWrapper}, true]}
+
 resources:
 
   ContainersCommon:
@@ -74,6 +101,21 @@ outputs:
         map_merge:
           - get_attr: [NeutronL3Base, role_data, config_settings]
           - get_attr: [NeutronLogging, config_settings]
+          - tripleo::profile::base::neutron::l3_agent_wrappers::enable_keepalived_wrapper: {get_param: NeutronEnableKeepalivedWrapper}
+            tripleo::profile::base::neutron::l3_agent_wrappers::keepalived_process_wrapper: '/var/lib/neutron/keepalived_wrapper'
+            # TODO(beagles): this can be removed after a cleanup of the related puppet-tripleo code.
+            tripleo::profile::base::neutron::l3_agent_wrappers::keepalived_state_change_wrapper: '/var/lib/neutron/keepalived_state_change_wrapper'
+            tripleo::profile::base::neutron::l3_agent_wrappers::keepalived_image: {get_param: DockerNeutronL3AgentImage}
+            tripleo::profile::base::neutron::l3_agent_wrappers::enable_haproxy_wrapper: {get_param: NeutronEnableHaproxyDockerWrapper}
+            tripleo::profile::base::neutron::l3_agent_wrappers::haproxy_process_wrapper: '/var/lib/neutron/l3_haproxy_wrapper'
+            tripleo::profile::base::neutron::l3_agent_wrappers::haproxy_image: {get_param: DockerNeutronL3AgentImage}
+            tripleo::profile::base::neutron::l3_agent_wrappers::enable_dibbler_wrapper: {get_param: NeutronEnableDibblerDockerWrapper}
+            tripleo::profile::base::neutron::l3_agent_wrappers::dibbler_process_wrapper: '/var/lib/neutron/dibbler_wrapper'
+            tripleo::profile::base::neutron::l3_agent_wrappers::dibbler_image: {get_param: DockerNeutronL3AgentImage}
+            tripleo::profile::base::neutron::l3_agent_wrappers::enable_radvd_wrapper: {get_param: NeutronEnableRadvdDockerWrapper}
+            tripleo::profile::base::neutron::l3_agent_wrappers::radvd_process_wrapper: '/var/lib/neutron/radvd_wrapper'
+            tripleo::profile::base::neutron::l3_agent_wrappers::radvd_image: {get_param: DockerNeutronL3AgentImage}
+
       logging_source: {get_attr: [NeutronL3Base, role_data, logging_source]}
       logging_groups: {get_attr: [NeutronL3Base, role_data, logging_groups]}
       service_config_settings: {get_attr: [NeutronL3Base, role_data, service_config_settings]}
@@ -102,7 +144,29 @@ outputs:
             - path: /var/lib/neutron
               owner: neutron:neutron
               recurse: true
+      docker_config_scripts: {get_attr: [ContainersCommon, docker_config_scripts]}
       docker_config:
+        step_2:
+          create_keepalived_wrapper:
+            start_order: 1
+            detach: false
+            net: host
+            pid: host
+            user: root
+            command: # '/docker_puppet_apply.sh "STEP" "TAGS" "CONFIG" "DEBUG"'
+              list_concat:
+                -
+                  - '/docker_puppet_apply.sh'
+                  - '4'
+                  - 'file'
+                  - 'include ::tripleo::profile::base::neutron::l3_agent_wrappers'
+            image: {get_param: DockerNeutronL3AgentImage}
+            volumes:
+              list_concat:
+                - {get_attr: [ContainersCommon, docker_puppet_apply_volumes]}
+                -
+                  - /run/openvswitch:/run/openvswitch
+                  - /var/lib/neutron:/var/lib/neutron
         step_4:
           neutron_l3_agent:
             start_order: 10
@@ -125,6 +189,27 @@ outputs:
                   - /run/openvswitch:/run/openvswitch
                   - /var/lib/neutron:/var/lib/neutron
                   - /run/netns:/run/netns:shared
+                  - /var/lib/openstack:/var/lib/openstack
+                -
+                  if:
+                    - keepalived_wrapper_enabled
+                    - - /var/lib/neutron/keepalived_wrapper:/usr/local/bin/keepalived:ro
+                    - null
+                -
+                  if:
+                    - haproxy_wrapper_enabled
+                    - - /var/lib/neutron/l3_haproxy_wrapper:/usr/local/bin/haproxy:ro
+                    - null
+                -
+                  if:
+                    - radvd_wrapper_enabled
+                    - - /var/lib/neutron/radvd_wrapper:/usr/local/bin/radvd:ro
+                    - null
+                -
+                  if:
+                    - dibbler_wrapper_enabled
+                    - - /var/lib/neutron/dibbler_wrapper:/usr/local/bin/dibbler_client:ro
+                    - null
             environment:
               - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
       metadata_settings:
diff --git a/puppet/services/docker.yaml b/puppet/services/docker.yaml
index 361e518c9e..e338913022 100644
--- a/puppet/services/docker.yaml
+++ b/puppet/services/docker.yaml
@@ -54,6 +54,11 @@ parameters:
     default: '--log-driver=journald --signature-verification=false --iptables=false --live-restore'
     description: Options that are used to startup the docker service.
     type: string
+  DockerAdditionalSockets:
+    default: ['/var/lib/openstack/docker.sock']
+    description: Additional domain sockets for the docker daemon to bind to (useful for mounting
+                 into containers that launch other containers)
+    type: comma_delimited_list
   DeploymentUser:
     default: ''
     description: User added to the docker group in order to use container commands.
@@ -64,6 +69,7 @@ conditions:
   insecure_registry_mirror_is_empty: {equals : [{get_param: DockerRegistryMirror}, '']}
   service_debug_unset: {equals : [{get_param: DockerDebug}, '']}
   deployment_user_is_empty: {equals : [{get_param: DeploymentUser}, '']}
+  additional_sockets_is_empty: {equals : [{get_param: DockerAdditionalSockets}, []]}
 
 outputs:
   role_data:
@@ -95,6 +101,11 @@ outputs:
             - deployment_user_is_empty
             - {}
             - tripleo::profile::base::docker::deployment_user: {get_param: DeploymentUser}
+          -
+            if:
+            - additional_sockets_is_empty
+            - {}
+            - tripleo::profile::base::docker::additional_sockets: {get_param: DockerAdditionalSockets}
       step_config: |
         include ::tripleo::profile::base::docker
       upgrade_tasks: