加入truenasseeker章节和启动顺序调整章节

This commit is contained in:
gaolifeng
2022-10-14 12:25:31 +08:00
parent db2d8573d1
commit 64e2cf069b
4 changed files with 164 additions and 1 deletions

View File

@@ -333,7 +333,8 @@ TrueNas:
服务主机ubuntu:
- [使用setup_aquar.sh脚本进行环境初始化](./details/使用setup_aquar.sh脚本进行环境初始化)
- 设置docker-compose等待nfs挂载后再启动
- [设置docker-compose等待nfs挂载后再启动](./details/设置docker-compose等待nfs挂载后再启动.md)
- [使用truenasseeker.py脚本自动扫描nfs服务并挂载](./details/使用truenasseeker.py脚本自动扫描nfs服务并挂载.md)
Windows虚拟机:

View File

@@ -0,0 +1,40 @@
如果你遇到了搬家或者更换路由器的情况,你网络中所有的设备都会失去原有的IP地址,这会导致Aquar中各个子系统间原本建立起来的关联会全部失效。
truenasseeker.py脚本就是用来解决这个问题的。它在每次开机时会检查系统是否有效地挂载了`/opt/aquar/storages/aquarpool`目录,如果这个目录没有正常挂载,则会载局域网中扫描truenas主机,并修改ubuntu的nfs配置为最最新地址,然后重新挂载这个这个地址。
如果你已经部署了truenasseeker.py但在网络变动后发现docker应用中的存储池数据仍然不见了,你可以在ubuntu控制台上以超级用户执行一次`aqserv restart`命令,或者干脆重启一次机器,再看存储池内容是否恢复了。
1.`sudo -i`切换超级用户。
2.安装依赖的软件包。
```shell
apt install -y nmap
pip install scapy python-nmap pyfunctional
```
3.将truenasseeker.py脚本拷贝至`/opt/aquar/src`路径下。
你可以尝试执行`python3 /opt/aquar/src/truenasseeker.py`命令运行一次看是否会出错,正常情况下它会输出"truenas seeker is no need to do anything."
4.创建`/usr/lib/systemd/system/trunas-scan.service`配置文件,配置内容如下:
```
# [Unit]
# Description=scan local network for truenas
# After=docker.service opt-aquar-storages-aquarpool.mount
#
# [Service]
# Type=simple
# User=root
# ExecStart=python3 /opt/aquar/src/truenasseeker.py
#
# [Install]
# WantedBy=multi-user.target
```
5.执行`systemctl daemon-reload`重载系统服务。
6.执行`systemctl enable trunas-scan.service`将脚本设置为开机启动。
7.执行`systemctl status trunas-scan.service`查看服务状态是否为enabled。如果是,则代表脚本正常部署了。

View File

@@ -1,5 +1,7 @@
设置docker-compose等待nfs挂载后再启动
默认情况下docker-compose中的服务和nfs挂载动作的执行是不区分先后顺序的,这会导致开机以后docker服务已经启动但nfs挂载点未就绪,于是在docker应用中就无法正常的看到存储池中的文件了。所以这一步是必不可少的。
1.执行`sudo -i`进入管理员角色
2.执行`systemctl list-units | grep mount`寻找与fstab中配置对应的信息

120
files/truenasseeker.py Normal file
View File

@@ -0,0 +1,120 @@
#! /usr/bin/env python
# vim: set fenc=utf8 ts=4 sw=4 et :
# apt install -y nmap
# pip install scapy python-nmap pyfunctional
# -------/usr/lib/systemd/system/trunas-scan.service--------
# [Unit]
# Description=scan local network for truenas
# After=docker.service opt-aquar-storages-aquarpool.mount
#
# [Service]
# Type=simple
# User=root
# ExecStart=python3 /opt/aquar/src/truenasseeker.py
#
# [Install]
# WantedBy=multi-user.target
from __future__ import absolute_import, division, print_function
import logging
import scapy.config
import scapy.layers.l2
import scapy.route
import math
import os
import getopt
import sys
import shutil
import re
import nmap
from functional import seq
logging.basicConfig(format='%(asctime)s %(levelname)-5s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
logger = logging.getLogger(__name__)
nm = nmap.PortScanner()
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))
def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
logger.warning("%s is too big. skipping" % net)
return None
return net
def scan():
if os.geteuid() != 0:
print('You need to be root to run this script', file=sys.stderr)
sys.exit(1)
for network, netmask, _, interface, address, _ in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
# skip docker interface
if interface.startswith('docker') or interface.startswith('br-') or interface.startswith('tun'):
logger.warning("Skipping interface '%s'" % interface)
continue
net = to_CIDR_notation(network, netmask)
nfsAddress = None
if net:
ipInfo = nm.scan(hosts=net, arguments='-p 22,80,111,139,443,445,8006,8008,8081,8384')
resList = seq(list(ipInfo['scan'].items())).map(lambda i: (i[0],seq(list(i[1]['tcp'].items())).filter(lambda p: p[1]['state'] == "open").map(lambda pi: pi[0] )))
for res in resList:
logger.info("%s: %s" % (res[0],res[1]))
if 22 not in res[1] and 80 in res[1] and 111 in res[1] and 139 in res[1] and 443 in res[1] and 445 in res[1]:
nfsAddress = res[0]
return nfsAddress
def checknfs():
return os.path.ismount('/opt/aquar/storages/aquarpool')
def updatefstab(nfsAdress):
shutil.copy('/etc/fstab', '/etc/fstab.bak')
fstabFile = open("/etc/fstab", "r+")
configText = fstabFile.read()
prepart = re.split("##\[aquar config start\]##", configText)[0]
postpart = re.split("##\[aquar config end\]##", configText)[1]
nfsConfig = "\n##[aquar config start]##\n %s:/mnt/aquarpool /opt/aquar/storages/aquarpool nfs defaults,_netdev 0 0\n##[aquar config end]##\n" % nfsAdress
logger.info("new nfs config:")
logger.info(nfsConfig)
newConifg = prepart + nfsConfig+ postpart
logger.info("fstab now is:")
logger.info(newConifg)
fstabFile.seek(0)
fstabFile.write(newConifg)
fstabFile.truncate()
fstabFile.close()
if __name__ == "__main__":
print('truenas seeker starting.')
if not checknfs():
print('truenas seeker find nfs directory is broken, trying to find truenas in local network.')
nfsAddress = scan()
updatefstab(nfsAddress)
print('truenas seeker updated fstab succesfully.')
os.system("mount -a")
print('truenas seeker has remounted fstab.')
else:
print('truenas seeker is no need to do anything.')