Installing Confluent Server (successor of xCAT) and deploying Rocky Linux 9.8 with Ansible integration

Posted on Wed 30 September 2026 by Pavlo Khmel

Confluent is the modern successor of xCAT. Example in this article shows how to install and configure confluent server. And it also shows how to star Ansible playbooks to complete server configuration after operation system deployment by confluent.

  • Confluent server: 10.1.254.100
  • Ansible server: 10.1.254.5

NOTE: It is possible to start Ansible playbooks from confluent server directly. This article shows example with remote server and adding SSH public key.

Add repository

Check current repository: https://xcat2.github.io/confluent-docs/downloads/

Current command I used for Rocky Linux 9.8:

rpm -ivh https://hpc.lenovo.com/yum/latest/el9/x86_64/lenovo-hpc-yum-1-1.x86_64.rpm

Install and start services

dnf -y install lenovo-confluent tftp-server ansible-core
systemctl enable confluent
systemctl enable httpd
systemctl enable tftp.socket
systemctl start confluent
systemctl start httpd
systemctl start tftp.socket

NOTE: /etc/hosts - is edited manually

10.1.11.19  node-11-19

Or /etc/hosts can be updated with confluent command:

confluent2hosts everything -a

Configure confluent and add first server

nodegroupattrib everything deployment.useinsecureprotocols=firmware console.method=ipmi dns.servers=10.1.0.1 dns.domain=my.hpc.local net.ipv4_gateway=10.1.0.1
nodegroupattrib everything bmcuser=ipmi bmcpass='{{ user_ipmi_password }}'
nodedefine node-11-19 bmc=10.2.11.19 net.hwaddr=18:66:da:aa:dd:b9 net.ipv4_address=10.1.11.19/16
mkdir /var/log/ansible
chown confluent /var/log/ansible
osdeploy import Rocky-9.8-x86_64-minimal.iso
cp -a /var/lib/confluent/public/os/rocky-9.8-x86_64-default /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal
osdeploy initialize -i
nodegroupattrib everything -p crypted.rootpassword
ssh-keygen -t ed25519
sudo -u confluent -s /bin/bash
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
ssh-copy-id root@10.1.254.5
exit

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/ansible/firstboot.d/99-trigger-ansible-server.yml

- name: Trigger Dedicated Ansible Server
  hosts: all
  vars:
    ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
  gather_facts: false
  tasks:
    - name: Run remote playbook on Ansible server
      ansible.builtin.shell: >
        ssh -o BatchMode=yes -o StrictHostKeyChecking=no root@10.1.254.5
        "ansible-playbook -i /opt/ansible/inventory --vault-password-file /etc/ansible/vault_pass.txt /opt/ansible/node.yml --limit {{ inventory_hostname }}"
        | tee /var/log/ansible/{{ inventory_hostname }}.log
      delegate_to: localhost

    - name: Reboot and wait for the server to come back
      ansible.builtin.reboot:
        msg: "Ansible is rebooting the system"
        reboot_timeout: 600
        post_reboot_delay: 30
        test_command: "whoami"

Add "text" in the first line to enable text instead of GUI install process.

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/kickstart

text
....
....

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/kickstart.custom

firewall --disabled
selinux --disabled

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/packagelist

@^minimal-environment

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/partitioning

clearpart --all --initlabel
ignoredisk --only-use=%%INSTALLDISK%%
# Automatically creates required boot partitions (EFI)
reqpart
# /boot must be a plain partition, not LVM
part /boot --fstype="xfs" --ondisk=%%INSTALLDISK%% --size=1024
# Create Physical Volume using all remaining disk space
part pv.01 --fstype="lvmpv" --ondisk=%%INSTALLDISK%% --size=1 --grow
# Create Volume Group
volgroup vg_root pv.01
# Create Root LV filling 100% of the Volume Group
logvol / --fstype="xfs" --vgname=vg_root --size=1 --grow --name=root %%LUKSHOOK%%

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/profile.yaml

label: Rocky Linux 9.8 Minimal
kernelargs: quiet console=tty0 console=ttyS0,115200
installedargs: quiet console=tty0 console=ttyS0,115200

NOTE: it can be tty1 and ttyS1 on different hardware.

(Optional) vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/scripts/post.custom

. /etc/confluent/functions
ib_count=`nmcli -p dev show | grep -B 2 infiniband | grep GENERAL.DEVICE | awk {'first = $1; $1=""; print $0'}|sed 's/^ //g' | wc -l`
first_ib_mac_long=`ip a | grep infiniband | head -n 1 | awk '{print $2}'`
first_ib_mac=${first_ib_mac_long: -23}
second_ib_pci=`lspci | grep -i mel | tail -n 1 | awk '{print $1}'`
echo "SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"?*${first_ib_mac}\",ATTR{type}==\"32\",NAME=\"ib0\"" > /etc/udev/rules.d/71-rename-ib.rules
if [[ "$ib_count" -eq "2" ]]
then
    echo "SUBSYSTEM==\"pci\",ACTION==\"add\",RUN=\"/bin/sh -c 'echo 1 > /sys/bus/pci/devices/0000:${second_ib_pci}/remove'\"" > /etc/udev/rules.d/72-delete-second-ib.rules
fi

Add line to allow root login.

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/scripts/setupssh.sh

. . .
echo PermitRootLogin yes >> $targssh
. . .

vi /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/scripts/firstboot.d/ansible.sh

#!/bin/sh
echo "ssh-rsa AAAAB3Nz.......RO+Xkvc= root@ansible" >> /root/.ssh/authorized_keys

Change permission, regenerates and updates the network boot files:

chmod +x /var/lib/confluent/public/os/rocky-9.8-x86_64-minimal/scripts/firstboot.d/ansible.sh
osdeploy updateboot rocky-9.8-x86_64-minimal
osdeploy list

Deploy first server

nodedeploy node-11-19 -n rocky-9.8-x86_64-minimal
nodeconsole node-11-19

(Optional) Add user to Web interface

confetty create /users/demouser role=admin
useradd demouser
passwd demouser

https://10.1.254.100/lenovo-confluent/

(Optional) How to update kernel

Copy new RPMs to /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/

Example with kernel-5.14.0-687.50.1.el9_8.x86_64.rpm

cp kernel-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-core-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-modules-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-modules-core-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-modules-extra-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-tools-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/
cp kernel-tools-libs-5.14.0-687.50.1.el9_8.x86_64.rpm /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/Packages/k/

Update local repo

dnf install -y createrepo_c
cd /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/
createrepo_c --update .
chown -R confluent:confluent /var/lib/confluent/distributions/rocky-9.8-x86_64/Minimal/
osdeploy updateboot rocky-9.8-x86_64-minimal

(optional) DNS and DHCP serveice - dnsmasq

Confluent only responds to nodes defined in its database. Use dnsmasq if confluent server needs to act as DNS and DHCP. dnsmasq is reading /etc/hosts for DNS. Example:

yum install dnsmasq

File /etc/dnsmasq.conf

bind-dynamic
dhcp-range=10.1.222.1,10.1.222.100

Enable and start

systemctl enable dnsmasq --now