diff --git a/defaults/main.yml b/defaults/main.yml
index 06e40c4..b22f505 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -46,9 +46,15 @@ zun_git_install_branch: master
 zun_kuryr_git_repo: https://opendev.org/openstack/kuryr-libnetwork
 zun_kuryr_git_install_branch: master
 
+# This is only required until kuryr-libnetwork depends upon a version of kuryr-lib
+# which includes https://review.opendev.org/c/openstack/kuryr/+/764908
+zun_kuryr_lib_git_repo: https://opendev.org/openstack/kuryr
+zun_kuryr_lib_git_install_branch: master
+
 zun_upper_constraints_url: "{{ requirements_git_url | default('https://releases.openstack.org/constraints/upper/' ~ requirements_git_install_branch | default('master')) }}"
 zun_git_constraints:
   - "git+{{ zun_git_repo }}@{{ zun_git_install_branch }}#egg=zun"
+  - "git+{{ zun_kuryr_lib_git_repo }}@{{ zun_kuryr_lib_git_install_branch }}#egg=kuryr-lib"
   - "git+{{ zun_kuryr_git_repo }}@{{ zun_kuryr_git_install_branch }}#egg=kuryr-libnetwork"
   - "--constraint {{ zun_upper_constraints_url }}"
 
@@ -80,6 +86,10 @@ zun_kuryr_log_dir: "/var/log/kuryr"
 
 zun_kuryr_lock_path: "/var/lock/kuryr"
 
+## Docker setup information
+zun_docker_package_version: "{{ _zun_docker_package_version }}"
+zun_containerd_package_version: "{{ _zun_containerd_package_version }}"
+
 # Set a list of users that are permitted to execute the docker binary.
 zun_docker_users:
   - "{{ zun_system_user_name }}"
@@ -178,7 +188,7 @@ zun_kuryr_service_port: 23750
 zun_service_description: "Zun Compute Service"
 zun_service_publicuri: "{{ zun_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ zun_service_port }}"
 zun_service_publicurl: "{{ zun_service_publicuri }}"
-zun_service_adminuri: "{{ zun_service_adminuri_proto }}//{{ internal_lb_vip_address }}:{{ zun_service_port }}"
+zun_service_adminuri: "{{ zun_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ zun_service_port }}"
 zun_service_adminurl: "{{ zun_service_adminuri }}"
 zun_service_internaluri: "{{ zun_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ zun_service_port }}"
 zun_service_internalurl: "{{ zun_service_internaluri }}"
@@ -312,5 +322,6 @@ zun_kuryr_init_overrides:
     Wants: network-online.target
   Service:
     CapabilityBoundingSet: CAP_NET_ADMIN
+    AmbientCapabilities: CAP_NET_ADMIN
     Group: "{{ zun_kuryr_system_group_name }}"
     User: "{{ zun_kuryr_system_user_name }}"
diff --git a/tasks/zun_compute.yml b/tasks/zun_compute.yml
index 20ed575..f7bb358 100644
--- a/tasks/zun_compute.yml
+++ b/tasks/zun_compute.yml
@@ -26,6 +26,23 @@
 
 - name: Run apt install block
   block:
+    - name: Run the apt package pinning role
+      include_role:
+        name: apt_package_pinning
+      vars:
+        apt_package_pinning_file_name: "docker.pref"
+        apt_package_pinning_priority: 999
+        apt_pinned_packages:
+          - package: "docker-ce"
+            version: "{{ zun_docker_package_version }}"
+            priority: 1000
+          - package: "docker-ce-cli"
+            version: "{{ zun_docker_package_version }}"
+            priority: 1000
+          - package: "containerd.io"
+            version: "{{ zun_containerd_package_version }}"
+            priority: 1000
+
     - name: Get apt gpg key
       get_url:
         url: "{{ item.gpg_uri }}"
@@ -96,11 +113,20 @@
     cache_valid_time: "{{ (ansible_pkg_mgr == 'apt') | ternary(cache_timeout, omit) }}"
     enablerepo: "{{ (ansible_pkg_mgr in ['yum', 'dnf']) | ternary('extras', omit) }}"
 
+- name: Ensure the Docker config directory exists
+  file:
+    path: "/etc/docker"
+    state: "directory"
+    owner: "root"
+    group: "root"
+    mode: "0755"
+
 - name: Generate kuryr config
   config_template:
     content: |
       {
-        "live-restore": true
+        "live-restore": true,
+        "default-ipc-mode": "shareable"
       }
     dest: "/etc/docker/daemon.json"
     owner: "root"
@@ -145,6 +171,7 @@
     createhome: "yes"
     home: "{{ zun_kuryr_system_home_folder }}"
     generate_ssh_key: "yes"
+  when: zun_kuryr_system_user_name != 'root'
   tags:
     - zun-kuryr-user
     - zun-kuryr-key
@@ -211,7 +238,7 @@
 - name: Ensure docker users are added to the docker group
   user:
     name: "{{ item }}"
-    group: "{{ zun_docker_groupname }}"
+    groups: "{{ zun_docker_groupname }}"
     append: yes
   with_items: "{{ zun_docker_users }}"
 
@@ -225,3 +252,15 @@
   tags:
     - sudoers
     - zun-sudoers
+
+- name: Configure multipathd (RedHat only)
+  command:
+    cmd: "/sbin/mpathconf --enable"
+    creates: "/etc/multipath.conf"
+  when: ansible_os_family == "RedHat"
+
+- name: Enable multipathd service
+  systemd:
+    name: multipathd
+    state: started
+    enabled: yes
diff --git a/tasks/zun_post_install.yml b/tasks/zun_post_install.yml
index 71dd693..20cd4ff 100644
--- a/tasks/zun_post_install.yml
+++ b/tasks/zun_post_install.yml
@@ -18,7 +18,7 @@
     - name: Get docker api version
       command: >-
         {% raw %}
-        docker version -f "{{.Client.APIVersion }}"
+        docker version -f "{{ .Client.APIVersion }}"
         {% endraw %}
       failed_when: false
       changed_when: false
diff --git a/tasks/zun_pre_flight.yml b/tasks/zun_pre_flight.yml
index e69f74d..6c3b98f 100644
--- a/tasks/zun_pre_flight.yml
+++ b/tasks/zun_pre_flight.yml
@@ -24,13 +24,13 @@
     - "zun_api"
     - "zun_compute"
 
-- name: Check for oslomsg_rpc_all group
+- name: Check for rabbitmq_all group
   fail:
     msg: >-
-      The group `oslomsg_rpc_all` is undefined. Before moving forward
+      The group `rabbitmq_all` is undefined. Before moving forward
       set this group within inventory with at least one host.
   when:
-    - (groups['oslomsg_rpc_all'] | length) < 1
+    - (groups['rabbitmq_all'] | length) < 1
 
 - name: Check for oslomsg_rpc_password
   fail:
diff --git a/tasks/zun_pre_install.yml b/tasks/zun_pre_install.yml
index e2eb034..f1e5e7a 100644
--- a/tasks/zun_pre_install.yml
+++ b/tasks/zun_pre_install.yml
@@ -69,6 +69,7 @@
     - { path: "{{ zun_system_home_folder }}/.ssh", mode: "0700" }
     - { path: "{{ zun_system_home_folder }}/cache/api" }
     - { path: "{{ zun_system_home_folder }}/instances" }
+    - { path: "{{ zun_system_home_folder }}/volumes" }
     - { path: "{{ zun_lock_path }}" }
     - { path: "/var/run/zun" }
   tags:
diff --git a/templates/rootwrap.conf.j2 b/templates/rootwrap.conf.j2
index 407490b..64d8adf 100644
--- a/templates/rootwrap.conf.j2
+++ b/templates/rootwrap.conf.j2
@@ -10,7 +10,7 @@ filters_path=/etc/zun/rootwrap.d
 # explicitely specify a full path (separated by ',')
 # If not specified, defaults to system PATH environment variable.
 # These directories MUST all be only writable by root !
-exec_dirs={{ zun_bin }},{{ zun_bin }}/libexec/kuryr,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin
+exec_dirs={{ zun_bin }},{{ zun_bin | dirname }}/libexec/kuryr,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin
 
 # Enable logging to syslog
 # Default value is False
diff --git a/templates/sudoers.j2 b/templates/sudoers.j2
index 5f2a2b8..dfb6b5f 100644
--- a/templates/sudoers.j2
+++ b/templates/sudoers.j2
@@ -1,6 +1,6 @@
 # {{ ansible_managed }}
 
 Defaults:{{ zun_system_user_name }} !requiretty
-Defaults:{{ zun_system_user_name }} secure_path="{{ zun_bin }}:{{ zun_bin }}/libexec/kuryr:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+Defaults:{{ zun_system_user_name }} secure_path="{{ zun_bin }}:{{ zun_bin | dirname }}/libexec/kuryr:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
 {{ zun_system_user_name }} ALL = (root) NOPASSWD: {{ zun_bin }}/{{ zun_service_name }}-rootwrap
diff --git a/templates/zun.conf.j2 b/templates/zun.conf.j2
index 88f95d0..c2d2fa2 100644
--- a/templates/zun.conf.j2
+++ b/templates/zun.conf.j2
@@ -6,7 +6,9 @@ transport_url = {{ zun_oslomsg_rpc_transport }}://{% for host in zun_oslomsg_rpc
 
 use_sandbox = true
 image_driver_list = glance,docker
-default_image_driver = glance
+default_image_driver = docker
+
+capsule_driver = docker
 
 
 [api]
@@ -100,6 +102,11 @@ topics = {{ notification_topics | join(',') }}
 ssl = {{ zun_oslomsg_notify_use_ssl | bool }}
 
 
+[placement_client]
+endpoint_type = {{ zun_service_endpoint_type }}
+insecure = {{ keystone_service_adminuri_insecure | bool }}
+
+
 [scheduler]
 driver = {{ zun_scheduler_driver }}
 available_filters = {{ zun_scheduler_available_filters }}
@@ -108,7 +115,8 @@ enabled_filters = {{ zun_scheduler_default_filters }}
 
 [volume]
 use_multipath = true
-driver_list = cinder
+driver_list = cinder,local
+volume_dir = /var/lib/{{ zun_system_user_name }}/volumes
 
 
 [websocket_proxy]
diff --git a/vars/debian.yml b/vars/debian.yml
index 9fe461c..26365f9 100644
--- a/vars/debian.yml
+++ b/vars/debian.yml
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+_zun_docker_package_version: "5:19.03.14~*"
+_zun_containerd_package_version: "1.4.3-1"
+
 zun_docker_repo:
   - name: "docker-ce"
     uri: "https://download.docker.com/linux/{{ ansible_distribution | lower }}"
@@ -27,8 +30,12 @@ zun_distro_packages:
   - software-properties-common
 
 zun_distro_compute_packages:
+  - containerd.io
+  - docker-ce-cli
   - docker-ce
   - pciutils
+  - numactl
+  - multipath-tools
 
 zun_docker_groupname: docker
 
diff --git a/vars/redhat.yml b/vars/redhat.yml
index 28de2d7..32bafe1 100644
--- a/vars/redhat.yml
+++ b/vars/redhat.yml
@@ -13,10 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+_zun_docker_package_version: "19.03.14-3"
+_zun_containerd_package_version: "1.4.3-3.1"
+
 zun_docker_repo:
   - name: "docker-ce"
     description: Docker CE Stable
-    uri: "https://download.docker.com/linux/centos/7/$basearch/stable"
+    uri: "https://download.docker.com/linux/centos/{{ ansible_distribution_major_version }}/$basearch/stable"
     gpgkey: "https://download.docker.com/linux/centos/gpg"
 
 # Common yum packages
@@ -25,7 +28,11 @@ zun_distro_packages:
   - systemd-devel
 
 zun_distro_compute_packages:
-  - "{{ (ansible_distribution_major_version is version('8', '<')) | ternary('docker', 'docker-ce') }}"
+  - "containerd.io-{{ zun_containerd_package_version }}.el{{ ansible_distribution_major_version }}.x86_64"
+  - "docker-ce-cli-{{ zun_docker_package_version }}.el{{ ansible_distribution_major_version }}.x86_64"
+  - "docker-ce-{{ zun_docker_package_version }}.el{{ ansible_distribution_major_version }}.x86_64"
   - pciutils
+  - numactl
+  - device-mapper-multipath
 
-zun_docker_groupname: dockerroot
+zun_docker_groupname: docker
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 8f73b3f..434e83e 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -15,6 +15,15 @@
 
 - project:
     templates:
-      - openstack-ansible-role-jobs
+      - check-requirements
+      - openstack-ansible-deploy-aio_metal-jobs
       - publish-openstack-docs-pti
       - release-notes-jobs-python3
+    check:
+      jobs:
+        - openstack-ansible-upgrade-aio_metal-ubuntu-focal:
+            voting: false
+    gate:
+      jobs:
+        - openstack-ansible-upgrade-aio_metal-ubuntu-focal:
+            voting: false