diff --git a/ansible/baremetal-compute-inspect.yml b/ansible/baremetal-compute-inspect.yml
index 416f70ae3e500af38da3165ef38141dadee5a249..c61224372a6237b4e707603f856436637eab04b0 100644
--- a/ansible/baremetal-compute-inspect.yml
+++ b/ansible/baremetal-compute-inspect.yml
@@ -6,7 +6,7 @@
 # We install openstacksdk in a virtualenv on one of the controllers, and delegate to
 # it when executing the stackhpc.os-ironic-state role.
 
-- name: Ensure dependencies are installed and the virtual environment is activated
+- name: Ensure dependencies are installed
   hosts: controllers[0]
   gather_facts: true
   vars:
diff --git a/playbooks/kayobe-overcloud-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-base/overrides.yml.j2
index c5f1689bf6a4b1940f6f177947cec704aa1c8c6b..c6d9ca0560c183f1cfc433ccde0d7485ff1e54fc 100644
--- a/playbooks/kayobe-overcloud-base/overrides.yml.j2
+++ b/playbooks/kayobe-overcloud-base/overrides.yml.j2
@@ -17,3 +17,10 @@ pip_upper_constraints_file: "/tmp/upper-constraints.txt"
 # Use the CI infra's PyPI mirror.
 pip_local_mirror: true
 pip_index_url: "http://{{ zuul_site_mirror_fqdn }}/pypi/simple"
+
+# NOTE(mgoddard): CentOS 8 removes interfaces from their bridge during ifdown,
+# and removes the bridge if there are no interfaces left. When Kayobe bounces
+# veth links plugged into the bridge, it causes the bridge which has the IP we
+# are using for SSH to be removed. Use a dummy interface.
+aio_bridge_ports:
+  - dummy1
diff --git a/playbooks/kayobe-overcloud-base/pre.yml b/playbooks/kayobe-overcloud-base/pre.yml
index f6d09b8a1dfd394723345590e0921c64030a9fb3..8d471475f6a4bdc0804bd32d53ecdad9c558e436 100644
--- a/playbooks/kayobe-overcloud-base/pre.yml
+++ b/playbooks/kayobe-overcloud-base/pre.yml
@@ -19,6 +19,14 @@
         - "ip l add breth1 type bridge"
         - "ip l set breth1 up"
         - "ip a add 192.168.33.3/24 dev breth1"
+        # NOTE(mgoddard): CentOS 8 removes interfaces from their bridge during
+        # ifdown, and removes the bridge if there are no interfaces left. When
+        # Kayobe bounces veth links plugged into the bridge, it causes the
+        # bridge which has the IP we are using for SSH to be removed. Use a
+        # dummy interface.
+        - "ip l add dummy1 type dummy"
+        - "ip l set dummy1 up"
+        - "ip l set dummy1 master breth1"
 
     - name: Ensure kayobe is installed
       shell:
diff --git a/playbooks/kayobe-seed-base/overrides.yml.j2 b/playbooks/kayobe-seed-base/overrides.yml.j2
index d0290d1ee86f9906e33057f928fe323d98fe3c23..b875cd23acdb83e62596acac178d2c50aa3badab 100644
--- a/playbooks/kayobe-seed-base/overrides.yml.j2
+++ b/playbooks/kayobe-seed-base/overrides.yml.j2
@@ -21,3 +21,10 @@ overcloud_host_image_workaround_resolv_enabled: false
 # Use the CI infra's PyPI mirror.
 pip_local_mirror: true
 pip_index_url: "http://{{ zuul_site_mirror_fqdn }}/pypi/simple"
+
+# NOTE(mgoddard): CentOS 8 removes interfaces from their bridge during ifdown,
+# and removes the bridge if there are no interfaces left. When Kayobe bounces
+# veth links plugged into the bridge, it causes the bridge which has the IP we
+# are using for SSH to be removed. Use a dummy interface.
+aio_bridge_ports:
+  - dummy1
diff --git a/playbooks/kayobe-seed-base/pre.yml b/playbooks/kayobe-seed-base/pre.yml
index 291fa90a3e2089112b294370c8c2cdd177f1a2a3..6e1dbd8e6f68bf11aa29dfea21722e07846fd344 100644
--- a/playbooks/kayobe-seed-base/pre.yml
+++ b/playbooks/kayobe-seed-base/pre.yml
@@ -29,6 +29,14 @@
         - "ip l add breth1 type bridge"
         - "ip l set breth1 up"
         - "ip a add 192.168.33.5/24 dev breth1"
+        # NOTE(mgoddard): CentOS 8 removes interfaces from their bridge during
+        # ifdown, and removes the bridge if there are no interfaces left. When
+        # Kayobe bounces veth links plugged into the bridge, it causes the
+        # bridge which has the IP we are using for SSH to be removed. Use a
+        # dummy interface.
+        - "ip l add dummy1 type dummy"
+        - "ip l set dummy1 up"
+        - "ip l set dummy1 master breth1"
 
     - name: Ensure kayobe is installed
       shell:
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 196bef64b6a35d47260530ca3d2ecff12b5abbdd..3a07b58ee46868bce124857d5db5d93a42c783f6 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -92,9 +92,9 @@
     timeout: 7200
 
 - job:
-    name: kayobe-overcloud-centos
+    name: kayobe-overcloud-centos8
     parent: kayobe-overcloud-base
-    nodeset: kayobe-centos
+    nodeset: kayobe-centos8
 
 - job:
     name: kayobe-overcloud-upgrade-base
@@ -112,9 +112,9 @@
     attempts: 3
 
 - job:
-    name: kayobe-overcloud-upgrade-centos
+    name: kayobe-overcloud-upgrade-centos8
     parent: kayobe-overcloud-upgrade-base
-    nodeset: kayobe-centos
+    nodeset: kayobe-centos8
 
 - job:
     name: kayobe-seed-base
@@ -128,9 +128,9 @@
     timeout: 5400
 
 - job:
-    name: kayobe-seed-centos
+    name: kayobe-seed-centos8
     parent: kayobe-seed-base
-    nodeset: kayobe-centos
+    nodeset: kayobe-centos8
 
 - job:
     name: kayobe-seed-upgrade-base
@@ -148,6 +148,6 @@
     attempts: 3
 
 - job:
-    name: kayobe-seed-upgrade-centos
+    name: kayobe-seed-upgrade-centos8
     parent: kayobe-seed-upgrade-base
-    nodeset: kayobe-centos
+    nodeset: kayobe-centos8
diff --git a/zuul.d/nodesets.yaml b/zuul.d/nodesets.yaml
index 04067f11945daca736905f2b9fb506dca3b74781..96d75a90c059321d7d4ef70f00f783b50df0dffb 100644
--- a/zuul.d/nodesets.yaml
+++ b/zuul.d/nodesets.yaml
@@ -4,3 +4,9 @@
     nodes:
       - name: primary
         label: centos-7
+
+- nodeset:
+    name: kayobe-centos8
+    nodes:
+      - name: primary
+        label: centos-8
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 74d01e5de9a400fcedeff16a5aae72200d13c83c..5b059ae2d9e5aaa8b2061c8d2cd3c9dc97350cdc 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -10,10 +10,12 @@
         - kayobe-tox-ansible-syntax
         - kayobe-tox-ansible
         - kayobe-tox-molecule
-        - kayobe-overcloud-centos
-        - kayobe-overcloud-upgrade-centos
-        - kayobe-seed-centos
-        - kayobe-seed-upgrade-centos
+        - kayobe-overcloud-centos8
+        # TODO(mgoddard): Enable upgrade jobs when CentOS 8 support in Train.
+        # - kayobe-overcloud-upgrade-centos8
+        - kayobe-seed-centos8
+        # TODO(mgoddard): Enable upgrade jobs when CentOS 8 support in Train.
+        # - kayobe-seed-upgrade-centos8
 
     gate:
       queue: kayobe
@@ -21,7 +23,9 @@
         - kayobe-tox-ansible-syntax
         - kayobe-tox-ansible
         - kayobe-tox-molecule
-        - kayobe-overcloud-centos
-        - kayobe-overcloud-upgrade-centos
-        - kayobe-seed-centos
-        - kayobe-seed-upgrade-centos
+        - kayobe-overcloud-centos8
+        # TODO(mgoddard): Enable upgrade jobs when CentOS 8 support in Train.
+        # - kayobe-overcloud-upgrade-centos8
+        - kayobe-seed-centos8
+        # TODO(mgoddard): Enable upgrade jobs when CentOS 8 support in Train.
+        # - kayobe-seed-upgrade-centos