diff --git a/roles/docker/handlers/main.yml b/roles/docker/handlers/main.yml
index 79db42f9219a8c563d4499f47a53b6d139ed4d9b..6f54f33d533ea38f7cde03de02d96a6d3613b7a3 100644
--- a/roles/docker/handlers/main.yml
+++ b/roles/docker/handlers/main.yml
@@ -4,6 +4,8 @@
   notify:
     - Docker | reload systemd
     - Docker | reload docker
+    - Docker | pause while Docker restarts
+    - Docker | wait for docker
 
 - name : Docker | reload systemd
   shell: systemctl daemon-reload
@@ -13,3 +15,13 @@
   service:
     name: docker
     state: restarted
+
+- name: Docker | pause while Docker restarts
+  pause: seconds=10 prompt="Waiting for docker restart"
+
+- name: Docker | wait for docker
+  command: /usr/bin/docker images
+  register: docker_ready
+  retries: 10
+  delay: 5
+  until: docker_ready.rc == 0
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
index 03db20c7537da0d9f22219939ff34c7d717fa3e2..6d71c498022d71b6639e32b0ca80657bc998993c 100644
--- a/roles/docker/tasks/main.yml
+++ b/roles/docker/tasks/main.yml
@@ -59,6 +59,14 @@
   when: ansible_service_mgr == "systemd" and
         (http_proxy is defined or https_proxy is defined or no_proxy is defined)
 
+- name: Write docker.service systemd file
+  template:
+    src: systemd-docker.service.j2
+    dest: /etc/systemd/system/docker.service
+  register: docker_service_file
+  notify: restart docker
+  when: ansible_service_mgr == "systemd" and ansible_os_family != "CoreOS"
+
 - meta: flush_handlers
 
 - name: ensure docker service is started and enabled
diff --git a/roles/network_plugin/calico/templates/systemd-docker.service b/roles/docker/templates/systemd-docker.service.j2
similarity index 83%
rename from roles/network_plugin/calico/templates/systemd-docker.service
rename to roles/docker/templates/systemd-docker.service.j2
index 01383d772135087faca8bdae7f5080f5fd92722d..b19b1caaf07a4c315820e227e4c30323bda20a94 100644
--- a/roles/network_plugin/calico/templates/systemd-docker.service
+++ b/roles/docker/templates/systemd-docker.service.j2
@@ -2,11 +2,11 @@
 Description=Docker Application Container Engine
 Documentation=http://docs.docker.com
 {% if ansible_os_family == "RedHat" %}
-After=network.target
+After=network.target docker-storage-setup.service
 Wants=docker-storage-setup.service
 {% elif ansible_os_family == "Debian" %}
 After=network.target docker.socket
-Requires=docker.socket
+Wants=docker.socket
 {% endif %}
 
 [Service]
@@ -20,17 +20,21 @@ EnvironmentFile=-/etc/sysconfig/docker-storage
 EnvironmentFile=-/etc/default/docker
 {% endif %}
 Environment=GOTRACEBACK=crash
+ExecReload=/bin/kill -s HUP $MAINPID
+Delegate=yes
+KillMode=process
 ExecStart=/usr/bin/docker daemon \
           $OPTIONS \
           $DOCKER_STORAGE_OPTIONS \
           $DOCKER_NETWORK_OPTIONS \
           $INSECURE_REGISTRY \
           $DOCKER_OPTS
+TasksMax=infinity
 LimitNOFILE=1048576
 LimitNPROC=1048576
 LimitCORE=infinity
-MountFlags=slave
 TimeoutStartSec=1min
+Restart=on-abnormal
 
 [Install]
 WantedBy=multi-user.target
diff --git a/roles/kubernetes/master/handlers/main.yml b/roles/kubernetes/master/handlers/main.yml
index a4082887b32c479a620431059dc39a1c89f9f92e..87e3adc69d239549f5f50caadcd16d174bad64a7 100644
--- a/roles/kubernetes/master/handlers/main.yml
+++ b/roles/kubernetes/master/handlers/main.yml
@@ -1,4 +1,35 @@
 ---
-- name: restart kube-apiserver
-  set_fact:
-    restart_apimaster: True
+- name: Master | restart kubelet
+  command: /bin/true
+  notify:
+    - Kubelet | reload systemd
+    - Kubelet | reload kubelet
+
+- name: wait for master static pods
+  command: /bin/true
+  notify:
+    - wait for kube-scheduler
+    - wait for kube-controller-manager
+
+- name: Master | reload systemd
+  command: systemctl daemon-reload
+  when: ansible_service_mgr == "systemd"
+
+- name: Master | reload kubelet
+  service:
+    name: kubelet
+    state: restarted
+
+- name: wait for kube-scheduler
+  uri: url=http://localhost:10251/healthz
+  register: scheduler_result
+  until: scheduler_result.status == 200
+  retries: 15
+  delay: 5
+
+- name: wait for kube-controller-manager
+  uri: url=http://localhost:10252/healthz
+  register: controller_manager_result
+  until: controller_manager_result.status == 200
+  retries: 15
+  delay: 5
diff --git a/roles/kubernetes/master/tasks/main.yml b/roles/kubernetes/master/tasks/main.yml
index fe984ce17a1d221482cc14471829b9417c92c0d7..9140ef36c7ac59fb7b45d4c4001ce46141797bf7 100644
--- a/roles/kubernetes/master/tasks/main.yml
+++ b/roles/kubernetes/master/tasks/main.yml
@@ -19,12 +19,7 @@
     src: manifests/kube-apiserver.manifest.j2
     dest: "{{ kube_manifest_dir }}/kube-apiserver.manifest"
   register: apiserver_manifest
-
-- name: restart kubelet
-  service:
-    name: kubelet
-    state: restarted
-  when: apiserver_manifest.changed
+  notify: Master | restart kubelet
 
 - name: wait for the apiserver to be running
   uri: url=http://localhost:8080/healthz
@@ -58,8 +53,10 @@
   template:
     src: manifests/kube-controller-manager.manifest.j2
     dest: "{{ kube_manifest_dir }}/kube-controller-manager.manifest"
+  notify: wait for kube-controller-manager
 
 - name: Write kube-scheduler manifest
   template:
     src: manifests/kube-scheduler.manifest.j2
     dest: "{{ kube_manifest_dir }}/kube-scheduler.manifest"
+  notify: wait for kube-scheduler
diff --git a/roles/kubernetes/node/templates/kubelet.service.j2 b/roles/kubernetes/node/templates/kubelet.service.j2
index acad42e1f3d7bdb853d573ac774dbeaec3326642..ad62d856244132bbc200c220732072c43294fcc4 100644
--- a/roles/kubernetes/node/templates/kubelet.service.j2
+++ b/roles/kubernetes/node/templates/kubelet.service.j2
@@ -2,9 +2,11 @@
 Description=Kubernetes Kubelet Server
 Documentation=https://github.com/GoogleCloudPlatform/kubernetes
 {% if kube_network_plugin is defined and kube_network_plugin == "calico" %}
-After=docker.service calico-node.service
+After=docker.service docker.socket calico-node.service
+Wants=docker.socket calico-node.service
 {% else %}
 After=docker.service
+Wants=docker.socket
 {% endif %}
 
 [Service]
diff --git a/roles/network_plugin/calico/tasks/main.yml b/roles/network_plugin/calico/tasks/main.yml
index a4c32c1c059854d8b60b39e6ee0999c8a5b0d0d9..510b8af8261d1ac88939b576cd3700cff48e56ba 100644
--- a/roles/network_plugin/calico/tasks/main.yml
+++ b/roles/network_plugin/calico/tasks/main.yml
@@ -10,13 +10,6 @@
     - restart docker
   when: ansible_os_family != "CoreOS"
 
-- name: Calico | Write docker.service systemd file
-  template:
-    src: systemd-docker.service
-    dest: /lib/systemd/system/docker.service
-  notify: restart docker
-  when: ansible_service_mgr == "systemd" and ansible_os_family != "CoreOS"
-
 - meta: flush_handlers
 
 - name: Calico | Install calicoctl container script
diff --git a/roles/network_plugin/calico/templates/calico-node.service.j2 b/roles/network_plugin/calico/templates/calico-node.service.j2
index 115da35aec13ed4f1d38d21058ba79204b4acd92..4c709705d144aafdbb29cde88168cb1e8a66aff8 100644
--- a/roles/network_plugin/calico/templates/calico-node.service.j2
+++ b/roles/network_plugin/calico/templates/calico-node.service.j2
@@ -1,8 +1,8 @@
 [Unit]
 Description=Calico per-node agent
 Documentation=https://github.com/projectcalico/calico-docker
-After=docker.service etcd-proxy.service
-Wants=docker.socket
+After=docker.service docker.socket etcd-proxy.service
+Wants=docker.socket etcd-proxy.service
 
 [Service]
 User=root
diff --git a/roles/network_plugin/flannel/handlers/main.yml b/roles/network_plugin/flannel/handlers/main.yml
index 1982765d4ae723ea2ae692d58cbb2ef433de3d97..a503569f63da2d5f38817784b9f0608108819be8 100644
--- a/roles/network_plugin/flannel/handlers/main.yml
+++ b/roles/network_plugin/flannel/handlers/main.yml
@@ -4,22 +4,6 @@
   ignore_errors: yes
   notify: restart docker
 
-- name: restart docker
-  command: /bin/true
-  notify:
-    - Flannel | reload systemd
-    - Flannel | reload docker
-    - Flannel | reload kubelet
-
-- name : Flannel | reload systemd
-  shell: systemctl daemon-reload
-  when: ansible_service_mgr == "systemd"
-
-- name: Flannel | reload docker
-  service:
-    name: docker
-    state: restarted
-
 - name: Flannel | reload kubelet
   service:
     name: kubelet
diff --git a/roles/network_plugin/flannel/tasks/main.yml b/roles/network_plugin/flannel/tasks/main.yml
index 55c47d2116b984c52af2660dee9076f7f5ea9cfb..9588559f6a5fb9e04de45a3ae8bc1644662c16e6 100644
--- a/roles/network_plugin/flannel/tasks/main.yml
+++ b/roles/network_plugin/flannel/tasks/main.yml
@@ -50,11 +50,4 @@
     state: link
   when: ansible_os_family == "CoreOS"
 
-- name: Flannel | Write docker.service systemd file
-  template:
-    src: systemd-docker.service
-    dest: /lib/systemd/system/docker.service
-  notify: restart docker
-  when: ansible_service_mgr == "systemd" and ansible_os_family != "CoreOS"
-
 - meta: flush_handlers
diff --git a/roles/network_plugin/flannel/templates/systemd-docker.service b/roles/network_plugin/flannel/templates/systemd-docker.service
deleted file mode 100644
index 3275c6e2414b15d3d73326664b998877f2c765c2..0000000000000000000000000000000000000000
--- a/roles/network_plugin/flannel/templates/systemd-docker.service
+++ /dev/null
@@ -1,28 +0,0 @@
-[Unit]
-Description=Docker Application Container Engine
-Documentation=http://docs.docker.com
-{% if ansible_os_family == "RedHat" %}
-After=network.target
-Wants=docker-storage-setup.service
-{% elif ansible_os_family == "Debian" %}
-After=network.target docker.socket
-Requires=docker.socket
-{% endif %}
-
-[Service]
-Type=notify
-EnvironmentFile=-/etc/default/docker
-Environment=GOTRACEBACK=crash
-ExecStart=/usr/bin/docker daemon \
-          $OPTIONS \
-          $DOCKER_STORAGE_OPTIONS \
-          $DOCKER_NETWORK_OPTIONS \
-          $INSECURE_REGISTRY
-LimitNOFILE=1048576
-LimitNPROC=1048576
-LimitCORE=infinity
-MountFlags=slave
-TimeoutStartSec=1min
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/network_plugin/meta/main.yml b/roles/network_plugin/meta/main.yml
index 736262ab01530d6efeee777c788cb3770f0081da..0dd36511b518c3d4d0fbfc88ebf05e7eab4814d0 100644
--- a/roles/network_plugin/meta/main.yml
+++ b/roles/network_plugin/meta/main.yml
@@ -6,3 +6,4 @@ dependencies:
    when: kube_network_plugin == 'flannel'
  - role: network_plugin/weave
    when: kube_network_plugin == 'weave'
+ - role: docker
diff --git a/roles/network_plugin/weave/handlers/main.yml b/roles/network_plugin/weave/handlers/main.yml
index f983ee5794a00f5dc0ae458f35f2983c27c32be9..e821e989b0fc4992e0bb498ea3b904db65998488 100644
--- a/roles/network_plugin/weave/handlers/main.yml
+++ b/roles/network_plugin/weave/handlers/main.yml
@@ -1,10 +1,4 @@
 ---
-- name: Weave | restart docker
-  command: /bin/true
-  notify:
-    - Weave | reload systemd
-    - Weave | reload docker
-
 - name: restart weave
   command: /bin/true
   notify:
@@ -27,11 +21,6 @@
     - Weave | reload systemd
     - reload weaveexpose
 
-- name: Weave | reload docker
-  service:
-    name: docker
-    state: restarted
-
 - name: reload weave
   service:
     name: weave
diff --git a/roles/network_plugin/weave/tasks/main.yml b/roles/network_plugin/weave/tasks/main.yml
index 5703dde9701e4391095df6023cd411a617847812..eb56d8c9bca09098f361b39383df7dc8f5af05d3 100644
--- a/roles/network_plugin/weave/tasks/main.yml
+++ b/roles/network_plugin/weave/tasks/main.yml
@@ -7,14 +7,7 @@
     group: root
     mode: 0644
   notify:
-    - Weave | restart docker
-
-- name: Write docker.service systemd file
-  template:
-    src: systemd-docker.service
-    dest: /lib/systemd/system/docker.service
-  notify: Weave | restart docker
-  when: ansible_service_mgr == "systemd" and ansible_os_family != "CoreOS"
+    - restart docker
 
 - name: Weave | Install weave
   command: rsync -piu "{{ local_release_dir }}/weave/bin/weave" "{{ bin_dir }}/weave"
diff --git a/roles/network_plugin/weave/templates/systemd-docker.service b/roles/network_plugin/weave/templates/systemd-docker.service
deleted file mode 100644
index 3275c6e2414b15d3d73326664b998877f2c765c2..0000000000000000000000000000000000000000
--- a/roles/network_plugin/weave/templates/systemd-docker.service
+++ /dev/null
@@ -1,28 +0,0 @@
-[Unit]
-Description=Docker Application Container Engine
-Documentation=http://docs.docker.com
-{% if ansible_os_family == "RedHat" %}
-After=network.target
-Wants=docker-storage-setup.service
-{% elif ansible_os_family == "Debian" %}
-After=network.target docker.socket
-Requires=docker.socket
-{% endif %}
-
-[Service]
-Type=notify
-EnvironmentFile=-/etc/default/docker
-Environment=GOTRACEBACK=crash
-ExecStart=/usr/bin/docker daemon \
-          $OPTIONS \
-          $DOCKER_STORAGE_OPTIONS \
-          $DOCKER_NETWORK_OPTIONS \
-          $INSECURE_REGISTRY
-LimitNOFILE=1048576
-LimitNPROC=1048576
-LimitCORE=infinity
-MountFlags=slave
-TimeoutStartSec=1min
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/network_plugin/weave/templates/weave.service.j2 b/roles/network_plugin/weave/templates/weave.service.j2
index a4e9e8d8ec445ba9e11ace6b800725933c1c0a8a..e901c34e73211b13578ebbf8bdf21b5acda3ec8b 100644
--- a/roles/network_plugin/weave/templates/weave.service.j2
+++ b/roles/network_plugin/weave/templates/weave.service.j2
@@ -1,8 +1,8 @@
 [Unit]
 Description=Weave Network
 Documentation=http://docs.weave.works/weave/latest_release/
-Requires=docker.service
-After=docker.service
+Wants=docker.socket
+After=docker.service docker.socket
 
 [Service]
 EnvironmentFile=-/etc/weave.env
diff --git a/roles/network_plugin/weave/templates/weaveexpose.service.j2 b/roles/network_plugin/weave/templates/weaveexpose.service.j2
index 03446ee0fd2b915a96cfac69e5af2ecfbe99cc43..f9931696e0a824183ccc3c03102cc0b674792b61 100644
--- a/roles/network_plugin/weave/templates/weaveexpose.service.j2
+++ b/roles/network_plugin/weave/templates/weaveexpose.service.j2
@@ -1,9 +1,7 @@
 [Unit]
 Documentation=http://docs.weave.works/
-Requires=docker.service
-Requires=weave.service
-After=weave.service
-After=docker.service
+Wants=docker.socket weave.service
+After=docker.service docker.socket weave.service
 
 [Service]
 Type=oneshot
diff --git a/roles/network_plugin/weave/templates/weaveproxy.service.j2 b/roles/network_plugin/weave/templates/weaveproxy.service.j2
index fe5032893271e56f747c0e2c3eabd46c854bf051..29197296fa4dbd4aeb04579fb2dcac7c18f948bb 100644
--- a/roles/network_plugin/weave/templates/weaveproxy.service.j2
+++ b/roles/network_plugin/weave/templates/weaveproxy.service.j2
@@ -1,8 +1,8 @@
 [Unit]
 Description=Weave proxy for Docker API
 Documentation=http://docs.weave.works/
-Requires=docker.service
-After=docker.service
+Wants=docker.socket
+After=docker.service docker.socket
 
 [Service]
 EnvironmentFile=-/etc/weave.%H.env