Thursday, May 21, 2020

Personal Installation Guide of Raspberry Pi 4B cluster

Why this project with Raspberry Pi cluster ? Because it is cheap and can be used for the many purposes as below.

Hardware

4 x Raspberry Pi 4B with heat sinks
Raspberry Pi Cluster Case 4 layers with Cooling Fan for each layer
4 x MicroSDHC SanDisk 32G Class 10
One MicroSD Adapter for installation of OS
4 x USB-C power cable
4 x Cat 6 LAN cable
USB power supply with 8 USB ports total max 10A
External USB fans connected to USB power supply, important to keep the CPU cool especially when overclock
4 x UPS Battery Case 5V max 3.3A (each with 3 x Panasonic 18650BD 3200mAH batteries)
8 ports Gigabit Ethernet Switch
External RAID-0 disks with 2 x 8TB (WD Ultrastar HC320 7200rpm) storage, USB-C to USB3.0 interface (HD is the most expensive item for this project)
cat /proc/cpuinfo    Select all
Reference : https://www.rs-online.com/designspark/raspberry-pi-3-model-b-vs-3-model-b processor : 0 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3 processor : 1 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3 processor : 2 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3 processor : 3 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3 Hardware : BCM2835 Revision : c03112 Serial : 100000003bc32951 Model : Raspberry Pi 4 Model B Rev 1.2


SD Card images for BerryBoot

BerryBoot(very flexible and allow to add custom OS images for multiboot)
https://www.berryterminal.com/doku.php/berryboot

OS : Ubuntu 18.04.3 LTS
Download from Ubuntu_Server_arm64_18.04.3.img
https://sourceforge.net/projects/berryboot/files/os_images/
or raspberry pi image from
https://wiki.ubuntu.com/ARM/RaspberryPi
or download the latest image for raspi4 and convert to berryboot format as below
shell script    Select all
nohup curl -OL http://cdimage.ubuntu.com/ubuntu/releases/18.04.4/release/ubuntu-18.04.4-preinstalled-server-arm64+raspi4.img.xz & # or download the 32 bits version # nohup curl -OL http://cdimage.ubuntu.com/ubuntu/releases/18.04.4/release/ubuntu-18.04.4-preinstalled-server-armhf+raspi4.img.xz & sudo apt update sudo apt install kpartx squashfs-tools unxz ubuntu-18.04.4-preinstalled-server-arm64+raspi4.img.xz # And follow this guide to create your own berry boot images. # https://www.berryterminal.com/doku.php/berryboot/adding_custom_distributions # Convert arm64+raspi4 to berryboot OS image sudo kpartx -av ubuntu-18.04.4-preinstalled-server-arm64+raspi4.img #sudo mount /dev/mapper/loop0p2 /mnt sudo mount /dev/mapper/loop1p2 /mnt sudo sed -i 's/^\/dev\/mmcblk/#\0/g' /mnt/etc/fstab sudo sed -i 's/^PARTUUID/#\0/g' /mnt/etc/fstab sudo rm -f /mnt/etc/console-setup/cached_UTF-8_del.kmap.gz sudo rm -f /mnt/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service sudo rm -f /mnt/etc/systemd/system/multi-user.target.wants/raspberrypi-net-mods.service sudo rm -f /mnt/etc/rc3.d/S01resize2fs_once sudo mksquashfs /mnt Ubuntu_Server_arm64_18.04.4_raspi4.img -comp lzo -e lib/modules sudo umount /mnt sudo kpartx -d ubuntu-18.04.4-preinstalled-server-arm64+raspi4.img # Convert armhf+raspi4 to berryboot OS image unxz ubuntu-18.04.4-preinstalled-server-armhf+raspi4.img.xz sudo kpartx -av ubuntu-18.04.4-preinstalled-server-armhf+raspi4.img sudo mount /dev/mapper/loop1p2 /mnt sudo sed -i 's/^\/dev\/mmcblk/#\0/g' /mnt/etc/fstab sudo sed -i 's/^PARTUUID/#\0/g' /mnt/etc/fstab sudo rm -f /mnt/etc/console-setup/cached_UTF-8_del.kmap.gz sudo rm -f /mnt/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service sudo rm -f /mnt/etc/systemd/system/multi-user.target.wants/raspberrypi-net-mods.service sudo rm -f /mnt/etc/rc3.d/S01resize2fs_once sudo mksquashfs /mnt Ubuntu_Server_armhf_18.04.4_raspi4.img -comp lzo -e lib/modules sudo umount /mnt sudo kpartx -d ubuntu-18.04.4-preinstalled-server-armhf+raspi4.img Download links for these 2 converted images and other updated Raspbian images are on the right hand sidebar of this blog. # BerryBoot way to change default OS images on reboot # Reference : https://www.raspberrypi.org/forums/viewtopic.php?t=37861 # Reference : https://yoursunny.com/t/2017/berryboot-reboot-into/


Ubuntu Server image setup

shell script    Select all
plug in the Ethernet cable before boot up login: ubuntu password: ubuntu change ubuntu password once login # Update Server Security # Reference : https://www.raspberrypi.org/documentation/configuration/security.md sudo apt install openssh-server # check hostname hostnamectl # check network interface ifconfig # update some packages sudo apt update sudo apt-get install dpkg sudo apt-get install --reinstall python3-minimal python3-lockfile sudo apt-get install --reinstall python3-twisted sudo apt-get install --reinstall python3 python3-pip sudo apt-get install --reinstall python-minimal python-lockfile sudo apt-get install --reinstall python python-pip # change hostname, change to pi01, pi02 ... # Reference : https://linuxize.com/post/how-to-change-hostname-on-ubuntu-18-04/ sudo hostnamectl set-hostname pi01 hostnamectl # change timezone sudo dpkg-reconfigure tzdata # change eth0 to Static IP # Reference : https://linuxconfig.org/how-to-configure-static-ip-address-on-ubuntu-18-04-bionic-beaver-linux cat /etc/netplan/01-netcfg.yaml network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no addresses: - 10.0.1.XXX/24 gateway4: 10.0.0.1 nameservers: addresses: [8.8.8.8, 1.1.1.1] # Once ready apply changes with: sudo netplan apply # Mount NTFS external raid disk and Install NFS Server # Reference : https://www.tecmint.com/install-nfs-server-on-ubuntu/ # Reference : https://vitux.com/install-nfs-server-and-client-on-ubuntu/ # Check UUID or PARTUUID sudo blkid # add this in /etc/fstab, for example PARTUUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" /media/RAID0WD ntfs defaults,nls=utf8,dmask=0000,fmask=0022,uid=1000,gid=1000,windows_names 0 0 # reboot to check mounted disk sudo reboot # After reboot df -h # add this in /etc/exports, for example /media/RAID0WD 10.0.1.0/24(rw,sync,no_root_squash,no_subtree_check,insecure,anonuid=1000,anongid=1000) echo "/media/RAID0WD 10.0.1.0/24(rw,sync,no_root_squash,no_subtree_check,insecure,anonuid=1000,anongid=1000)" | sudo tee -a /etc/exports # Export and restart NFS Server sudo exportfs -a sudo systemctl restart nfs-kernel-server # Allow nfs on firewall sudo ufw allow from 10.0.1.0/24 to any port nfs showmount -e pi01 # Install Raspberry pi bin and check cpu temperature sudo add-apt-repository ppa:ubuntu-raspi2/ppa sudo apt-get update sudo apt-get install libraspberrypi-bin # My CPU temp=38.0'C vcgencmd measure_temp # Mount NFS from Mac OS X Connect to Server, enter nfs://10.0.1.101/media/RAID0WD # Mount NFS from other Ubuntu nodes # Reference : https://www.raspberrypi.org/documentation/configuration/nfs.md # add this in /etc/fstab, for example 10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0 echo "10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0" | sudo tee -a /etc/fstab ## Install Samba for Ubuntu Server # Reference https://linuxize.com/post/how-to-install-and-configure-samba-on-ubuntu-18-04/ # put this in /etc/samba/smb.conf, for example [raidshare] path = /media/RAID0WD browseable = yes guest ok = no read only = no force create mode = 0660 force directory mode = 2770 valid users = ubuntu @ubuntu ## Add Samba password for user ubuntu sudo smbpasswd -a ubuntu # Restart Samba Server sudo systemctl restart smbd # Allow samba on firewall sudo ufw allow 'Samba' # create images folder for berryboot images installation for other nodes cd $HOME ln -sf /media/RAID0WD smb_share cd $HOME/smb_share mkdir -p images # Download required berryboot os images nohup curl -L https://sourceforge.net/projects/berryboot/files/os_images/Ubuntu_Server_arm64_18.04.3.img/download -o Ubuntu_Server_arm64_18.04.3.img & # Check sha1 signature openssl sha1 Ubuntu_Server_arm64_18.04.3.img


Raspbian Buster image setup

shell script    Select all
plug in the Ethernet cable before boot up login: pi password: raspberry change password once login # Reference : https://www.raspberrypi.org/documentation/configuration/security.md sudo apt install openssh-server # check hostname hostname # check network interface ifconfig # change hostname, change to pi01, pi02 ... etc sudo raspi-config -> Select 2. Network Options -> Select N1 Hostname # Enable SSH at the command line using raspi-config sudo raspi-config -> Select 5. Interfacing Options -> Select P2 SSH -> Select Yes # VNC Server at the command line using raspi-config sudo raspi-config -> Select 5. Interfacing Options -> Select P3 VNC -> Select Yes # change timezone sudo dpkg-reconfigure tzdata -> Select the timezone # change locales sudo dpkg-reconfigure locales -> Select the locale # change eth0 to Static IP # Reference : https://pimylifeup.com/raspberry-pi-static-ip-address/ sudo vi /etc/dhcpcd.conf # Restart dhcp sudo service dhcpcd restart # you will have 2 IP addresses, which is good for mounting nfs at start hostname -I # if you have 2 ip addresses and would like to stop the dhcp for eth0, see discussions here. https://raspberrypi.stackexchange.com/questions/52010/set-static-ip-and-stop-dhcp-on-jessie-lite # Mount NTFS external raid disk and Install NFS Server for Raspbian Buster # Check UUID or PARTUUID sudo blkid # add this in /etc/fstab, for example PARTUUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" /media/RAID0WD ntfs defaults,nls=utf8,dmask=0000,fmask=0022,uid=1000,gid=1000,windows_names 0 0 # reboot to check mounted disk sudo reboot # After reboot df -h # Install NFS Server for Raspbian Buster sudo apt install nfs-kernel-server # add this in /etc/exports, for example /media/RAID0WD 10.0.1.0/24(rw,sync,no_root_squash,no_subtree_check,insecure,anonuid=1000,anongid=1000) echo "/media/RAID0WD 10.0.1.0/24(rw,sync,no_root_squash,no_subtree_check,insecure,anonuid=1000,anongid=1000)" | sudo tee -a /etc/exports # Export and restart NFS Server sudo exportfs -a sudo systemctl restart nfs-kernel-server showmount -e pi01 # Mount NFS from Mac OS X Connect to Server, enter nfs://10.0.1.101/media/RAID0WD # Mount NFS from other Raspbian nodes # Reference : https://www.raspberrypi.org/documentation/configuration/nfs.md # add this in /etc/fstab, for example 10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0 echo "10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0" | sudo tee -a /etc/fstab # Install Samba for Raspbian Buster sudo apt install samba # put this in /etc/samba/smb.conf, for example [raidshare] path = /media/RAID0WD browseable = yes guest ok = no read only = no force create mode = 0660 force directory mode = 2770 valid users = pi @pi # Add Samba password for user pi sudo smbpasswd -a pi # Restart Samba Server sudo systemctl restart smbd # create images folder for berryboot images installation for other nodes cd $HOME ln -sf /media/RAID0WD smb_share cd $HOME/smb_share mkdir -p images # Download required berryboot os images nohup curl -L https://sourceforge.net/projects/berryboot/files/os_images/Debian_Buster_Raspbian_FULL_2019.10.img/download -o Debian_Buster_Raspbian_FULL_2019.10.img & nohup curl -L https://sourceforge.net/projects/berryboot/files/os_images/Debian_Buster_Raspbian_2019.10.img/download -o Debian_Buster_Raspbian_2019.10.img & # Check sha1 signature openssl sha1 Debian_Buster_Raspbian_FULL_2019.10.img openssl sha1 Debian_Buster_Raspbian_2019.10.img


Nodes pi01 pi02 pi03 pi04 setup

shell script    Select all
Reference : https://magpi.raspberrypi.org/articles/build-a-raspberry-pi-cluster-computer Install OS images to other nodes, change hostname and assign fixed IP address for each node. # Mount NFS for other nodes # Reference : https://www.raspberrypi.org/documentation/configuration/nfs.md # Install package sudo apt install nfs-common # add this in /etc/fstab, for pi02, pi03, pi04 nodes and reboot to be effective 10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0 echo "10.0.1.101:/media/RAID0WD /mnt/RAID0WD nfs auto 0 0" | sudo tee -a /etc/fstab # Generate ssh key copy it to every other node in the cluster # Reference : http://www.linuxproblem.org/art_9.html # Login pi01 ssh pi@10.0.1.101 ssh-keygen -t rsa ssh-copy-id 10.0.1.102 ssh-copy-id 10.0.1.103 ssh-copy-id 10.0.1.104 exit # Login pi02 ssh pi@10.0.1.102 ssh-keygen -t rsa ssh-copy-id 10.0.1.101 ssh-copy-id 10.0.1.103 ssh-copy-id 10.0.1.104 exit # Login pi03 ssh pi@10.0.1.103 ssh-keygen -t rsa ssh-copy-id 10.0.1.101 ssh-copy-id 10.0.1.102 ssh-copy-id 10.0.1.104 exit # Login pi04 ssh pi@10.0.1.104 ssh-keygen -t rsa ssh-copy-id 10.0.1.101 ssh-copy-id 10.0.1.102 ssh-copy-id 10.0.1.103 exit Install MPI for each node pi01, pi02, pi03, pi04 nodes sudo apt install mpich python3-mpi4py sudo apt install python-mpi4py ##Test01 # Running in pi01 mpirun -n 4 -host 10.0.1.101,10.0.1.102,10.0.1.102,10.0.1.104 hostname ##Test02 # Running in pi01 mkdir -p /media/RAID0WD/Projects ln -sf /media/RAID0WD/Projects $HOME #Create shell script as temp.sh in $HOME/Projects folder cat > $HOME/Projects/temp.sh <<EOF #!/bin/sh echo "\$(hostname)" "\$(vcgencmd measure_temp)" EOF chmod +x $HOME/Projects/temp.sh # create a common Projects folder in all other nodes # all nodes pi02 to pi04 create folder link and assume mounted NFS from pi01 ln -sf /mnt/RAID0WD/Projects $HOME/ # Running in pi01 to pi04 ssh pi@10.0.1.101 mpirun -n 4 -host 10.0.1.101,10.0.1.102,10.0.1.102,10.0.1.104 $HOME/Projects/temp.sh ssh pi@10.0.1.102 mpirun -n 4 -host 10.0.1.101,10.0.1.102,10.0.1.102,10.0.1.104 $HOME/Projects/temp.sh ssh pi@10.0.1.103 mpirun -n 4 -host 10.0.1.101,10.0.1.102,10.0.1.102,10.0.1.104 $HOME/Projects/temp.sh ssh pi@10.0.1.104 mpirun -n 4 -host 10.0.1.101,10.0.1.102,10.0.1.102,10.0.1.104 $HOME/Projects/temp.sh ##Test03 # Add this in /etc/hosts for all nodes pi01, pi02, pi03, pi04 ssh pi@10.0.1.101 echo -e "10.0.1.101\tpi01\n10.0.1.102\tpi02\n10.0.1.103\tpi03\n10.0.1.104\tpi04" | sudo tee -a /etc/hosts ssh pi@10.0.1.102 echo -e "10.0.1.101\tpi01\n10.0.1.102\tpi02\n10.0.1.103\tpi03\n10.0.1.104\tpi04" | sudo tee -a /etc/hosts ssh pi@10.0.1.103 echo -e "10.0.1.101\tpi01\n10.0.1.102\tpi02\n10.0.1.103\tpi03\n10.0.1.104\tpi04" | sudo tee -a /etc/hosts ssh pi@10.0.1.104 echo -e "10.0.1.101\tpi01\n10.0.1.102\tpi02\n10.0.1.103\tpi03\n10.0.1.104\tpi04" | sudo tee -a /etc/hosts #Running on any node cd $HOME/Projects curl -OL https://raw.githubusercontent.com/mpi4py/mpi4py/master/demo/helloworld.py mpirun -n 4 -host pi01,pi02,pi03,pi04 python $HOME/Projects/helloworld.py ##Test04 #Running on exactly 2 processes only cd $HOME/Projects curl -OL https://raw.githubusercontent.com/mpi4py/mpi4py/master/demo/osu_bw.py mpirun -n 2 -host pi01,pi02 python $HOME/Projects/osu_bw.py # create a file $HOME/Projects/4bmachinelist with the list of available pi 4b nodes for mpi # It is not advised to mix pi 4b with 3b together to run mpi, as it will degrade the performance. mpirun -n 2 -machinefile $HOME/Projects/4bmachinelist python $HOME/Projects/osu_bw.py #On each node, launch 1 process only mpirun -npernode 1 -machinefile $HOME/Projects/4bmachinelist $HOME/Projects/temp.sh # -N is same as -npernode, -hostfile is same as -machinefile mpirun -N 1 -hostfile $HOME/Projects/4bmachinelist $HOME/Projects/temp.sh # or mpirun -N 1 -hostfile $HOME/Projects/4bmachinelist bash -c 'echo "$(hostname)" "$(vcgencmd measure_temp)"' | sort ##Test05 # Count how many processes for your cluster, you should get 4 x 4 nodes = 16 processes cd $HOME/Projects curl -L https://github.com/Apress/raspberry-pi-supercomputing/archive/master.zip -o supercomputing.zip unzip supercomputing.zip mpirun -hostfile 4bmachinelist -N 1 python3 $HOME/Projects/raspberry-pi-supercomputing-master/Codes/code/chapter08/prog01.py mpirun -hostfile 4bmachinelist -N 4 python3 $HOME/Projects/raspberry-pi-supercomputing-master/Codes/code/chapter08/prog03.py ##Test06 # Calculate primes # Get the source code from curl -OL https://people.sc.fsu.edu/~jburkardt/py_src/prime_mpi/prime_mpi.py # There are 2 errors to fix before using it # Line 41, there is a missing closing bracket ) at the end # Line 74, should be changed from comm.Reduce ( [ t, MPI.DOUBLE ], [ primes, MPI.INT ], op = MPI.SUM, root = 0 ) to primes = comm.reduce ( t, op = MPI.SUM, root = 0 ) # Test the time required among different processes by running the below # assuming maximum 4 processes (pi 4 CPU has 4 cores) per node cd $HOME/Projects mpirun -n 4 -hostfile 4bmachinelist python3 prime_mpi.py mpirun -n 8 -hostfile 4bmachinelist python3 prime_mpi.py mpirun -n 12 -hostfile 4bmachinelist python3 prime_mpi.py mpirun -n 16 -hostfile 4bmachinelist python3 prime_mpi.py #On each node, launch 3 and 4 processes, and time their differences cd $HOME/Projects time mpirun -N 3 -hostfile 4bmachinelist python3 prime_mpi.py time mpirun -N 4 -hostfile 4bmachinelist python3 prime_mpi.py # Please post your results of Test06 here in the comment ##Test07 # Collective communication using the scatter function example cd ~/Projects curl -L https://pythonprogramming.net/scatter-gather-mpi-mpi4py-tutorial/ | grep -A13 -B1 "from mpi4py" | sed '1d' > sct9.py time mpirun -N 4 -hostfile 4bmachinelist python sct9.py ##Test08 # Collective communication using the gather function example cd ~/Projects curl -L https://pythonprogramming.net/mpi-gather-command-mpi4py-python/ | grep -A19 -B1 "from mpi4py" | sed '1d' > sct10.py time mpirun -N 4 -hostfile 4bmachinelist python sct10.py ##Test09 # mpicc examples cd $HOME/Projects curl -L https://github.com/wesleykendall/mpitutorial/archive/gh-pages.zip -o mpitutorial.zip unzip mpitutorial.zip cd mpitutorial-gh-pages/tutorials/mpi-reduce-and-allreduce/code make time mpirun -N 4 -hostfile $HOME/Projects/4bmachinelist reduce_avg 100000000 time mpirun -N 4 -hostfile $HOME/Projects/4bmachinelist reduce_stddev 100000000


Optional Server or services setup

shell script    Select all
# Nginx (a lightweght webserver) and fast php plugin sudo apt-get install nginx cd; ln -s /usr/share/nginx/html . # check ip address and use browser connect to test web server hostname -I ifconfig eth0 ifconfig wlan0 # for wireless lan ip addr | grep -Po '(?!(inet 127.\d.\d.1))(inet \K(\d{1,3}\.){3}\d{1,3})' # install php in nginx sudo apt install php-fpm php-curl php-gd php-cli php7.3-opcache php-mbstring php-xml php-zip # link the html folder to home cd $HOME sudo chown pi:pi /var/www/html ln -sf /var/www/html . # create testing php page cat > ~/html/info.php <<EOF <?php phpinfo(); ?> EOF # add in /etc/php/7.3/fpm/pool.d/www.conf user = pi group = pi # enable php in nginx and edit this file sudo vi /etc/nginx/sites-enabled/default # and change or add the followings in server section: server { ... # Add index.php to the list if you are using PHP index index.html index.htm index.php index.nginx-debian.html; ... ## Begin - PHP location ~ \.php$ { # Choose either a socket or TCP/IP address fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; # fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; } ## End - PHP ## Begin - Security # deny all direct access for these folders location ~* /(.git|cache|bin|logs|backups|tests)/.*$ { return 403; } # deny running scripts inside core system folders location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } # deny running scripts inside user folder location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } # deny access to specific files in the root folder location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; } ## End - Security ... } # # see instructions for php7 here -> https://getgrav.org/blog/raspberrypi-nginx-php7-dev # reload web server and test # check to ensure the /var/run/php/php7.3-fpm.sock file exists sudo service nginx restart sudo service php7.3-fpm restart ls -l /var/run/php/php7.3-fpm.sock # Use this command to check whether the web server is working or not curl -L http://127.0.0.1/ curl -L http://127.0.0.1/info.php # python cgi plugin for nginx see here # install minidlna as a media server sudo apt install minidlna # edit /etc/minidlna.conf and add the followings media_dir=V,/media/RAID0WD/MyMovie friendly_name=MyMovie # edit /etc/default/minidlna and add the followings USER="root" GROUP="root" # reload minidlna sudo service minidlna restart sudo service minidlna force-reload # see what network services are working on raspberry pi sudo netstat -ntlp # free ddns no-ip.com Free sign-up and have 3 Hostnames but need to Confirm Every 30 Days # After sign-up, manual update of IP address # Use this command to obtain your public IP address and update on their website host myip.opendns.com resolver1.opendns.com | grep myip # and then download and Install the dynamic update client for Linux https://www.noip.com/support/knowledgebase/installing-the-linux-dynamic-update-client/ You can have 3 host names and have to install virtual host in nginx web server. In server settings of /etc/nginx/sites-available/default, use this settings to map to different html subfolders for different hosts server { ... server_name ~^(.*)\.(.*)\.(.*)$; set $host_name $1; set $subdomain_name $2; set $domain_name $3; root /var/www/html/$host_name.$subdomain_name.$domain_name; ... } # Suppose myhostname1, myhostname2 and myhostname3 are the hostnames obtained from no-ip.com # Setup html root for mutli-hosts as above settings in nginx sudo chown -R pi:pi /var/www/html mkdir -p /var/www/html/10.0.1.101 mkdir -p /var/www/html/127.0.0.1 mkdir -p /var/www/html/myhostname1.ddns.net mkdir -p /var/www/html/myhostname2.ddns.net mkdir -p /var/www/html/myhoatname3.ddns.net # Restart web server to be effective sudo service nginx restart sudo service php7.3-fpm restart # Test web server after restart services cd /var/www/html/ cp index.nginx-debian.html 10.0.1.101 curl -L http://10.0.1.101/ cd /var/www/html/ cp info.php 127.0.0.1/ curl -L http://127.0.0.1/info.php # Test webserver from ddns cd /var/www/html/myhostname1.ddns.net curl -L https://getgrav.org/blog/raspberrypi-nginx-php7-dev -o index.html # make sure your hone router tcp port 80 has been forwarded to your internal Pi host and test with curl -L http://myhostname1.ddns.net/ # And also test the webserver from the browser on Phone # How to access the server and nodes from Android Phone # Recommend Termux from Google Play Store # It use the Volume Up key + keyboard to enter special control characters and can install packages # Reference : https://wiki.termux.com/wiki/Touch_Keyboard apt update apt upgrade # Install ssh and login server apt install openssh ssh-copy-id pi@10.0.1.101 ssh pi@10.0.1.101 # Assume ddns is setup ssh-copy-id pi@myhostname.ddns.net ssh pi@myhostname.ddns.net # Install python 3 apt search python apt install python # To improve command line history productivity, please refer Terminal history usage tips : https://www.howtogeek.com/howto/44997/how-to-use-bash-history-to-improve-your-command-line-productivity/amp/ # ssh forwarding from Android Device (better to have Android tablet with keyboard and mouse) # Reference: https://wiki.termux.com/wiki/Main_Page # Need to install VNC Viewer and Termux from Google Play Store # Install and start vncserver in Termux vncserver -localhost export DISPLAY=":1" # ssh forwarding and login pi ssh -Y pi@10.0.1.104 # install and run jupyter-notebook from pi (after installation of tensorflow) pip3 install jupyter jupyter-notebook & # run the juypter notebook example from https://colab.research.google.com/github/lmoroney/io19/blob/master/Zero%20to%20Hero/Rock-Paper-Scissors.ipynb # After session ended and kill vncserver in Termux vncserver -kill :1 # free ssl certificate for web server https://letsencrypt.org/getting-started/ # After you have your ddns host and nginx running on your Pi, follow the certbot instructions here # Reference : https://certbot.eff.org/lets-encrypt/debianbuster-nginx # set up certbot and obtain ssl certifcate for nginx sudo apt-get install certbot python-certbot-nginx sudo certbot --nginx crontab -e # add this entry to automate letencrypt certificate renewal 43 6 * * * certbot renew --renew-hook "systemctl reload nginx" Certificate and chain have been saved at: /etc/letsencrypt/live/myhostname1.ddns.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/myhostname1.ddns.net/privkey.pem Your cert will expire on (90 days after). To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" sudo certbot certonly sudo certbot certificates sudo systemctl reload nginx # make sure your home router tcp port 443 has been forwarded to your internal Pi host and test with curl -L https://myhostname1.ddns.net/ # Install OpenVPN Server After you have the ddns hostname or fixed IP address, setup OpenVPN as per instructions here # Reference : https://www.pcmag.com/how-to/how-to-create-a-vpn-server-with-raspberry-pi curl -L https://install.pivpn.io | bash # Choose OpenVPN and use udp port 1194 # Also need to assign fixed IP to your Pi # After installation, sudo reboot to be effective # forward udp port 1194 to the internal IP address of your Pi # Client access # Create configuration file e.g. iphone, macbook etc. pivpn add # Client access Use "OpenVPN Connect App" for phone and notebook send the profile to the client by email and import, e.g. for iPhone # Makeuse of X11 forwarding to run graphical applications see https://kb.iu.edu/d/bdnt For macOS High Sierra or above, please see this guide to install xQuartz. https://www.unixtutorial.org/get-x11-forwarding-in-macos-high-sierra/
You can install it from https://www.xquartz.org or via "sudo port -v install xorg" in the terminal. For In Windows 10 WSL, and install XServer in Windows 10 such as xming -> https://sourceforge.net/projects/xming/ and set DISPLAT for WSL x11-apps export DISPLAY=localhost:0.0 export DISPLAY=:0 For Linux, there is built-in support. In Terminal, type ssh -Y pi@10.0.1.101 # After login Raspberry pi sudo apt-get install idle3 idle & # run scratch sudo apt-get install scratch scratch & # run codeblocks sudo apt install codeblocks codeblocks & If you get "cannot open display error", see discussions here. https://superuser.com/questions/310197/how-do-i-fix-a-cannot-open-display-error-when-opening-an-x-program-after-sshi # run browser chromium-browser & # Access Raspberry Pi Desktop Remotely Use Windows Remote Desktop Client to connect to the Raspberry Pi. # Install xrdp and reboot the pi after installation sudo apt install xrdp sudo systemctl restart xrdp # For macOS, there is "Microsoft Remote Desktop Connection Client for Mac" in the Mac App Store. # setup cron job to backup project data # Reference : https://www.raspberrypi.org/documentation/linux/usage/cron.md Create a shell script e.g. cat > /home/pi/backup.sh <<EOF #!/bin/sh cd /media/RAID0WD; tar --exclude='./Projects/Downloads' -zcf Projects-backup/"Projects$(date '+%Y%m%d').tar.gz" Projects EOF chmod a+x /home/pi/backup.sh mkdir -p /media/RAID0WD/Projects-backup # add this entry in the crontab 0 0 * * * /home/pi/backup.sh #List crontab crontab -l # Overclock # Reference : https://www.seeedstudio.com/blog/2020/02/12/how-to-safely-overclock-your-raspberry-pi-4-to-2-147ghz/ #Install docker # Not for berryboot images curl -sSL https://get.docker.com | sh sudo usermod -aG docker $USER sudo newgrp docker sudo apt install libffi-dev libssl-dev python3 python3-pip sudo apt-get remove python-configparser sudo pip3 -v install docker-compose # test docker hello-world docker run hello-world cd $HOME mkdir my-wordpress cd my-wordpress cat > docker-compose.yaml <<EOF version: '3.2' services: db: image: hypriot/rpi-mysql volumes: - "./.data/db:/var/lib/mysql" restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest links: - db ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpress EOF docker-compose up -d # then try browser http://localhost:8000/ # stop the docker-compose example docker-compose down # test nodejs cd $HOME git clone https://github.com/hypriot/rpi-node-haproxy-example cd rpi-node-haproxy-example docker-compose up curl http://localhost:80 curl http://localhost:70 docker-compose stop # test nodejs + mongodb cd $HOME git clone https://github.com/hagaik/easy-node-authentication.git cd easy-node-authentication cat > config/database.js <<EOF // config/database.js module.exports = { 'url' : 'mongodb://mongo:27017' // looks like mongodb://<user>:<pass>@mongo.onmodulus.net:27017/Mikha4ot }; EOF cat > Dockerfile <<EOF FROM hypriot/rpi-node # Create app directory WORKDIR /usr/src/app # Install app dependencies COPY package*.json ./ RUN npm install # Copy app source code COPY . . #Expose port and start application EXPOSE 8080 CMD [ "npm", "start" ] EOF cat > docker-compose.yaml <<EOF version: "3.2" services: db: image: dhermanns/rpi-mongo volumes: - "data-volume:/data/db" restart: always ports: - "27017:27017" expose: - "27017" webm: build: . depends_on: - db ports: - "8080:8080" expose: - "8080" volumes: data-volume: EOF # build and start as daemon docker-compose up --build -d # then try browser http://localhost:8080/ # stop and down docker-compose down -v # move docker data-root to nfs mounted drive e.g. /mnt/docker-data sudo service docker stop cat << EOF | sudo tee -a /etc/docker/daemon.json { "storage-driver": "overlay", "data-root": "/mnt/docker-data" } EOF sudo rsync -aP /var/lib/docker/ /mnt/docker-data sudo mv /var/lib/docker /var/lib/docker.old sudo service docker start


Install tensorflow and horovod for Pi 4 cluster

shell script    Select all
Install all these packages for every nodes in the Pi 4 cluster in order to run horovod with tensorflow # Install tenorflow 2.1.0 # Reference https://qengineering.eu/install-tensorflow-2.1.0-on-raspberry-pi-4.html # or https://qengineering.eu/install-tensorflow-2.2.0-on-raspberry-pi-4.html for tenorflow 2.2.0 cd ~/Projects sudo apt-get install gfortran sudo apt-get install libhdf5-dev libc-ares-dev libeigen3-dev sudo apt-get install libatlas-base-dev libopenblas-dev libblas-dev sudo apt-get install liblapack-dev cython sudo pip3 install pybind11 sudo apt-get install python3-h5py # upgrade pip3 and check pip3 version curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python3 get-pip.py --force-reinstall # pip 20.1.1 from /home/pi/.local/lib/python3.7/site-packages/pip (python 3.7) python3 --version pip3 --version # download the wheel wget https://github.com/Qengineering/Tensorflow-Raspberry-Pi/raw/master/tensorflow-2.1.0-cp37-cp37m-linux_armv7l.whl # install TensorFlow 2.1.0 python3 -m pip install --user tensorflow-2.1.0-cp37-cp37m-linux_armv7l.whl # test run examples as in how-to-install-tensorflow-with-gpu python3 -m pip install --user matplotlib python3 -m pip install --user pandas python3 -m pip install --user keras scikit-learn cd ~/Projects curl -L https://tinyurl.com/tensorflowwin | grep -A7 tftest.py | sed '1,2d' > tftest.py python3 tftest.py curl -L https://tinyurl.com/tensorflowwin | grep -A129 irislearn.py | sed '1,8d' > irislearn.py curl -L https://tinyurl.com/tensorflowwin | grep -A150 iris.data.nbsp | sed '1d' > iris.data python3 irislearn.py curl -L https://tinyurl.com/tensorflowwin | grep -A37 keraslearn.py | sed '1,3d' > keraslearn.py curl -L https://tinyurl.com/tensorflowwin | grep -A768 pima-indians-diabetes.data.nbsp | sed '1d' > pima-indians-diabetes.data python3 keraslearn.py # install horovod # https://github.com/horovod/horovod#install python3 -m pip install cffi>=1.4.0 cloudpickle python3 -m pip install horovod # Reboot to make it effective sudo reboot # First test run the simple hellohorovod.py cd ~/Projects cat > hellohorovod.py <<EOF from mpi4py import MPI import horovod.tensorflow as hvd # Split COMM_WORLD into subcommunicators subcomm = MPI.COMM_WORLD.Split(color=MPI.COMM_WORLD.rank % 2, key=MPI.COMM_WORLD.rank) # Initialize Horovod hvd.init(comm=subcomm) print('COMM_WORLD rank: %d, Name: %s, Horovod rank: %d' % (MPI.COMM_WORLD.rank, MPI.Get_processor_name(), hvd.rank())) EOF # run it with cd ~/Projects horovodrun -np 1 -H localhost:1,pi02:1,pi03:1,pi04:4 python3 hellohorovod.py # Then try run the tensorflow v2 example as below # please be warned that and watch out the temperature of PIs. # https://github.com/horovod/horovod/blob/master/examples/tensorflow2_keras_mnist.py # For non-keras, the sample is https://github.com/horovod/horovod/blob/master/examples/tensorflow2_mnist.py cd ~/Projects wget https://raw.githubusercontent.com/horovod/horovod/master/examples/tensorflow2_keras_mnist.py time horovodrun -np 4 -H localhost:1,pi02:1,pi03:1,pi04:1 python3 tensorflow2_keras_mnist.py time horovodrun -np 8 -H localhost:2,pi02:2,pi03:2,pi04:2 python3 tensorflow2_keras_mnist.py time horovodrun -np 12 -H localhost:3,pi02:3,pi03:3,pi04:3 python3 tensorflow2_keras_mnist.py # 1 slot per node has the faster performance for the Pi cluster # As with the release of the new 8GB Pi4B model, it is possible to increase the number of slots for these 8GB machines. # append self public key to self authorized list ssh pi@10.0.1.101 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys exit ssh pi@10.0.1.102 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys exit ssh pi@10.0.1.103 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys exit ssh pi@10.0.1.104 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys exit # create ~/Projects/myhostfile cat > ~/Projects/myhostfile <<EOF pi01 slots=1 pi02 slots=1 pi03 slots=1 pi04 slots=1 EOF # running in background with nohup cd ~/Projects nohup horovodrun -np 4 -hostfile myhostfile python3 tensorflow2_keras_mnist.py & cat ~/Projects/nohup.out exit # create folder in non-nfs ext4 partition folder if running in nodes other than pi01 mkdir -p ~/horovod ssh pi01 'mkdir -p ~/horovod' ssh pi02 'mkdir -p ~/horovod' ssh pi03 'mkdir -p ~/horovod' ssh pi04 'mkdir -p ~/horovod' # When running in pi02, pi03 and pi04, it cannot start in the nfs shared folder if it is not an ext4 partition. # e.g. when start in pi03 ssh pi03 cd ~/horovod horovodrun -np 4 -hostfile ~/Projects/myhostfile python3 ~/Projects/tensorflow2_keras_mnist.py # run it with horovod and time and redirect outputfile to keras_mnist.np4.out cd ~/horovod nohup bash -c 'time horovodrun -np 4 -hostfile ~/Projects/myhostfile3 python3 ~/Projects/tensorflow2_keras_mnist.py' &> keras_mnist.np4.out & # The time for number of nodes for this testing nohup bash -c 'time horovodrun -np 4 -H pi01:1,pi02:1,pi03:1,pi04:1 --output-filename logs python3 ~/Projects/tensorflow2_keras_mnist.py' &> nohup.out.np4_1111 & nohup bash -c 'time horovodrun -np 3 -H pi01:1,pi02:1,pi03:1 --output-filename logs python3 ~/Projects/tensorflow2_keras_mnist.py' &> nohup.out.np3_111 & nohup bash -c 'time horovodrun -np 2 -H pi01:1,pi02:1 --output-filename logs python3 ~/Projects/tensorflow2_keras_mnist.py' &> nohup.out.np2_11 & nohup bash -c 'time horovodrun -np 1 -H pi01:1 --output-filename logs python3 ~/Projects/tensorflow2_keras_mnist.py' &> nohup.out.np1_1 & nohup.out.np4_1111:real not yet done (may be 50m) nohup.out.np3_111:real 88m13.692s nohup.out.np2_11:real 129m11.322s nohup.out.np1_1:real 207m28.119s


Some shortcuts

shell script    Select all
# Offending ECDSA key # Offending ECDSA key in $HOME/.ssh/known_hosts:5 # For Mac sed sed -i '' '5d' $HOME/.ssh/known_hosts # For GNU sed sed -i '5d' $HOME/.ssh/known_hosts # print line 5 to 6 of a text file sed -n '5,6p' $HOME/.ssh/known_hosts # print line 1 and Line 5 to 6 of a text file sed -n -e '1p' -e '5,6p' $HOME/.ssh/known_hosts # add all the hosts to the ~/.ssh/known_hosts file using ssh-keyscan # first login pi01 10.0.1.101 ssh pi@10.0.1.101 ssh-keyscan -t rsa,dsa pi02,pi01,pi04 > ~/.ssh/known_hosts






No comments: