diff --git a/docs/cri-o.md b/docs/cri-o.md
index a5e4504888f2ca1126be96ca9bd5053577815f07..6a7f77a90e9e51d4beb484aeb3004c16ac06fe35 100644
--- a/docs/cri-o.md
+++ b/docs/cri-o.md
@@ -4,7 +4,7 @@
 Kubespray supports basic functionality for using CRI-O as the default container runtime in a cluster.
 
 * Kubernetes supports CRI-O on v1.11.1 or later.
-* `scale.yml` and `upgrade-cluster.yml` are not supported on clusters using CRI-O.
+* etcd: configure either kubeadm managed etcd or host deployment
 
 _To use the CRI-O container runtime set the following variables:_
 
@@ -13,6 +13,7 @@ _To use the CRI-O container runtime set the following variables:_
 ```yaml
 download_container: false
 skip_downloads: false
+etcd_kubeadm_enabled: true
 ```
 
 ## k8s-cluster.yml
@@ -24,7 +25,7 @@ container_manager: crio
 ## etcd.yml
 
 ```yaml
-etcd_deployment_type: host
+etcd_deployment_type: host # optionally and mutually exclusive with etcd_kubeadm_enabled
 ```
 
 [CRI-O]: https://cri-o.io/
diff --git a/roles/etcdctl/tasks/main.yml b/roles/etcdctl/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cd65cb4c5749c7afb4574e09e67b2621391a3b6f
--- /dev/null
+++ b/roles/etcdctl/tasks/main.yml
@@ -0,0 +1,59 @@
+---
+# To get the binary from container to host, use the etcd data directory mounted
+# rw from host into the container.
+
+- name: Check unintentional include of this role
+  assert:
+    that: etcd_kubeadm_enabled
+
+- name: Check if etcdctl exist
+  stat:
+    path: "{{ bin_dir }}/etcdctl"
+  register: stat_etcdctl
+
+- block:
+  - name: Check version
+    command: "{{ bin_dir }}/etcdctl version"
+    register: etcdctl_version
+    check_mode: no
+    changed_when: false
+
+  - name: Remove old binary if version is not OK
+    file:
+      path: "{{ bin_dir }}/etcdctl"
+      state: absent
+    when: etcd_version.lstrip('v') not in etcdctl_version.stdout
+  when: stat_etcdctl.stat.exists
+
+- name: Check if etcdctl still exist after version check
+  stat:
+    path: "{{ bin_dir }}/etcdctl"
+  register: stat_etcdctl
+
+- block:
+  - name: Copy etcdctl script to host
+    shell: "docker exec \"$(docker ps -qf ancestor={{ etcd_image_repo }}:{{ etcd_image_tag }})\" cp /usr/local/bin/etcdctl {{ etcd_data_dir }}"
+    when: container_manager ==  "docker"
+
+  - name: Copy etcdctl script to host
+    shell: "crictl exec \"$(crictl ps -q --image {{ etcd_image_repo }}:{{ etcd_image_tag }})\" cp /usr/local/bin/etcdctl {{ etcd_data_dir }}"
+    when: container_manager in ['crio', 'containerd']
+
+  - name: Copy etcdctl to {{ bin_dir }}
+    copy:
+      src: "{{ etcd_data_dir }}/etcdctl"
+      dest: "{{ bin_dir }}"
+      remote_src: true
+      mode: 0755
+  when: not stat_etcdctl.stat.exists
+
+- name: Remove binary in etcd data dir
+  file:
+    path: "{{ etcd_data_dir }}/etcdctl"
+    state: absent
+
+- name: Create etcdctl wrapper script
+  template:
+    src: etcdctl.sh.j2
+    dest: "{{ bin_dir }}/etcdctl.sh"
+    mode: 0755
diff --git a/roles/etcdctl/templates/etcdctl.sh.j2 b/roles/etcdctl/templates/etcdctl.sh.j2
new file mode 100644
index 0000000000000000000000000000000000000000..266bcfdadd890c45acfc59a2a31439148a575c99
--- /dev/null
+++ b/roles/etcdctl/templates/etcdctl.sh.j2
@@ -0,0 +1,8 @@
+#!/bin/bash
+# {{ ansible_managed }}
+# example invocation: etcdctl.sh get --keys-only --from-key ""
+
+etcdctl \
+  --cacert {{ kube_cert_dir }}/etcd/ca.crt \
+  --cert {{ kube_cert_dir }}/etcd/server.crt \
+  --key {{ kube_cert_dir }}/etcd/server.key "$@"
diff --git a/roles/kubernetes/master/tasks/kubeadm-etcd.yml b/roles/kubernetes/master/tasks/kubeadm-etcd.yml
index 2433fdb9f39b501cbf2a5581bf7001cdcb40bb7d..eb68c26fef030b6c5e2f3e40388ef7b016803053 100644
--- a/roles/kubernetes/master/tasks/kubeadm-etcd.yml
+++ b/roles/kubernetes/master/tasks/kubeadm-etcd.yml
@@ -16,7 +16,7 @@
   include_tasks: "{{ role_path }}/../../etcd/tasks/install_host.yml"
   vars:
     etcd_cluster_setup: true
-  when: etcd_deployment_type == "host"
+  when: etcd_deployment_type == "host" and not etcd_kubeadm_enabled
 
 - name: Ensure etcdctl binary is installed
   include_tasks: "{{ role_path }}/../../etcd/tasks/install_etcdctl_docker.yml"
@@ -24,4 +24,9 @@
     etcd_cluster_setup: true
     etcd_retries: 4
   when:
-    - etcd_deployment_type == "docker"
+    - etcd_deployment_type == "docker" and not etcd_kubeadm_enabled
+
+- name: Ensure etcdctl script is installed
+  import_role:
+    name: etcdctl
+  when: etcd_kubeadm_enabled