0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Fedora で作る PC クラスター part1

Last updated at Posted at 2025-04-09

概要

1台ごとに計算ソフトをインストールし、環境構築を行という面倒を解消するために、Fedora 40 server edition で PC クラスターを作成した際のログ。
使用するソフトは、Gaussian16、Gromacs、Amber、AlphaFold3。
セットアップの流れは、以下の通り。

  1. HDD のマウント
  2. ネットワーク設定
  3. Ansible の設定
  4. NFS の設定
  5. LDAP の設定
  6. SSSD の設定
  7. SLURM のインストール
  8. Singularityを導入し、コンテナを共有ディレクトリに配置
  9. ユーザー管理
  10. テストジョブ
  11. バックサーバーの設定

Part 1 では、NFS の設定までを行う。

検証環境

PC_cluster.png

ヘッドノートは、各計算機からのデータの I/O と Slurm の制御を行うため、コア数の多い CPU が好ましい。バックアップノードは負荷が低いため、性能の低い CPU で十分。

・ヘッドノード(1台)
AMD Ryzen Threadripper 3990x (64core/128thread)
RAM 128GB
M.2 SSD 4TB + HDD 18TB x 2 (RAID 0)

・バックアップノード(1台)
Intel core i7-7700 (4core/8thread)
RAM 128GB
SSD 1TB + HDD 18TB x 2 (RAID 0)
Fedora 40 server edition

・計算ノード(7台)
AMD Ryzen 9 9950x or 7950x (16core/32thread)
RAM 96GB
M.2 SSD 2TB
GPU: RTX A4000 or A6000 or RX 4080 super
Fedora 40 server edition

・スイッチ
NETGEAR 卓上型コンパクト アンマネージスイッチングハブ GS316 ギガビット 16ポート

STEP.1 HDD のマウント

ヘッドノード、バックアップノードともに M.2 SSD にシステムをインストールした。18TB HDD 2 台、マウントしてストレージとして使用する。

まずは、ヘッドノードを設定する。

lsblk

# 以下のように表示される。
NAME              MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                 8:0    0 16.4T  0 disk 
├─sda1              8:1    0  600M  0 part 
├─sda2              8:2    0    1G  0 part 
└─sda3              8:3    0 16.4T  0 part 
sdb                 8:16   0 16.4T  0 disk 
└─sdb1              8:17   0 16.4T  0 part 
zram0             252:0    0    8G  0 disk [SWAP]
nvme0n1           259:0    0  3.6T  0 disk 
├─nvme0n1p1       259:1    0  600M  0 part /boot/efi
├─nvme0n1p2       259:2    0    1G  0 part /boot
└─nvme0n1p3       259:3    0  3.6T  0 part 
  └─fedora00-root 253:0    0  3.6T  0 lvm  /

この場合、バックアップ用の HDD は、/dev/sda と /dev/sdb で、システム用 SSD は /dev/nvme0n1 となる。

sudo dnf install mdadm
sudo mdadm --create --verbose /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdb
sudo mkfs.ext4 /dev/md0
sudo mkdir -p /mnt/data
sudo mount /dev/md0 /mnt/data  # マウントを実行
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm.conf  # RAID 情報を保存
sudo blkid /dev/md0
# 以下のように表示される
# /dev/md0: UUID="dd2ffc42-3098-4570-b068-75dab35f5e61" BLOCK_SIZE="4096" TYPE="ext4"

# 自動マウント設定(fstab)
sudo vi /etc/fstab
# 以下の情報を書き込む
# UUID=dd2ffc42-3098-4570-b068-75dab35f5e61 /mnt/data   ext4   defaults,nofail   0 0

<注意>
nofail をつけておかないと、再起動時に emergency mode になってしまうことがある。
nofail は、起動時にこのディスクが見つからなくても emergency mode に入らず、正常起動するようにとの意味。

# マウントを確認する
sudo umount /mnt/data
sudo systemctl daemon-reload
sudo mount -a
# 何もコメントが出なければ成功!

# RAID ステータスを確認
cat /proc/mdstat

次に、バックアップノードを設定する

# HDD の接続名を調べる
lsblk

NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda               8:0    0  16.4T  0 disk 
└─sda1            8:1    0  16.4T  0 part 
sdb               8:16   0 931.5G  0 disk 
├─sdb1            8:17   0   600M  0 part /boot/efi
├─sdb2            8:18   0     1G  0 part /boot
└─sdb3            8:19   0 929.9G  0 part 
  └─fedora-root 253:0    0 929.9G  0 lvm  /
sdc               8:32   0  16.4T  0 disk 
└─sdc1            8:33   0  16.4T  0 part 
zram0           252:0    0     8G  0 disk [SWAP]

この場合、バックアップ用の HDD は、/dev/sda と /dev/sdc で、システム用 SSD は /dev/sdb となる。

ディスクを初期化して、設定を行う。

sudo dnf install mdadm
sudo mdadm --create --verbose /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdc
sudo mkfs.ext4 /dev/md0
# マウントポイントの作成
sudo mkdir -p /mnt/backup
sudo mount /dev/md0 /mnt/backup
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm.conf
sudo blkid /dev/md0

# UUID を確認する
sudo blkid /dev/md0
# 以下のように表示される
# /dev/md0: UUID="232bfdc2-0f94-4563-84b2-24c98ca8c22c" BLOCK_SIZE="4096" TYPE="ext4"

# 次に /etc/fstab に UUID を書き込む
sudo vi /etc/fstab
# 以下の情報を /etc/fstab に書き込む。terminal 用のコマンドではない。
UUID=232bfdc2-0f94-4563-84b2-24c98ca8c22c   /mnt/backup   ext4   defaults   0 0

# 確認
sudo umount /mnt/backup
systemctl daemon-reload
sudo mount -a
# 何もメッセージが出なければ成功!

STEP.2 ネットワーク設定

計算ノードは静的 IP(固定IP)にする。
ip アドレスの情報は、/etc/hosts に書き込む。

各計算ノードで固定 ip アドレスを設定する手順は以下。

# デバイス名を確認
nmcli device

# 以下のように表示される
DEVICE        TYPE      STATE                   CONNECTION 
enp69s0       ethernet  connected               enp69s0    
lo            loopback  connected (externally)  lo         
eno1          ethernet  disconnected            --         
wlo2          wifi      disconnected            --         
p2p-dev-wlo2  wifi-p2p  disconnected            --   

enp69s0 がインターネットに接続されている LAN ポートで、eno1 がクラスター内通信用の LAN ポートである。
単にヘッドノードと計算ノードを繋いでも disconnected と表示されてしまう。
そこで、クラスター内通信用として static IP を設定する。

# ヘッドノード
# eno1 の部分は、nmcli device で確認したデバイス名に変える
sudo nmcli connection add type ethernet ifname eno1 con-name cluster-net ip4 192.168.17.1/24
sudo nmcli connection up cluster-net

nmcli device
# 以下のように表示される
DEVICE        TYPE      STATE                   CONNECTION  
enp69s0       ethernet  connected               enp69s0     
eno1          ethernet  connected               cluster-net 
lo            loopback  connected (externally)  lo          
wlo2          wifi      disconnected            --          
p2p-dev-wlo2  wifi-p2p  disconnected            --  

続いて、計算ノードの設定を行う。
192.168.17.1, 192.168.17.2, 192.168.17.3 のように割り当てていく。

# 計算ノード
nmcli device
# enp5s0 の部分は、nmcli device で確認したデバイス名にする。以下の例では、192.168.17.4 に設定している。
sudo nmcli connection add type ethernet ifname enp5s0 con-name cluster-net \
  ip4 192.168.17.4/24
sudo nmcli connection up cluster-net

もし設定を間違えた場合は、以下のように設定を削除する。

nmcli connection show
# UUID を確認する。例えば、以下のように表示される。
# cluster-net  d9674e33-19f9-4b20-9b5f-e01e8e4f2066  ethernet  eno1 
# 以下のコマンドで削除する。
sudo nmcli connection delete uuid d9674e33-19f9-4b20-9b5f-e01e8e4f2066
# 接続プロファイル名を確認
nmcli connection show
# ip アドレスを設定
sudo nmcli connection modify "Wired connection 1" ipv4.addresses 192.168.100.10/24
sudo nmcli connection modify "Wired connection 1" ipv4.gateway 192.168.100.1
sudo nmcli connection modify "Wired connection 1" ipv4.dns "192.168.100.1"
sudo nmcli connection modify "Wired connection 1" ipv4.method manual
# ネットワーク再起動
sudo nmcli connection down "Wired connection 1" && sudo nmcli connection up "Wired connection 1"

続いて /etc/hosts の設定を行う。
ヘッドノートと全ての計算ノードの /etc/hosts に以下のように記述
以下は、計算ノード tableaux_02 の例

# hostname の設定
127.0.1.1    tableaux_02

# 計算クラスターの設定
192.168.17.100  rachmaninov
192.168.17.1    tableaux_01
192.168.17.2    tableaux_02
192.168.17.3    tableaux_03
192.168.17.4    tableaux_04
192.168.17.5    tableaux_05
192.168.17.6    tableaux_06
192.168.17.7    tableaux_07
192.168.17.8    tableaux_08
192.168.17.9    tableaux_09
192.168.17.10   tableaux_10

...

また以下のコマンドを実行して、hostname を切り替える。

# tableaux_02の部分は、それぞれの計算ノード名に変える。
sudo hostnamectl set-hostname tableaux_02
# terminal の表示が、
# odyssey@localhost:~$ から
# odyssey@tableaux02:~$ に変わる

STEP.3 Ansible の設定

それぞれのノードにログインして設定を行うのは手間がかかるので、Ansible を用いて一括設定する。

ヘッドノードで以下を実行。

sudo dnf install ansible -y

# Ansible のバージョンを確認する
ansible --version

# ansible の
sudo mkdir -p /etc/ansible
sudo vi /etc/ansible/hosts

# 以下の内容を追記していく
[cluster]
tableaux_01 ansible_host=192.168.17.1
tableaux_02 ansible_host=192.168.17.2
tableaux_03 ansible_host=192.168.17.3
tableaux_04 ansible_host=192.168.17.4
tableaux_05 ansible_host=192.168.17.5
tableaux_08 ansible_host=192.168.17.8
tableaux_09 ansible_host=192.168.17.9

[cluster:vars]
ansible_user=odyssey
ansible_ssh_private_key_file=/home/odyssey/.ssh/id_rsa

クラスター間での公開鍵認証設定を行う。

ssh-keygen -t rsa -b 4096
# パスワードは入力しない。empty のまま。

# 各計算ノードに公開鍵を配布する
ssh-copy-id odyssey@tableaux_01
ssh-copy-id odyssey@tableaux_02
...

# 以下のコマンドで問題ないことを確認する
ansible cluster -m ping

Playbookの作成は以下のように行う

vi update_nodes.yml

以下の内容を update_nodes.yml に書き込む。
以下の内容は、書き方の例であり、このまま実行するとエラーが起きる。

# ソフトウェアのインストール
---
- name: Update all cluster nodes
  hosts: cluster
  become: true
  tasks:
    - name: Update DNF package cache
      dnf:
        update_cache: yes
    
    - name: Upgrade all packages
      dnf:
        name: "*"
        state: latest

# ファイルの配布
---
- name: Deploy configuration files
  hosts: cluster
  become: true
  tasks:
    - name: Copy configuration file
      copy:
        src: /path/to/local/config.conf
        dest: /etc/application/config.conf
        owner: root
        group: root
        mode: '0644'

# ユーザー管理
---
- name: Setup users on cluster
  hosts: cluster
  become: true
  tasks:
    - name: Add cluster user
      user:
        name: cluster_user
        shell: /bin/bash
        groups: wheel
        append: yes


ヘッドノードで以下の設定を行う。

mkdir ~/cluster-setup
cd ~/cluster-setup

この中に、以下のようにファイルを置く。

cluster-setup/
├── ansible.cfg
├── inventory.ini
├── playbooks/
│   ├── hosts.yml
│   ├── nfs_client.yml
│   ├── ldap_sssd.yml
│   └── slurm.yml
├── templates/
│   └── hosts.j2
├── files/
│   ├── slurm.conf
│   └── sssd.conf

~/cluster-setup/ansible.cfg の中身

[defaults]
inventory = inventory.ini
host_key_checking = False
remote_user = odyssey
timeout = 60

inventory.ini の中身

[compute]
tableaux_01
tableaux_02
tableaux_03
tableaux_04
tableaux_05
tableaux_06
tableaux_07
tableaux_08
tableaux_09
tableaux_10

Ansible で /etc/hosts を配布する場合

templates/hosts.j2 の中身

127.0.0.1   localhost
127.0.1.1   {{ inventory_hostname }}

192.168.17.100  rachmaninov
192.168.17.1    tableaux_01
192.168.17.2    tableaux_02
192.168.17.3    tableaux_03
192.168.17.4    tableaux_04
192.168.17.5    tableaux_05
192.168.17.6    tableaux_06
192.168.17.7    tableaux_07
192.168.17.8    tableaux_08
192.168.17.9    tableaux_09
192.168.17.10   tableaux_10

playbooks/hosts.yml の中身

- name: Deploy /etc/hosts to all compute nodes
  hosts: compute
  become: yes
  tasks:
    - name: Copy /etc/hosts file
      template:
        src: templates/hosts.j2
        dest: /etc/hosts
        owner: root
        group: root
        mode: '0644'

Ansible で NFS クライアント設定

~/cluster-setup/playbooks/nfs_client.yml の中身

- name: Configure NFS client on compute nodes
  hosts: compute
  become: yes
  tasks:

    - name: Install NFS utilities
      package:
        name: nfs-utils
        state: present

    - name: Create mount point directory
      file:
        path: /mnt/data
        state: directory
        owner: root
        group: root
        mode: '0755'

    - name: Ensure NFS mount entry in /etc/fstab
      lineinfile:
        path: /etc/fstab
        line: "rachmaninov:/mnt/data  /mnt/data  nfs  defaults  0  0"
        state: present
        create: yes

    - name: Mount NFS share
      mount:
        path: /mnt/data
        src: "rachmaninov:/mnt/data"
        fstype: nfs
        state: mounted

STEP.4 NFS の設定

ヘッドノード側での設定

sudo dnf install -y nfs-utils
sudo nano /etc/exports

/etc/exports には以下の内容を記述

/mnt/data  192.168.17.0/24(rw,sync,no_root_squash)
# NFSサービスを有効化・起動
sudo systemctl enable --now nfs-server
sudo exportfs -rav
# 動作確認
showmount -e localhost

# 以下のように表示される
# Export list for localhost:
# /mnt/data 192.168.17.0/24

計算ノードの設定は Ansible を利用して行う。

  1. nfs-utils のインストール
  2. /mnt/data ディレクトリ作成
  3. /etc/fstab に NFSマウント設定を追記
  4. 実際に /mnt/data をマウント

ファイル構成

cluster-setup/
├── ansible.cfg
├── inventory.ini
├── playbooks/
│   └── nfs_client.yml

~/cluster-setup/playbooks/nfs_client.yml

- name: Configure NFS client on compute nodes
  hosts: compute
  become: yes
  tasks:

    - name: Install NFS utilities
      package:
        name: nfs-utils
        state: present

    - name: Create mount point directory
      file:
        path: /mnt/data
        state: directory
        owner: root
        group: root
        mode: '0755'

    - name: Ensure NFS mount entry in /etc/fstab
      lineinfile:
        path: /etc/fstab
        line: "rachmaninov:/mnt/data  /mnt/data  nfs  defaults  0  0"
        state: present
        create: yes

    - name: Mount NFS share
      mount:
        path: /mnt/data
        src: "rachmaninov:/mnt/data"
        fstype: nfs
        state: mounted

まだ準備中の計算ノードがある場合は、inventory.ini で対象のノードをコメントアウトしておく。

以下のコマンドで Ansible による NFS の設定を実行。

# 実行時に計算ノードでのパスワードを聞かれる。
ansible-playbook playbooks/nfs_client.yml --ask-become-pass -e ansible_become_flags='-E'

成功すると以下のように表示される。
この操作では、各ノード dnf 経由で nfs-utils をインストールするので、インターネット接続がないとエラーが起きてしまう。

PLAY [Configure NFS client on compute nodes] **************************************************

TASK [Gathering Facts] ************************************************************************
ok: [tableaux_03]
ok: [tableaux_01]
ok: [tableaux_02]
ok: [tableaux_05]
ok: [tableaux_04]
ok: [tableaux_09]
ok: [tableaux_08]

TASK [Install NFS utilities] ******************************************************************
ok: [tableaux_03]
ok: [tableaux_02]
ok: [tableaux_04]
ok: [tableaux_01]
ok: [tableaux_05]
ok: [tableaux_08]
ok: [tableaux_09]

TASK [Create mount point directory] ***********************************************************
ok: [tableaux_04]
ok: [tableaux_03]
ok: [tableaux_02]
ok: [tableaux_05]
ok: [tableaux_01]
ok: [tableaux_09]
ok: [tableaux_08]

TASK [Ensure NFS mount entry in /etc/fstab] ***************************************************
ok: [tableaux_04]
ok: [tableaux_03]
ok: [tableaux_02]
ok: [tableaux_05]
ok: [tableaux_01]
ok: [tableaux_09]
ok: [tableaux_08]

TASK [Mount NFS share] ************************************************************************
changed: [tableaux_02]
changed: [tableaux_05]
changed: [tableaux_03]
changed: [tableaux_04]
changed: [tableaux_01]
changed: [tableaux_09]
changed: [tableaux_08]

PLAY RECAP ************************************************************************************
tableaux_01                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_02                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_03                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_04                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_05                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_08                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
tableaux_09                : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

各計算ノードで df -h で確認すると以下のように rachmaninov:/mnt/data が表示される。

df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/fedora-root  3.7T  723G  3.0T  20% /
devtmpfs                 4.0M     0  4.0M   0% /dev
tmpfs                     16G     0   16G   0% /dev/shm
efivarfs                 256K   58K  194K  23% /sys/firmware/efi/efivars
tmpfs                    6.3G  1.9M  6.3G   1% /run
/dev/nvme0n1p2           960M  653M  308M  68% /boot
tmpfs                     16G     0   16G   0% /tmp
/dev/nvme0n1p1           599M  7.6M  592M   2% /boot/efi
tmpfs                    3.2G   12K  3.2G   1% /run/user/1000
rachmaninov:/mnt/data     33T  2.0M   31T   1% /mnt/data
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?