diff --git a/roles/kubernetes/master/tasks/pre-upgrade.yml b/roles/kubernetes/master/tasks/pre-upgrade.yml
index 239c46be94fb9821418cbfbb640b46dd936c7113..3b9f26de1d99c1359d77ce439d1ae8d095cfd5bb 100644
--- a/roles/kubernetes/master/tasks/pre-upgrade.yml
+++ b/roles/kubernetes/master/tasks/pre-upgrade.yml
@@ -14,3 +14,12 @@
     name: kube-apiserver
     state: stopped
   when: (kube_apiserver_service_file.stat.exists|default(False) or kube_apiserver_init_script.stat.exists|default(False))
+
+- name: "Pre-upgrade | remove kube-apiserver service definition"
+  file:
+    path: "{{ item }}"
+    state: absent
+  when: (kube_apiserver_service_file.stat.exists|default(False) or kube_apiserver_init_script.stat.exists|default(False))
+  with_items:
+    - /etc/systemd/system/kube-apiserver.service
+    - /etc/init.d/kube-apiserver
diff --git a/roles/network_plugin/canal/tasks/main.yml b/roles/network_plugin/canal/tasks/main.yml
index ba83edee899ed64a658daa5b8ae7f39b8c0f8b11..e88cfad7e024b017a83bca696e1ac0b3a706cc4d 100644
--- a/roles/network_plugin/canal/tasks/main.yml
+++ b/roles/network_plugin/canal/tasks/main.yml
@@ -1,9 +1,11 @@
 ---
-- name: Canal | Write flannel configuration
-  template:
-    src: network.json.j2
-    dest: /etc/flannel-network.json
-    backup: yes
+- name: Canal | Set Flannel etcd configuration
+  command: |-
+    {{ bin_dir }}/etcdctl --peers={{ etcd_access_addresses }} \
+    set /{{ cluster_name }}/network/config \
+    '{ "Network": "{{ kube_pods_subnet }}", "SubnetLen": {{ kube_network_node_prefix }}, "Backend": { "Type": "{{ flannel_backend_type }}" } }'
+  delegate_to: "{{groups['etcd'][0]}}"
+  run_once: true
 
 - name: Canal | Write canal configmap
   template:
diff --git a/roles/network_plugin/canal/templates/canal-node.yml.j2 b/roles/network_plugin/canal/templates/canal-node.yml.j2
index bdeae6cfd1dde24ab04990ced9713c8f66f7ec7d..ef6793f30df19e4758e24ac3c481e47c6c709251 100644
--- a/roles/network_plugin/canal/templates/canal-node.yml.j2
+++ b/roles/network_plugin/canal/templates/canal-node.yml.j2
@@ -19,10 +19,6 @@ spec:
     spec:
       hostNetwork: true
       volumes:
-        # Used by flannel-server-helper
-        - name: "networkconfig"
-          hostPath:
-            path: "/etc/flannel-network.json"
         # Used by calico/node.
         - name: lib-modules
           hostPath:
@@ -45,29 +41,6 @@ spec:
           hostPath:
             path: /etc/resolv.conf
       containers:
-        - name: "flannel-server-helper"
-          image: "{{ flannel_server_helper_image_repo }}:{{ flannel_server_helper_image_tag }}"
-          env:
-            # Cluster name
-            - name: CLUSTER_NAME
-              valueFrom:
-                configMapKeyRef:
-                  name: canal-config
-                  key: cluster_name
-            # The location of the etcd cluster.
-            - name: FLANNELD_ETCD_ENDPOINTS
-              valueFrom:
-                configMapKeyRef:
-                  name: canal-config
-                  key: etcd_endpoints
-          args:
-            - "--network-config=/etc/flannel-network.json"
-            - "--etcd-prefix=/$(CLUSTER_NAME)/network"
-            - "--etcd-server=$(FLANNELD_ETCD_ENDPOINTS)"
-          volumeMounts:
-            - name: "networkconfig"
-              mountPath: "/etc/flannel-network.json"
-          imagePullPolicy: "Always"
         # Runs the flannel daemon to enable vxlan networking between
         # container hosts.
         - name: flannel
diff --git a/roles/network_plugin/canal/templates/network.json.j2 b/roles/network_plugin/canal/templates/network.json.j2
deleted file mode 100644
index cbbec384140c4bca6cc2f19978e952bc66f779be..0000000000000000000000000000000000000000
--- a/roles/network_plugin/canal/templates/network.json.j2
+++ /dev/null
@@ -1 +0,0 @@
-{ "Network": "{{ kube_pods_subnet }}", "SubnetLen": {{ kube_network_node_prefix }}, "Backend": { "Type": "{{ flannel_backend_type }}" } }