VirtualBox 搭建 CentOS 7 集群

软件开发时我们可能需要集群环境,特别是现在微服务很流行的情况下。如果我们手里的电脑配置不错就可以用 来搭建集群,用于学习或开发还是很不错,性价比很高。

我这里是用 VirtualBox 搭建 CentOS 7 集群,宿主机是内存 16 GB 加 SSD 1 TB 的 MacBook Pro。集群的核心是选择网络模式,VirtualBox 的网络模式概况如下:

Mode VM -> Host VM <- Host VM1 <-> VM2 VM -> Net/LAN VM <- Net/LAN
Host-only + + + - -
Internal - - + - -
Bridged + + + + +
NAT + Port forward - + Port forward
NAT service + Port forward + + Port forward

我希望集群的机器可以互相访问并能访问网络,从上面的列表可知,我们可以选择 Bridged,或者 NAT service 搭配 Port forward。在搭建之初,我搜索了相关的资料,但是并没找到特别理想的,这篇 Setting up CentOS 7 nodes 勉强还凑合,于是我主要参考它来搭建,网络模式也同样是选择的 Bridged,它还使用了双网卡,虚拟机之间通信使用的 Internal Networking, 感觉上性能可能会好点,没实测。双网卡并不是必须的,VirtualBox 对 Internal Networking 的说明是其在安全方面更有优势:

Even though technically, everything that can be done using internal networking can also be done using bridged networking, there are security advantages with internal networking. In bridged networking mode, all traffic goes through a physical interface of the host system. It is therefore possible to attach a packet sniffer such as Wireshark to the host interface and log all traffic that goes over it. If, for any reason, you prefer two or more VMs on the same machine to communicate privately, hiding their data from both the host system and the user, bridged networking therefore is not an option.

由于 CentOS 主要是运行服务,我们可以使用 Minimal 安装,这样可以减少资源开销,安装好后,默认是没有启用网络的, 网络相关的配置是在 /etc/sysconfig/network-scripts 目录下,配置文件的命令惯例是 ifcfg-enp0sXX 是整数,我这里是 ifcfg-enp0s3 和 ifcfg-enp0s8,将 /etc/sysconfig/network-scripts/ifcfg-enp0s3/etc/sysconfig/network-scripts/ifcfg-enp0s8 中的 ONBOOT 改成 yes

构建 Internal Network 时,手动去指定 ip 会很麻烦,VirtualBox 给了我们另一个选择:

Unless you configure the virtual network cards in the guest operating systems that are partici- pating in the internal network to use static IP addresses, you may want to use the DHCP server that is built into Oracle VM VirtualBox to manage IP addresses for the internal network.

我们可以 10.0.0.0/8, 172.16.0.0/12192.168.0.0/16 选择一个合适的私有 ip 地址范围来构建 Internal Network,我这里选择 172.16.0.0/12

在宿主机下运行命令 /Applications/VirtualBox.app/Contents/MacOS/VBoxManage dhcpserver add --netname=intnet --server-ip=172.16.0.1 --netmask=255.240.0.0 --lower-ip=172.16.0.2 --upper-ip=172.16.255.255 --enable 创建好 DHCP server。

之后我们可以利用 VirtualBox 的克隆功能来扩展我们的集群节点。

修改记录

  • 2021/10/21:第一次完成

Reference

记一次 Docker 网络问题排查

最近在学 docker,虽然很早之前就简单体验过一次,但限于时间没有深入,最近有点空余时间,于是准备深入学习一下。但没想到一开始就遇到了拦路虎,照着官方文档 Get Started 一步一步往下,在构建一个自己的镜像时就遇到了问题,在多容器之间也无法通信,这可愁坏我了,只能硬着头皮来排查问题。

构建镜像时问题表现是牵涉到连接网络的命令会失败,google 一圈之后,找到使用 --network=host 的偏方,成功绕过问题。而多容器之间无法通信却一时措手无策。现在就只有 --network=host 这一个线索,于是就想加上这个参数后有什么区别呢?

在官方文档上搜寻一圈之后我没查到有用信息,于是我想相关的书可能会讲讲 docker 网络这块,在微信读书上找了杨保华、戴王剑和曹亚仑合著的《Docker 技术入门与实战(第3版)》。因为 docker 技术在快速发展,所以书中的命令与当前版本有些许差异,但问题不大,不妨碍理解。这本书有两节专门介绍 docker 网络,于是我便先看了这两节,从这里得到一条重要线索:docker 和宿主机的通信是依靠防火墙转发。--network=host 也验证了这条线索,加上这参数会直接使用宿主机的网络配置,这样 docker 和宿主机的通信就不需要防火墙转发了。

问题现在定位到了防火墙,那么为什么防火墙不转发 docker 的网络数据包呢?是不是哪条防火墙规则没配对?另外我还怀疑是不是我的实践环境有问题?我的实践环境是这样的:物理主机是 macOS,上面安装 virtulbox,使用 virtulbox 创建了一个 CentOS 8 的虚拟机, 虚拟机的网络模式是 NAT。这种情况无疑增加了问题排查的难度,怎么来排查呢?

我先看了一下 virtulbox 的用户手册中的网络模式介绍,NAT 是可以连接到宿主机,而且现在虚拟机是可以访问网络的。如果想快速定位问题,我想还得从网络请求的数据包入手,想办法来跟踪数据包。

于是就来查怎么调试 iptables。查到可以通过 TRACE 和 LOG 来输出日志,看介绍也没看出这俩有什么区别。凭经验觉得 TRACE 好像比 LOG 后出来,看起来也高大上一点,先试着用 TRACE 。Google 了一圈,找到都是 CentOS 6 或 CentOS 7 相关的配置,也只能先将就着用吧。

我先是参考的 CentOS implements iptables log output and debugging through raw table

1
2
$sudo modprobe ipt_LOG
$sudo sysctl net.netfilter.nf_log.2

输出的结果是 NONE,于是尝试显示设置 sudo sysctl net.netfilter.nf_log.2=ipt_LOG

继续阅读

UI 设计与屏幕适配

目前移动设备的尺寸很多,所以前端 (iOS, Android, Web, 小程序等)开发需要适配多种尺寸屏幕。在适配时我们可能会有困惑,设计稿通常是 px 来表示尺寸,设备的分辨率也是以 px 来表示,它们之间是一样的吗?还是存在什么关系?iOS 开发者用 point 来表示视图的尺寸; Android 开发者用 dp 来表示视图尺寸; Web 开发者用 px 来表示尺寸?它们和设计稿的 px 是什么关系?设计师应该以什么基准尺寸来设计会有利于屏幕适配?应该输出几套切图?除了切图,设计师还可以做些什么来配合开发者做屏幕适配?要搞清楚这些问题,我们需要翻翻历史了。

Tim Chien 和 Robert Nyman 的这篇 CSS Length Explained 帮了我的大忙,本文就是基于它而写成。

英寸

我们经常是用英寸为度量单位来表示手机屏幕尺寸,一英寸相当于2.54厘米或0.0254米。

设备像素(device pixel)

计算机屏幕显示事物的单位是像素。显示屏上的单个物理 “光点",能够独立于它的邻居显示出完整的颜色,被称为像素(图片元素)。我们把屏幕上的物理像素称为 "设备像素"。

DPI, PPI

DPI 是 dots per inch 的英文缩写,即每英寸点数; PPI 是 pixels per inch 的缩写,即每英寸像素。 它们都用来表示显示像素密度 (Display pixel density)。

计算机屏幕是由大量发光二极管整齐排列构成的集成电路,由于屏幕制造商工艺水平差异,每英寸集成电路上排列的二极管的数量会不一样,屏幕出厂时我们可以从厂商那里得知屏幕的 PPI。

于是我们可以知道:

1
width or height of one device pixel = 1 / device's DPI  

例如 MacBook Air(2011) 的 DPI 为 125 , 所以:

1
(width or height of one device pixel) = 1/125 inch = 0.008 inch = 0.02032 cm
继续阅读