> ## Documentation Index
> Fetch the complete documentation index at: https://testdocs.riad.com.bd/llms.txt
> Use this file to discover all available pages before exploring further.

# Complete Ubuntu VM Setup with LVM Storage and NFS Shares

> A comprehensive guide to setting up an Ubuntu virtual machine with LVM storage and NFS shares.

## Introduction

Setting up an Ubuntu virtual machine (VM) with Logical Volume Management (LVM) storage and  Network File System (NFS) shares can enhance your system's flexibility and scalability. This guide provides a step-by-step approach to configuring an Ubuntu VM with LVM for efficient storage management and NFS for sharing files across the network.

<Info>
  **Prerequisites**

  Before you begin, ensure you have the following prerequisites:

  * A preferred virtualization platform (e.g., VirtualBox, VMware, KVM).
  * An Ubuntu ISO image for installation.
  * Basic knowledge of Linux command line and system administration.
</Info>

## Server Setup

<Steps>
  <Step title="Installing Ubuntu VM">
    1. Create a new virtual machine in your chosen virtualization platform.
    2. Allocate sufficient resources (CPU, RAM, Disk Space) based on your requirements.
    3. Mount the Ubuntu ISO image and start the VM.
    4. Follow the on-screen instructions to install Ubuntu, ensuring you set up a user account and password.
    5. In the installation process keep the unallocated or free space as it is.
    6. Complete the installation and reboot the VM.
  </Step>

  <Step title="Enable remote root access">
    Open a terminal in your Ubuntu VM and use the below command to set the root password:

    ```bash theme={null}
    sudo passwd root
    ```
  </Step>

  <Step title="Command to enable remote root login">
    ```bash theme={null}
    sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
    sudo systemctl restart ssh
    ```
  </Step>
</Steps>

## Step 3: Install root CA certificates in the trust store

1. Copy the root CA certificate file (e.g., `my-ca.crt`) to the `/usr/local/share/ca-certificates/` directory.

```bash theme={null}
sudo cp my-ca.crt /usr/local/share/ca-certificates/
```

2. Update the CA certificates:

```bash theme={null}
sudo update-ca-certificates
```

## Step 4: Setting Up LVM Storage

1. Show the availabls space using below command

```bash theme={null}
vgs
```

you will see the free space in the VG like below:

```plaintext theme={null}
   VG        #PV #LV #SN Attr   VSize    VFree
  ubuntu-vg   1   1   0 wz--n- <498.00g <398.00g
```

2. to see the absolute free space use below command

```bash theme={null}
pvs 
```

you will see the free space in the PV like below:

```plaintext theme={null}
  PV         VG        Fmt  Attr PSize    PFree
  /dev/sda3  ubuntu-vg lvm2 a--  <498.00g <398.00g
```

3. Create a new logical volume (LV) using the free space:

```bash theme={null}
sudo lvcreate -L 300G -n nfs-share ubuntu-vg # Replace '300G' with the desired size and 'nfs-share' with your LV name
```

It will create a LV named nfs-share with 300GB size. give the terminal output like below:

```plaintext theme={null}
  Logical volume "nfs-share" created.
```

4. Format the new LV with a filesystem (e.g., xfs):

```bash theme={null}
sudo mkfs.xfs /dev/ubuntu-vg/nfs-share # Replace with your LV path  
```

you will see the terminal output like below:

```plaintext theme={null}
meta-data=/dev/ubuntu-vg/nfs-share isize=512    agcount=4, agsize=19660800 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=1
         =                       reflink=1    bigtime=1 inobtcount=1 nrext64=0
data     =                       bsize=4096   blocks=78643200, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=38400, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
Discarding blocks...Done.
```

5. Create a mount point and mount the LV:

```bash theme={null}
sudo mkdir -p /mnt/nfs-share
sudo mount /dev/ubuntu-vg/nfs-share /mnt/nfs-share
```

6. To make the mount persistent across reboots, add an entry to `/etc/fstab`:

```bash theme={null}
echo '/dev/ubuntu-vg/nfs-share /mnt/nfs-share xfs defaults 0 0' | sudo tee -a /etc/fstab
```

It will append the fstab file with the new entry. and command output like below:

```plaintext theme={null}
/dev/ubuntu-vg/nfs-share /mnt/nfs-share xfs defaults 0 0
```

## Step 5: Setting Up NFS Shares

1. Install NFS server packages:

```bash theme={null}
sudo apt update
sudo apt install nfs-kernel-server -y
```

2. Check the status of NFS server:

```bash theme={null}
sudo systemctl status nfs-kernel-server
```

3. Configure NFS exports by editing the `/etc/exports` file:

```bash theme={null}
echo '/mnt/nfs-share 192.168.12.0/255.255.255.0(rw,sync,no_subtree_check)' | sudo tee -a /etc/exports
```

This command will append the exports file with the new NFS share configuration. The output will be:

```plaintext theme={null}
/mnt/nfs-share 192.168.12.0/255.255.255.0(rw,sync,no_subtree_check)
```

4. Apply the export changes:

```bash theme={null}
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
```

5. Adjust firewall settings to allow NFS traffic (if applicable):

```bash theme={null}
sudo ufw allow from 192.168.12.0/24 to any port nfs
```

6. Verify NFS exports:

```bash theme={null}
showmount -e localhost
```

You should see output similar to:

```plaintext theme={null}
Export list for localhost:
/mnt/nfs-share 192.168.12.0/255.255.255.0
```

7. Set proper permissions on the NFS share directory:

```bash theme={null}
sudo chown -R nobody:nogroup /mnt/nfs-share
sudo chmod 777 /mnt/nfs-share
```

## Connect from Client Machine

1. On the client machine, install NFS client packages:

```bash theme={null}
sudo apt update
sudo apt install nfs-common -y
```

2. check avaiable shares from the NFS server:

```bash theme={null}
showmount -e <NFS_SERVER_IP>
```

You should see the exported shares from the server.
3\. Create a mount point on the client machine:

```bash theme={null}
sudo mkdir -p /mnt/nfs-client
```

4. Mount the NFS share from the server:

```bash theme={null}
sudo mount <NFS_SERVER_IP>:/mnt/nfs-share /mnt/nfs-client
```

5. To make the NFS mount persistent across reboots, add an entry to `/etc/fstab` on the client machine:

```bash theme={null}
echo '<NFS_SERVER_IP>:/mnt/nfs-share /mnt/nfs-client nfs defaults 0 0' | sudo tee -a /etc/fstab
```

This command will append the fstab file with the new NFS mount entry. The output will be:

```plaintext theme={null}
<NFS_SERVER_IP>:/mnt/nfs-share /mnt/nfs-client nfs defaults 0 0
```

6. Unmount the NFS share when done:

```bash theme={null}
sudo umount /mnt/nfs-client
```

## Mount using autofs (optional)

1. We dont need to add directory in the fstab file. Instead we will use autofs to mount the NFS share on demand.
2. Install autofs package:

```bash theme={null}
sudo apt update
sudo apt install autofs -y
```

3. Check the status of autofs service:

```bash theme={null}
sudo systemctl status autofs
```

4. Edit the autofs master configuration file `/etc/auto.master` to add a new map file:

```bash theme={null}
echo "/mnt/nfs /etc/auto.nfs --ghost --timeout=60" | sudo tee -a /etc/auto.master
```

This command will append the auto.master file with the new map file entry. The output will be:

```plaintext theme={null}
/mnt/nfs /etc/auto.nfs --ghost --timeout=60
```

For docker swarm it will be better if we add below permissions:

```plaintext theme={null}
nfs-share -fstype=nfs,rw,nolock,soft,tcp,intr 192.168.12.14:/mnt/nfs-share
```

```bash theme={null}
sudo systemctl restart autofs
```

**Why these extra flags matter for Docker:**

* **nolock:** Prevents the NFS client and server from trying to coordinate file locks, which often fail when multiple containers or nodes access the same share.
* **soft:** If the NFS server goes down, the client will eventually report an error instead of hanging the entire Linux process (and your Docker service) forever.
* **tcp:** Forces the use of TCP, which is more stable for Docker traffic than UDP.
* **intr:** Allows NFS requests to be interrupted if the server stops responding.

5. Create the map file `/etc/auto.nfs` with the NFS share details:

```bash theme={null}
echo "nfs-share -fstype=nfs,rw <NFS_SERVER_IP>:/mnt/nfs-share" | sudo tee /etc/auto.nfs
```

This command will create the auto.nfs file with the NFS share configuration. The output will be:

```plaintext theme={null}
nfs-share -fstype=nfs,rw <NFS_SERVER_IP>:/mnt/nfs-share
```

6. Restart the autofs service to apply the changes:

```bash theme={null}
sudo systemctl restart autofs
```

7. check the mounts:

```bash theme={null}
mount | grep autofs
```

You should see output similar to:

```plaintext theme={null}
autofs on /mnt/nfs type autofs (rw,relatime,fd=XX,pgrp=XXXX,timeout=60,minproto=5,maxproto=5)
```

8. Access the NFS share:

```bash theme={null}
ls /mnt/nfs/nfs-share
```

9. watch the autofs logs for any issues:

```bash theme={null}
sudo tail -f /var/log/syslog | grep autofs
```

## Allow ip to access NFS share through firewall

If you have UFW enabled on your Ubuntu VM, you need to allow the IP address or subnet of the client machines to access the NFS share. Use the following command to allow access:

```bash theme={null}
sudo ufw allow from
sudo ufw allow from
sudo ufw reload
```

Replace `<CLIENT_IP_OR_SUBNET>` with the actual IP address or subnet of the client machines.

## Extend the LVM Storage (if needed)

If you need to extend the LVM storage in the future, follow these steps:

1. Ad disk to the VM through your virtualization platform.
2. Run lsblk to identify the new disk (e.g., /dev/sdb).

```bash theme={null}
lsblk
```

You should see output similar to:

```plaintext theme={null}
root@nfs:~# lsblk
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                         8:0    0  500G  0 disk
├─sda1                      8:1    0    1M  0 part
├─sda2                      8:2    0    2G  0 part /boot
└─sda3                      8:3    0  498G  0 part
  ├─ubuntu--vg-ubuntu--lv 252:0    0  100G  0 lvm  /
  └─ubuntu--vg-nfs--share 252:1    0  300G  0 lvm  /mnt/nfs-share
sdb                         8:16   0  500G  0 disk
sr0                        11:0    1 1024M  0 rom
```

3. Create a physical volume (PV) on the new disk:

```bash theme={null}
sudo pvcreate /dev/sdb
```

You should see output similar to:

```plaintext theme={null}
  Physical volume "/dev/sdb" successfully created.
```

4. Extend the existing volume group (VG) to include the new PV:

```bash theme={null}
sudo vgextend ubuntu-vg /dev/sdb
```

You should see output similar to:

```plaintext theme={null}
  Volume group "ubuntu-vg" successfully extended
```

5. Extend the logical volume (LV) to use the additional space:

```bash theme={null}
sudo lvextend -r -l +100%FREE /dev/ubuntu-vg/nfs-share # Replace with your LV path
```

You should see output similar to:

```plaintext theme={null}
Size of logical volume ubuntu-vg/nfs-share changed from 300.00 GiB (76800 extents) to 897.99 GiB (229886 extents).
  Logical volume ubuntu-vg/nfs-share successfully resized.
meta-data=/dev/mapper/ubuntu--vg-nfs--share isize=512    agcount=4, agsize=19660800 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=1
         =                       reflink=1    bigtime=1 inobtcount=1 nrext64=0
data     =                       bsize=4096   blocks=78643200, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=38400, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 78643200 to 235403264
```

6. Verify the new size of the LV:

```bash theme={null}
sudo lvs
```

You should see output similar to:

```plaintext theme={null}
  LV        VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  nfs-share ubuntu-vg -wi-ao---- 897.99g                                                    
  ubuntu-lv ubuntu-vg -wi-ao---- 100.00g                                                    
```

## Troubleshooting

If you encounter issues during the setup process, consider the following troubleshooting steps:

1. Check NFS server status:

```bash theme={null}
sudo systemctl status nfs-kernel-server
```

2. Verify NFS exports:

```bash theme={null}
showmount -e localhost
```

3. Review system logs for errors:

```bash theme={null}
sudo tail -f /var/log/syslog
```

4. Ensure firewall rules are correctly configured to allow NFS traffic.
5. Verify LVM configuration:

```bash theme={null}
sudo lvdisplay
sudo vgdisplay
sudo pvdisplay
```

## Conclusion

By following this guide, you have successfully set up an Ubuntu virtual machine with LVM storage and
NFS shares. This configuration provides a flexible and scalable storage solution that can be easily managed and expanded as needed. Enjoy your new Ubuntu VM setup!
