無標題文檔

Clear Linux 下 KVM 硬件直通配置

前言

Clear Linux 是针对 Intel 平台的滚动 Linux 发行版。它有很多优势,我个人目前主要用来针对老机型(四代酷睿平台)的裸机运行平台,并主要用来跑虚拟机。

由于 Clear Linux 是过于强调精简的发行版,因此配置方面需要额外的精力,所在这里针对 KVM 虚拟机的配置做个记录。

BIOS 配置

针对硬件直通这块,首先需要 CPU 的支持,四代平台支持 VT-D 功能的不多,主要集中在 i5、i7 的 CPU。个人购买过四代 i3 的 CPU 发现并不支持硬件直通,所以又退款换货非常的折腾。

了解了支持的 CPU 以后,然后在 BIOS 中对应的开启虚拟化以及 VT-D,这里就不表。

内核配置

和其他的发行版不同,Clear Linux 的引导器是 Intel 自己研发的 clr-boot-manager。内核的参数文件具体的文件路径在 /etc/kernel/cmdline.d/ 这个目录中,然后对应的示例文件 iommu.conf:

intel_iommu=on iommu=pt vfio_iommu_type1.allow_unsafe_interrupts=1 vfio-pci.ids=<id>,<id>

这个 ID 是 PCI ID,对应的可以使用 lspci -nn 获得,例如列出网卡的 PCI ID:

$ lspci -nn | grep -i Ether
00:19.0 Ethernet controller [0200]: Intel Corporation Ethernet Connection I217-V [8086:153b] (rev 04)
02:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533] (rev 03)

同时,需要注意的是 IOMMU Group 分组是否在一个组中(这个可能需要 PCI 设备的支持),可以使用以下简单的 Shell 脚本查看(来自 Arch 的 Wiki):

#!/bin/bash
shopt -s nullglob
for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;

然后,使用 clr-boot-manager update 生成启动配置,然后 reboot 重启后查看 cat /proc/cmdline 内核引导参数是否已经生效。

Qemu 配置

查看 Qemu 下 PCI 的设备列表,例如

$  virsh nodedev-list | grep pci
pci_0000_00_00_0
pci_0000_00_02_0
pci_0000_00_03_0
pci_0000_00_14_0
pci_0000_00_16_0
pci_0000_00_19_0
pci_0000_00_1a_0
pci_0000_00_1c_0
pci_0000_00_1c_3
pci_0000_00_1d_0
pci_0000_00_1f_0
pci_0000_00_1f_2
pci_0000_00_1f_3
pci_0000_02_00_0

那么根据对并上面

$ lspci -nn | grep -i Ether
00:19.0 Ethernet controller [0200]: Intel Corporation Ethernet Connection I217-V [8086:153b] (rev 04)
02:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533] (rev 03)

两块网卡的 ID 分别为 pci_0000_00_19_0 和 pci_0000_02_00_0 ,然后我们 dump 出配置来

$ virsh nodedev-dumpxml pci_0000_00_19_0
<device>
  <name>pci_0000_00_19_0</name>
  <path>/sys/devices/pci0000:00/0000:00:19.0</path>
  <parent>computer</parent>
  <driver>
    <name>vfio-pci</name>
  </driver>
  <capability type='pci'>
    <class>0x020000</class>
    <domain>0</domain>
    <bus>0</bus>
    <slot>25</slot>
    <function>0</function>
    <product id='0x153b'>Ethernet Connection I217-V</product>
    <vendor id='0x8086'>Intel Corporation</vendor>
    <iommuGroup number='4'>
      <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
    </iommuGroup>
  </capability>
</device>

例如以上就可以 dump 出具体 PCI 信息的来,可以比较直观的看到 product id 以及生产商 vendor id 等信息。这里需要的几个参数分别是 domainbusslot、以及 function

我们分别记录下来,然后填写到以下的 xml 片段中,例如上面对应的数值就是

<hostdev mode='subsystem' type='pci' managed='yes'>
  <driver name='vfio'/>
  <source>
    <address domain='0' bus='0' slot='25' function='0'/>
  </source>
</hostdev>

可以直接使用十进制数值,因为 virsh edit 在编辑保存的时候会自动计算其原始的十六进制数值。

验证

使用 virsh edit 编辑对应的虚拟机配置,例如 virsh edit <my-machine> 。在编辑器中将上述 的 xml 粘贴入 devices 这个 xml 块中,保存关机然后在启动虚拟机即可生效。

在启动虚拟机以后,例如上述的网卡直通可以使用 ip a 等命令查看虚拟机有无识别到对应的物理网卡。如果一切顺利,那么就可以使用对应的网络配置程序来配置对应网卡的网络信息,这里不在复述。

常见问题

  1. 查看 IOMMU Group 中的设备是否分别在不同的组中,如果多个设备在同个组中,则需要额外的操作(参见 Arch Wiki 的内容);
  2. 如果物理机设备被直通出去,那么就无法使用该设备以及设备树下的子设备。例如,如果直通 USB 控制器给虚拟机,那么这个控制器下的键盘、鼠标都只能在虚拟机下使用;
  3. 直通的内核模块应该优先于其对应的物理设备驱动,否则会造成冲突造成无法直通,因此可以考虑搭配内核 blacklist 使用。

最后,如果服务器是 Intel 平台的,强烈建议尝试下 Clear Linux 你会爱上它的!

参考信息

精简 BASH/ZSH 的条件判断

这个小技巧来自 Youtube 上的个视频,很受用所以记录下。很多时候我们写的 Shell 脚本,都会前置些判断条件,以便正确执行想要的结果,例如:

if [ -x $(which vim) ]; then
    export EDITOR="vim"
fi

这样子写当然没有任何的问题,而且看起来就很直观。但是如果吹毛求疵的话,发现这样子的判断有点繁琐,同时会在写更复杂的 Shell 的时候,会增加更多的判断,这样子会造成整个 Shell 脚本非常的繁琐以及臃肿。

例如,我们可以阅读 neofetch 的源代码,这个脚本用于探测目标系统未知的情况下,获取对应的值,因此其会有非常多的条件判断。

BASH Script

这个例子可能会比较极端,那问题凸显得很明显。那么这种情况下,如何去优化自己的 Shell 代码呢?

首先我们要从返回值说起,我们都知道我们执行的每条 Shell 语句其实都有返回值。一般来说,返回 0 表示正常,返回非 0 表示这条语句可能会有问题。

我们如下做个尝试:

BASH Script

然后,通常我们写的条件判断,其实就是根据返回值的判断这个条件是否成立,下面是我们常见的「与、或、非」的判断:

BASH Script

那么其实我们可以知道当不同的逻辑判断,它们执行的顺序是不一样的。例如,我们需要「与」判断则需要将所有的条件语句都运行完毕,而「或」判断则只需要其中的一条语句满足条件即可(「非」也是类似)。

那么作为条件判断的例子,可以直接写为:

BASH Script

然后,我们将上面的代码结合起来,我们可以写成这个样子:

[ -x $(which vim) ] && export EDITOR="vim"

因为它们之间的条件其实是「与」的关系。然后,我们再多些例子看看这样子的写法是不是对应的精简了很多:

if [ ! -x $(which vim ) ]; then
  exit -1
fi

对比

[ -x $(which vim ) ] || exit -1 # 注意这里的「非」的用法

如果是多条语句,那么可以使用代码块的方式(在 Shell 里面其实就是个函数):

[ -x $(which vim ) ] && {
  export EDITOR="vim"
  echo "vim is installed"
}

既然引入了代码块,那么我们可以用更复杂的用法了,例如可以将两个代码块(函数)结合起来,这样子就可以写出非常短小精悍的条件判断:

{ cmd not found } || { echo "prev statment return value is \$?" }

看起来稍微有点复杂,但又带来了更多的内容:

  1. 你可以将两个代码块(函数)使用逻辑操作符链接起来;
  2. 后面的代码块可以接收前面代码块最后一条语句的返回值。

总体来说,这个小技巧可以精简不少的条件判断的代码,尤其在初始化的时候看起来非常的直观。

不过和很多的技巧一样,我们还是需要酌情的使用它,毕竟代码和脚本的可读性是放在第一位的。

- eof -

家里的内网开发环境(概述)

家里的开发环境越来越复杂了,所以需要复盘和回顾下目前的情况。这个得先从头开始说起:

Stage 1

Stage 1

应该说很上古的时期,和大部分开始的需求一样,需要离线跑些脚本。那时候我简单选用了台树莓派跑 NPM 的些代码。在很长的一段时期内它能很好的满足需求,因为只需要跑些爬虫和通知性质的脚本。

Stage 2

Stage 2

随着任务的增加,树莓派的性能瓶颈越发的明显,因为 NPM 的项目基本上都是些零散的小文件,tf 卡在 4k 的读取方面性能非常的弱。这时候开始考虑使用台「正儿八经」的 x86 小机子用来跑繁重的任务,技术栈这块也切换到了 Golang 以及 Python,而树莓派则退居二线作为通知和监控使用。

再后来数据量越来越「庞大」,达到了几百个 G 的级别,M93P 的硬盘容量明显不够了(SSD 256G、机械硬盘 1T)。加上对于数据安全性方面的考虑,购买了两块 2T 的硬盘以及 USB 的磁盘阵列盒子。

Stage 3

Stage 3

随着数据量的增加,我很快发现数据这块有了冷热的区别。同时,部署的环境也越来越复杂,虽然使用 Docker 搭配 docker─compose 也能很好的完成集成和部署,但在各个应用之间来回的切换 docker─compose 的目录让人感到非常的头痛和麻烦。

所以这时候在操作系统层面加上了 KVM 虚拟机这层,然后再再虚拟机上面跑 Docker。本来考虑上 K8S,但是其实各个应用之间是相对独立的关系,因此还是以单独虚拟机为单位分类各个应用的类别。

Stage 4

Stage 4

不过数据还是在不断的增加,我考虑到 USB 的磁盘阵列盒虽然能够满足目前的需求,但是横向的扩展性以及应用和数据分离做得还不够彻底,因此将数据这块单独部署了台 NAS 去处理

组装这台 NAS 其实走了很多弯路,硬件方面一开始用的是台盘位的 PC 机箱,但是很快发现非常不合适放在家里,一来机箱的体积太大了二来功耗也非常的大但是只能最多安装两到三块的硬盘。

和很多「垃圾佬」一样考虑过星际蜗牛的主机,四盘位的机箱加上 J1900 的四核低功耗的处理器,很适合用来做网络存储。但是还是考虑到数据的重要性,还是选择了单独的四盘位的机箱以及性能相对好点的 AMD 集成主板作为平台使用。

存储的选型方面一开始使用 CentOS + 阵列卡的形式,后面切换到了 FreeBSD + 直通卡配合 ZFS 的方式,各有优劣和千秋这里不展开详细的说明。

Stage 5

Stage 5

于是乎硬件和虚拟机的节点越来越多,怎么去治理和监控就成了纠结的事情了。还有因为国内网络环境的问题,所以我在网络这块考虑使用了 N1 作为旁路由和透明网关作为国际网络加速。原先的树莓派也替换为 N1 同时部署了 Grafana 以及 Prometheus 作为节点的监控和报警

服务发现这块选用了 Consul 和 DNSmasq 汇聚,这样子每个节点启动自举的时候,就可以在内网环境拿到对应的域名而不用去找 IP 地址,很方便。

Stage 6

Stage 6

基础环境搭建好了以后,逐渐的装了 Syncthing、Gitea、Drone 等用于数据同步以及测试代码的托管和 CI。由于测试数据的量逐渐的收敛了下来,所以很多时候 Runner 在空闲的状态,但随时可以调用很方便了。

硬件方面主要是有些补足的设备,例如我后面又购置了台瘦客户机装了 FreeBSD 用来实时给 macOS 做时间胶囊备份使用。

同时,买了两台 UPS 以及写了些对应的脚本,用于在断电的时候主动关机。

@TODO

@TODO

前几天从 @yff666 那边得到块星际蜗牛的「遗产」,组了台双盘位的 Raid1 小 NAS 主机,打算用来存冷数据,不过这块的数据需求还是要看目前的业务情况。

监控这块我觉得还有比较短板的地方,例如如果家里网络不通则无法收到通知邮件了,这里想考虑使用台 Android 手机配合 adb 发送短信,后面想好了再继续做吧。

- 待续 -

随忆 FreeBSD

Install FreeBSD

趁在隔离的空档期间组了台 NAS,自然而然的安装了 FreeBSD 和将数据拜托给了 ZFS。时间过得很快,回想接触这个系统已经有十几年的时间了。

初次接触 FreeBSD 还是在大学的时候,那时候自己的 MMX 166 笔记本装的还是 Slackware、实验室有台机子装的是 FreeBSD 4。由于次意外的断电,实验室的这台机器由于硬盘故障无法启动,当时作为兼职的运维只能我先去看看能不能解决。

那时候 FreeBSD 直观的印象其实很初步,就是配置方面和 Slackware 差不多,同时也体验到了 ports 的好处,就是至少不用像 Slackware 一样满世界的找 tar.gz 包了。

那时候「水云间」的 BSD 板块还是比较热闹的学术氛围浓厚,上面有各种各样的「奇迹淫巧」各种各样的 shell 脚本和配置文件。那时候的我们年轻而且还气盛,和争论 Vim、Emacs 哪个好一样,争论 GNU/Linux 和 BSD 之间孰优孰劣(现在是 Android 和 iOS 了吗?)也是个老生常谈的问题,热闹看得不亦乐乎。

再往后工作了以后就忙碌了很多,去「水云间」的日子也少了。在本世纪的头个十年,技术方面的发展非常的迅猛,「把玩」技术的时间也不会很多。我的主要系统也从 Slackware 往 Debian 上面迁移到后面买了台 Mac 就一直用 macOS 至今。

FreeBSD 的发展也是一路过来,版本从 4 一直到现在的 12,还是一路保持着 KISS(keep it simple, stupid)原则。当然FreeBSD 的「Simple」其实不是「简单」的意思,而是简洁。

安装好新的系统以及软件包以后,只需要拷贝应用的配置以及 /etc/rc.conf 还有 /boot/loader.conf 就可以直接投入使用。

开玩笑的说,这类的 BSD 系统是努力让管理员尽可能的快的遗忘掉它,因为知道使用 FreeBSD(以及 BSD 系列)的管理员,是知道拿它去做什么的。

所以这也是为什么眼看着份额却越来越低使用得人甚至讨论的人也是越来越少,而 FreeBSD 还存在的原因之一吧,哈哈。

的确 FreeBSD 从学院的背景走出来,很多地方不像 Linux 那么「分裂」以及「随意」,所以在 FreeBSD 安装盘里面有很多「年代感」的文件(所谓的传承?)。

FreeBSD 还是会时不时得给我些「小惊喜」。回到我的那台 NAS 上,我曾经需要给阵列卡加上监控和配置。LSI 厂商其实提供了 MegaRaid 等工具,在 FreeBSD 下其实官方已经提供了 mfiutil 这类的工具可以直接使用,同时参数和命令比 MegaRaid 更加的清晰。

FreeBSD 的在这个方面做得是两个极端,要么就是没有提供任何的支持,要么就是有非常完善的 Manual 以及 Handbook 说明。同理,对于 ZFS 方面的支持也是类似。除去协议方面的问题先不谈,我保守得至今还不敢在 Linux 生产环境下使用 ZFS,这已经是我的个固有的印象,而 FreeBSD 能做到开箱即用。

FreeBSD 的 slogan 现在变成了「The power to serve」。但 Linux 在应用层面 Docker 以及 K8S 等工具完全改变了传统运维的方式,这我在 FreeBSD 下是没有找到任何与之对比的杀手锏的(你问我 Jail?凑合吧…)。

在我看来,未来 FreeBSD 相对 Linux 应该更加下沉,无法让应用开发接触到了。它在底层存储、数据库、防火墙和网关还会继续占有一定的使用场景。对对,如果你说 macOS 甚至 Switch 也是 FreeBSD (或者和它有关系)的话。

FreeBSD 除了在特定场景下的优势,我个人对于 FreeBSD 的情感甚至可以说情怀,也是让我继续使用这个系统的原因。好比上面说的你十几年前的 rc.conf 不加修改扔到最新版本的 FreeBSD 还能兼容一样,当全部初始化时候出现 login 提示,这一切都给人感觉通过时间沉淀已经升华到另外一样东西了。

前几天,在之乎上看到个问题「现在使用 FreeBSD 是一种什么样的体验」、「现在学 FreeBSD 有必要吗」等等,只能轻轻的笑笑。其实,正式知道和使用 BSD 这些系统的人,基本上都是那些已经年过三十正在慢慢失去了折腾的时间和精力,或者已经在办公室里拿着保温杯泡着枸杞看着 KPI 担心脱发的那帮人了吧。

回想起如果那个下午没有意外的断电,可能就不会接触 FreeBSD 更不会有十几年的陪伴。但现在看过来,还是不后悔时间花在每次 /usr/ports 目录下等待 make install 完成屏幕暂停的时候吧。

因为,FreeBSD 以及 Slackware、Makefile、Vim… 等这些名词,毕竟是我的青春呀,笑(

- eof -

Dell PowerEdge H700 硬件阵列卡折腾记录

原先家里的网络存储这块比较松散,一台主机连接了个 USB3.0 的磁盘阵列盒做了个 Raid1 ,加上另外台机子使用的是基于 Linux 的软 Raid 组合,非常不利于管理和监控状态。

于是考虑组建个比较中心化的 NAS 来统一管理以及扩大存储这块的容量。

在某宝上研究了下,发现硬件这块的 Raid 卡普遍比较流行的是基于 LSI 芯片的方案。但性价比不是很好,稍微符合支持缓存、BBU 以及状态支持的都要四五百甚至网上(要知道蜗牛等矿难主机大概也就两三百)。

和店家聊了下需求以后,发现有一款 Dell PowerEdge H700 的阵列卡比较符合我的要求,同时价格相对来说比较便宜,带 1G 缓存支持 BBU 和 CadeCache 的只要两百人民币不到的价格。

阵列卡外观

阵列卡设置界面

到手安装上去以后,发现兼容性一般来说问题不大,经过我手的几块四代主板都可以支持(Q87、Z97系列芯片组)。可能是针对服务器设计的缘故,唯一的不好就是虽然带了块散热片但发热还是会让人担忧(红外测试了下,待机温度要六七十以上)。

所以我给它换了散热硅脂、加了块散热片(在缓存主控上),同时再从某宝上淘了个涡轮风扇对着板卡吹。经过这样子的改造待机温度基本上在三四十的样子比较符合预期,稳定性这块还是需要长时间使用下来再观察。顺便说下,涡轮风扇的转速通常比较高,对于噪音有要求的同学建议加根降压线。

Dell PowerEdge H700 基于 LSI 的芯片方案,因此可以直接使用 LSI MegaCli 的应用软件,无差别。软件方面,宿主机安装的是 CentOS,可以根据 Arch 的 AUR 脚本直接拿到 RPM 安装包本地安装。

注意,测试过其他的发行版(例如 Fedora)需要安装 ncurses5-compat-libs 这个软件包才能正常的运行主程序。

FreeBSD 下的安装也是比较方便,直接根据对应官方网站的安装即可,具体参见官方文档。

吐槽下 MegaCli 这个应用软件反人类的地方,首先先不说比较奇葩的安装位置 /opt/MegaRAID/MegaCli/MegaCli64 ,单从参数来说想要查看 --help 直接跑起来也是比较困难的事情(具体参考常用的命令)。

所以又从 Github 上找到了个 MegaCli 的 Warpper,扩展了下这个小应用(最后更新竟然在 2015 年),用于格式化输出(JSON 格式)以及方便监控。

Grafana 界面

最后,放张 Grafana 监控的图,这样子基本上就可以日常使用了。用了四块 2T 的硬盘组 Raid6、两块 Intel 的 SSD 组 Raid1 作为系统盘,同时加了块上古的三星 SSD 作为 CacheCade 盘。

除了硬盘总计硬件的成本大概两百不到,就可以享受硬 Raid 带来的方便了。修改以后的源代码在 https://github.com/mingcheng/megaraid ,欢迎随时交流。

- eof -

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 要知道作为码农取名是件很难的事情,所以不想在取名这事情上太费心思。

作为八零后,自认为还仅存点点可能不怎么被理解的幽默感,以及对平淡生活的追求和向往。 为了避免不必要的麻烦,声明本站所输出的内容以及观点仅代表个人,不代表自己所服务公司或组织的任何立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

分类

搜索

文章