2492 words
12 minutes
Deploying OpenStack with Ceph Tentacle: A 3-Node Converged Setup Guide

In this guide, I’ll walk you through deploying a fully functional OpenStack cloud platform integrated with Ceph Tentacle as the distributed storage backend — all on a 3-node converged cluster running Ubuntu Noble 24.04.

Ceph Logo + OpenStack Logo

This setup uses Kolla-Ansible for deploying OpenStack services as Docker containers, and cephadm for bootstrapping the Ceph cluster. By the end of this guide, you’ll have a working private cloud with:

  • ☁️ OpenStack — Keystone, Glance, Nova, Neutron, Cinder, Horizon
  • 💾 Ceph — Distributed storage for images, volumes, VMs, and backups
  • 🌐 Networking — Provider + tenant networks with floating IPs
  • 🖥️ VM Instances — Running CirrOS test instances with SSH access

Table of Contents#

  1. Topology & Specifications
  2. Node Preparation
  3. Deploy Ceph Tentacle with cephadm
  4. Ceph Pool & Keyring Setup for OpenStack
  5. Install Kolla-Ansible
  6. Kolla-Ansible Configuration
  7. External Ceph Integration with Kolla-Ansible
  8. Deploy OpenStack
  9. OpenStack Network Setup
  10. Create VM Instance
  11. Verify VM Connectivity

1. Topology & Specifications#

Network Topology#

┌──────────────────┐
│ Proxmox Host │
│ vmbr0 (eno1) │
│ 192.168.205.253 │
└────────┬─────────┘
┌─────────────────┼─────────────────┐
│ │ │
ens18 (Mgmt) ens18 (Mgmt) ens18 (Mgmt)
192.168.205.101 192.168.205.102 192.168.205.103
ens19 (Provider) ens19 (Provider) ens19 (Provider)
(no IP) (no IP) (no IP)
│ │ │
┌─────────────────┐ ┌──────────────┐ ┌──────────────┐
│ ops-ceph-ctrl │ │ops-ceph-comp1│ │ops-ceph-comp2│
│ (controller) │ │ (compute) │ │ (compute) │
│ │ │ │ │ │
│ /dev/sda (OS) │ │ /dev/sda(OS) │ │ /dev/sda(OS) │
│ /dev/sdb OSD.0 │ │ /dev/sdb OSD │ │ /dev/sdb OSD │
│ /dev/sdc OSD.1 │ │ /dev/sdc OSD │ │ /dev/sdc OSD │
│ /dev/sdd OSD.2 │ │ /dev/sdd OSD │ │ /dev/sdd OSD │
└─────────────────┘ └──────────────┘ └──────────────┘

Node Specifications#

Parameterops-ceph-ctrlops-ceph-comp1ops-ceph-comp2
CPU8 vCPU6 vCPU6 vCPU
RAM16 GB12 GB12 GB
Disk OS50 GB /dev/sda50 GB /dev/sda50 GB /dev/sda
Disk OSD3x 25 GB (/dev/sdb,sdc,sdd)3x 25 GB3x 25 GB
NIC 1ens18 → 192.168.205.101/24ens18 → 192.168.205.102/24ens18 → 192.168.205.103/24
NIC 2ens19 → no IPens19 → no IPens19 → no IP
OSUbuntu Noble 24.04Ubuntu Noble 24.04Ubuntu Noble 24.04
Ceph RoleMON, MGR, OSDOSDOSD
OpenStack RoleController, NetworkComputeCompute

2. Node Preparation#

Run the following steps on all nodes unless stated otherwise.

2.1 Set Hostname#

Terminal window
# On ops-ceph-ctrl
hostnamectl set-hostname ops-ceph-ctrl
# On ops-ceph-comp1
hostnamectl set-hostname ops-ceph-comp1
# On ops-ceph-comp2
hostnamectl set-hostname ops-ceph-comp2

2.2 Configure /etc/hosts#

Terminal window
sudo nano /etc/hosts

Add on all nodes:

192.168.205.101 ops-ceph-ctrl
192.168.205.102 ops-ceph-comp1
192.168.205.103 ops-ceph-comp2

2.3 Configure Netplan#

Terminal window
sudo nano /etc/netplan/50-cloud-init.yaml

Example for ops-ceph-ctrl:

network:
version: 2
renderer: networkd
ethernets:
ens18:
addresses:
- 192.168.205.101/24
routes:
- to: default
via: 192.168.205.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
ens19:
dhcp4: false

Adjust IP for comp1 (192.168.205.102) and comp2 (192.168.205.103). ens19 only needs dhcp4: false without an IP — Neutron will use it as the provider interface.

Terminal window
sudo netplan apply

2.4 Install Dependencies#

Terminal window
sudo apt update
sudo apt install -y git curl wget python3-dev python3-venv \
libffi-dev gcc libssl-dev libdbus-glib-1-dev chrony sshpass nano

2.5 Configure Passwordless SSH (from ops-ceph-ctrl)#

Terminal window
# Generate SSH key (ed25519)
ssh-keygen -t ed25519 -C "ops-ceph-ctrl"
# Distribute public key to all nodes including self
ssh-copy-id opsce@ops-ceph-ctrl
ssh-copy-id opsce@ops-ceph-comp1
ssh-copy-id opsce@ops-ceph-comp2

2.6 Set NOPASSWD sudo (all nodes)#

Terminal window
echo "opsce ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/opsce

2.7 Disable Swap & Time Sync#

Terminal window
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
sudo timedatectl set-timezone Asia/Jakarta
sudo systemctl enable --now chrony
chronyc tracking

2.8 Sysctl Configuration#

Terminal window
sudo nano /etc/sysctl.conf

Add:

net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
Terminal window
sudo sysctl -p

2.9 Install Docker#

Terminal window
curl -sL https://get.docker.com | bash
sudo systemctl enable --now docker

3. Deploy Ceph Tentacle with cephadm#

All steps are executed from ops-ceph-ctrl unless stated otherwise.

3.1 Install cephadm#

Terminal window
curl --silent --remote-name --location \
https://download.ceph.com/rpm-tentacle/el9/noarch/cephadm
chmod +x cephadm
sudo install -m 0755 cephadm /usr/local/sbin/cephadm
sudo cephadm add-repo --release tentacle
sudo apt update
sudo apt install -y cephadm

3.2 Bootstrap Ceph Cluster#

Terminal window
sudo cephadm bootstrap \
--mon-ip <your-controller-ip> \
--cluster-network <your-subnet>/24 \
--initial-dashboard-user <dashboard-user> \
--initial-dashboard-password <dashboard-password> \
--allow-overwrite

Verify:

Terminal window
sudo cephadm shell -- ceph -s

3.3 Install ceph-common#

Terminal window
# On ctrl
sudo cephadm install ceph-common
# On comp1 and comp2
ssh -t ops-ceph-comp1 "sudo cephadm add-repo --release tentacle && sudo apt update && sudo apt install -y ceph-common"
ssh -t ops-ceph-comp2 "sudo cephadm add-repo --release tentacle && sudo apt update && sudo apt install -y ceph-common"

3.4 Copy cephadm SSH Key to All Nodes#

Terminal window
sudo cephadm shell -- ceph cephadm get-pub-key | \
sudo tee /etc/ceph/ceph.pub
# Must run as root
sudo su
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ops-ceph-comp1
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ops-ceph-comp2
exit

3.5 Add Nodes to Cluster#

Terminal window
sudo cephadm shell -- ceph orch host add ops-ceph-comp1 192.168.205.102
sudo cephadm shell -- ceph orch host add ops-ceph-comp2 192.168.205.103
# Verify
sudo cephadm shell -- ceph orch host ls

3.6 Deploy OSD#

Terminal window
# ops-ceph-ctrl
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-ctrl:/dev/sdb
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-ctrl:/dev/sdc
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-ctrl:/dev/sdd
# ops-ceph-comp1
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp1:/dev/sdb
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp1:/dev/sdc
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp1:/dev/sdd
# ops-ceph-comp2
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp2:/dev/sdb
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp2:/dev/sdc
sudo cephadm shell -- ceph orch daemon add osd ops-ceph-comp2:/dev/sdd

Tip: Use hostname:/dev/sdX format — not user@hostname:/dev/sdX. The latter causes a “host not found” error. Also, warnings like Not using image... not in the list of non-dangling images are cosmetic and safe to ignore.

3.7 Verify Cluster#

Terminal window
sudo cephadm shell -- ceph -s
sudo cephadm shell -- ceph osd tree
sudo cephadm shell -- ceph df

Make sure all 9 OSDs (3 nodes × 3 disks) are up and in.

Here’s what the Ceph Block Images dashboard looks like after a successful deployment:

Ceph Block Images Dashboard

And the Grafana monitoring dashboard showing cluster health, OSD performance, and resource utilization:

Ceph Grafana Monitoring Dashboard

4. Ceph Pool & Keyring Setup for OpenStack#

4.1 Create Pools#

Terminal window
sudo cephadm shell -- bash -c "
ceph osd pool create volumes
ceph osd pool create images
ceph osd pool create backups
ceph osd pool create vms
rbd pool init volumes
rbd pool init images
rbd pool init backups
rbd pool init vms
"

4.2 Create Keyrings#

Terminal window
sudo cephadm shell -- bash -c "
ceph auth get-or-create client.glance \
mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=images' \
-o /etc/ceph/ceph.client.glance.keyring
ceph auth get-or-create client.cinder \
mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rwx pool=images' \
-o /etc/ceph/ceph.client.cinder.keyring
ceph auth get-or-create client.nova \
mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=vms, allow rx pool=images' \
-o /etc/ceph/ceph.client.nova.keyring
ceph auth get-or-create client.cinder-backup \
mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=backups' \
-o /etc/ceph/ceph.client.cinder-backup.keyring
"

4.3 Export Keyrings to Host#

Terminal window
sudo cephadm shell -- ceph auth get client.glance | sudo tee /etc/ceph/ceph.client.glance.keyring
sudo cephadm shell -- ceph auth get client.cinder | sudo tee /etc/ceph/ceph.client.cinder.keyring
sudo cephadm shell -- ceph auth get client.nova | sudo tee /etc/ceph/ceph.client.nova.keyring
sudo cephadm shell -- ceph auth get client.cinder-backup | sudo tee /etc/ceph/ceph.client.cinder-backup.keyring
sudo chmod 640 /etc/ceph/ceph.client.*.keyring

4.4 Generate ceph.conf#

Terminal window
sudo cephadm shell -- ceph config generate-minimal-conf | sudo tee /etc/ceph/ceph.conf
# Remove leading tabs to prevent kolla-ansible issues
sudo sed -i 's/^\t//' /etc/ceph/ceph.conf
cat /etc/ceph/ceph.conf

5. Install Kolla-Ansible#

Run from ops-ceph-ctrl as user opsce.

5.1 Create Virtual Environment#

Terminal window
python3 -m venv ~/kolla-venv
source ~/kolla-venv/bin/activate
# Auto-activate on login
echo 'source ~/kolla-venv/bin/activate' >> ~/.bashrc

5.2 Install Kolla-Ansible#

Terminal window
pip install -U pip
pip install 'ansible-core>=2.16,<2.17'
pip install docker dbus-python
# Install kolla-ansible from master
pip install git+https://opendev.org/openstack/kolla-ansible@master

5.3 Setup Kolla Directories#

Terminal window
sudo mkdir -p /etc/kolla
sudo chown $USER:$USER /etc/kolla
cp -r ~/kolla-venv/share/kolla-ansible/etc_examples/kolla/* /etc/kolla/
cp ~/kolla-venv/share/kolla-ansible/ansible/inventory/multinode ~/multinode

5.4 Install Ansible Galaxy Dependencies#

Terminal window
kolla-ansible install-deps

6. Kolla-Ansible Configuration#

6.1 Ansible Config#

Terminal window
sudo mkdir -p /etc/ansible
sudo tee /etc/ansible/ansible.cfg <<EOF
[defaults]
host_key_checking = False
pipelining = True
forks = 100
interpreter_python = /usr/bin/python3
EOF

6.2 Multinode Inventory#

Terminal window
nano ~/multinode

Update the top section:

[control]
ops-ceph-ctrl
[network]
ops-ceph-ctrl
[compute]
ops-ceph-comp1
ops-ceph-comp2
[monitoring]
ops-ceph-ctrl
[storage]
ops-ceph-ctrl
ops-ceph-comp1
ops-ceph-comp2
[deployment]
localhost ansible_connection=local

Leave all [xxx:children] groups as default from the template.

Verify:

Terminal window
ansible -i ~/multinode all -m ping

6.3 Generate Passwords#

Terminal window
kolla-genpwd
# Set admin password (replace with your own secure password)
sed -i 's/^keystone_admin_password:.*/keystone_admin_password: <your-password>/' /etc/kolla/passwords.yml

6.4 Configure globals.yml#

Terminal window
nano /etc/kolla/globals.yml
# =====================
# BASE IMAGE
# =====================
kolla_base_distro: "ubuntu"
# =====================
# NETWORKING
# =====================
network_interface: "ens18"
neutron_external_interface: "ens19"
kolla_internal_vip_address: "192.168.205.100"
# =====================
# ENABLE SERVICES
# =====================
enable_openstack_core: "yes"
enable_cinder: "yes"
enable_cinder_backup: "yes"
# =====================
# CEPH INTEGRATION
# =====================
glance_backend_ceph: "yes"
cinder_backend_ceph: "yes"
nova_backend_ceph: "yes"
ceph_glance_user: "glance"
ceph_glance_pool_name: "images"
ceph_cinder_user: "cinder"
ceph_cinder_pool_name: "volumes"
ceph_cinder_backup_user: "cinder-backup"
ceph_cinder_backup_pool_name: "backups"
ceph_nova_user: "nova"
ceph_nova_pool_name: "vms"

kolla_internal_vip_address must be an unused IP in the ens18 subnet. This IP will automatically appear on the ens18 interface of ops-ceph-ctrl after deployment as the HAProxy VIP.


7. External Ceph Integration with Kolla-Ansible#

7.1 Create Directories#

Terminal window
mkdir -p /etc/kolla/config/glance
mkdir -p /etc/kolla/config/nova
mkdir -p /etc/kolla/config/cinder/cinder-volume
mkdir -p /etc/kolla/config/cinder/cinder-backup

7.2 Copy ceph.conf#

Terminal window
cp /etc/ceph/ceph.conf /etc/kolla/config/glance/ceph.conf
cp /etc/ceph/ceph.conf /etc/kolla/config/nova/ceph.conf
cp /etc/ceph/ceph.conf /etc/kolla/config/cinder/ceph.conf

7.3 Copy Keyrings#

Terminal window
# Glance
cp /etc/ceph/ceph.client.glance.keyring \
/etc/kolla/config/glance/ceph.client.glance.keyring
# Nova (needs both nova AND cinder keyrings)
sudo cp /etc/ceph/ceph.client.nova.keyring \
/etc/kolla/config/nova/ceph.client.nova.keyring
sudo cp /etc/ceph/ceph.client.cinder.keyring \
/etc/kolla/config/nova/ceph.client.cinder.keyring
# Cinder Volume
sudo cp /etc/ceph/ceph.client.cinder.keyring \
/etc/kolla/config/cinder/cinder-volume/ceph.client.cinder.keyring
# Cinder Backup
sudo cp /etc/ceph/ceph.client.cinder.keyring \
/etc/kolla/config/cinder/cinder-backup/ceph.client.cinder.keyring
sudo cp /etc/ceph/ceph.client.cinder-backup.keyring \
/etc/kolla/config/cinder/cinder-backup/ceph.client.cinder-backup.keyring

7.4 Fix Ownership & Permissions#

Terminal window
sudo chown -R opsce:opsce /etc/kolla/config
sudo chmod 640 /etc/kolla/config/cinder/cinder-backup/*.keyring
sudo chmod 640 /etc/kolla/config/cinder/cinder-volume/*.keyring
sudo chmod 640 /etc/kolla/config/nova/*.keyring
sudo chmod 640 /etc/kolla/config/glance/*.keyring

7.5 Verify File Structure#

Terminal window
find /etc/kolla/config -type f -printf "%u %p\n" | sort

Expected output (all owned by opsce):

opsce /etc/kolla/config/cinder/ceph.conf
opsce /etc/kolla/config/cinder/cinder-backup/ceph.client.cinder-backup.keyring
opsce /etc/kolla/config/cinder/cinder-backup/ceph.client.cinder.keyring
opsce /etc/kolla/config/cinder/cinder-volume/ceph.client.cinder.keyring
opsce /etc/kolla/config/glance/ceph.conf
opsce /etc/kolla/config/glance/ceph.client.glance.keyring
opsce /etc/kolla/config/nova/ceph.conf
opsce /etc/kolla/config/nova/ceph.client.cinder.keyring
opsce /etc/kolla/config/nova/ceph.client.nova.keyring

8. Deploy OpenStack#

8.1 Bootstrap Servers#

Terminal window
kolla-ansible bootstrap-servers -i ~/multinode

Heads up: It’s common for Ceph MON/MGR services to go inactive dead after this step, since kolla-ansible reconfigures Docker daemon settings. If this happens, a simple sudo reboot on affected nodes is the cleanest fix. After reboot, verify Ceph health with sudo ceph -s before proceeding.

8.2 Pre-checks#

Terminal window
kolla-ansible prechecks -i ~/multinode

8.3 Deploy#

Terminal window
kolla-ansible deploy -i ~/multinode

Expect this to take 20-60 minutes depending on your hardware and network speed. Occasional single-task failures on compute nodes are typically timing-related and generally resolve themselves — verify with openstack compute service list after deployment.

8.4 Post-Deploy#

Terminal window
kolla-ansible post-deploy -i ~/multinode

8.5 Install OpenStack Client & Load Credentials#

Terminal window
pip install python-openstackclient \
-c https://releases.openstack.org/constraints/upper/2025.2
source /etc/kolla/admin-openrc.sh

8.6 Verify Services#

Terminal window
openstack service list
openstack compute service list
openstack network agent list
openstack volume service list

All services should be up. Note that cinder-volume backend shows rbd-1, confirming successful Ceph integration.

Here’s the actual output from a working deployment — all services, network agents, compute services, and volume services are confirmed up:

OpenStack Service List

9. OpenStack Network Setup#

9.1 Create Provider Network (External)#

Terminal window
openstack network create \
--share \
--external \
--provider-physical-network physnet1 \
--provider-network-type flat \
public-net
openstack subnet create \
--network public-net \
--subnet-range 17.19.21.0/24 \
--gateway 17.19.21.254 \
--allocation-pool start=17.19.21.100,end=17.19.21.200 \
--dns-nameserver 8.8.8.8 \
public-subnet

9.2 Create Private/Tenant Network#

Terminal window
openstack network create private-net
openstack subnet create \
--network private-net \
--subnet-range 10.0.0.0/24 \
--gateway 10.0.0.1 \
--dns-nameserver 8.8.8.8 \
private-subnet

9.3 Create Router#

Terminal window
openstack router create main-router
openstack router set main-router --external-gateway public-net
openstack router add subnet main-router private-subnet
# Verify
openstack router show main-router
openstack port list --router main-router

Once the router is created, you can visualize the network topology in Horizon:

OpenStack Network Topology

9.4 Create Security Group#

Terminal window
openstack security group create security-group-net \
--description 'Allow SSH and ICMP'
openstack security group rule create \
--protocol icmp security-group-net
openstack security group rule create \
--protocol tcp --ingress --dst-port 22 security-group-net
openstack security group rule list security-group-net

9.5 Create Floating IP#

Terminal window
openstack floating ip create public-net
openstack floating ip list

Note: Floating IPs are only externally reachable if the provider network interface is bridged to your physical network. In isolated lab environments, you can still access VMs via their private IPs using the Neutron router namespace (see Section 11).


10. Create VM Instance#

10.1 Upload Image#

Terminal window
wget http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img
openstack image create \
--disk-format qcow2 \
--container-format bare \
--public \
--file ./cirros-0.6.2-x86_64-disk.img \
cirros-0.6.2
openstack image list

10.2 Create Keypair#

Terminal window
openstack keypair create \
--public-key ~/.ssh/id_ed25519.pub \
controller-key
openstack keypair list

10.3 Create Flavor#

Terminal window
openstack flavor create \
--ram 512 \
--disk 8 \
--vcpus 1 \
--public \
c1-small
openstack flavor list

10.4 Create Instance#

Terminal window
# First instance
openstack server create \
--flavor c1-small \
--image cirros-0.6.2 \
--key-name controller-key \
--security-group security-group-net \
--network private-net \
cirros-instance-test
# Second instance (for inter-VM connectivity test)
openstack server create \
--flavor c1-small \
--image cirros-0.6.2 \
--key-name controller-key \
--security-group security-group-net \
--network private-net \
cirros-instance-test-2
# Check status
openstack server list

Wait until status is ACTIVE.

10.5 Assign Floating IP#

Terminal window
# List available floating IPs
openstack floating ip list
# Assign to each instance
openstack server add floating ip cirros-instance-test <floating-ip-1>
openstack server add floating ip cirros-instance-test-2 <floating-ip-2>
# Verify — instances should have 2 IPs (private + floating)
openstack server list

Here’s what it looks like in Horizon — both instances are Active and Running with their private and floating IPs assigned:

OpenStack Instances in Horizon

And the detailed server list from the CLI, confirming Ceph-backed storage and network connectivity:

OpenStack Server List and Details

11. Verify VM Connectivity#

11.1 Check Router Namespace#

Terminal window
# List all namespaces
sudo ip netns list
# Output: qrouter-xxx (id: N), qdhcp-xxx (id: N)

11.2 Ping VM from Namespace#

Terminal window
# Replace <router-id> with the ID from ip netns list output
sudo ip netns exec qrouter-<router-id> ping -c 4 10.0.0.71
sudo ip netns exec qrouter-<router-id> ping -c 4 10.0.0.104

11.3 SSH to VM from Namespace#

Terminal window
# SSH using key (recommended)
sudo ip netns exec qrouter-<router-id> ssh -i ~/.ssh/id_ed25519 cirros@10.0.0.71
# Or SSH with password (cirros password: gocubsgo)
sudo ip netns exec qrouter-<router-id> ssh cirros@10.0.0.71

11.4 Test Inter-VM Connectivity#

From inside cirros-instance-test, ping the other VM:

Terminal window
# Enter the first VM
sudo ip netns exec qrouter-<router-id> ssh cirros@10.0.0.71
# From inside the VM, ping the second VM
ping 10.0.0.104

Note: You cannot ping VMs directly from the controller host — there’s no route to the tenant or provider networks from the host’s default namespace. Always use sudo ip netns exec qrouter-<id> to access VM networks from the controller.

11.5 Verify OVS Bridge#

Terminal window
sudo docker exec openvswitch_vswitchd ovs-vsctl show

Verify:

  • br-ex has port ens19
  • br-int has qr-xxx (router port) and tap-xxx (VM port)
  • All bridge controllers show is_connected: true

Troubleshooting#

MON/MGR dies after bootstrap-servers#

kolla-ansible reconfigures Docker settings which can prevent Ceph containers from restarting. A sudo reboot is the cleanest fix. Alternatively, manually start the services:

Terminal window
sudo systemctl start ceph-<fsid>@mon.<hostname>.service
sudo systemctl start ceph-<fsid>@mgr.<hostname>.<id>.service

Error “host not found” when adding OSD#

Use hostname:/dev/sdX format — not user@hostname:/dev/sdX:

Terminal window
# CORRECT
sudo cephadm shell -- ceph orch daemon add osd <hostname>:/dev/sdb
# WRONG
sudo cephadm shell -- ceph orch daemon add osd user@<hostname>:/dev/sdb

Warning “Not using image… non-dangling images”#

Cosmetic warning, not an error. Safe to ignore.

kolla-ansible: command not found#

Ensure the Python virtual environment is activated:

Terminal window
source ~/kolla-venv/bin/activate
which kolla-ansible

Missing sudo password during bootstrap-servers#

Ensure passwordless sudo is configured for your deploy user:

Terminal window
echo "<user> ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/<user>

ceph.conf with leading tabs#

Kolla-ansible may fail to parse ceph.conf if it contains tabs. Strip them:

Terminal window
sudo sed -i 's/^\t//' /etc/kolla/config/*/ceph.conf

Cannot ping VM directly from controller#

This is expected — the host has no route to tenant/provider networks. Use the Neutron router namespace:

Terminal window
sudo ip netns list
sudo ip netns exec qrouter-<id> ping -c 4 <vm-ip>

References#


This guide is based on a real-world deployment. Adjust IPs, hostnames, credentials, and disk paths to match your own environment.

Deploying OpenStack with Ceph Tentacle: A 3-Node Converged Setup Guide
https://im-gatan.com/posts/openstack-ceph-deployment/
Author
Gatan
Published at
2026-06-18
License
CC BY-NC-SA 4.0