Home Lab Setup 2021

Golang builder

Setup

2020 年对于全世界真的是难熬的一年,对于我个人也一样。病痛的折磨,各种意外,各个城市的辗转和奔波,每一件事情都像脸上叠加的一层层口罩,闷得我喘不过气来。

是时候做点事情了,忙起来才能忘掉这些糟心的事情。打造一个 home lab 是我一直想做的一件事情,新的一年, 我打算从它开始:

为啥要搞 home lab:

  • 方便测试一些工作和兴趣上的东西
  • 优化家庭网络,增强其扩展性
  • 现代化的生活少不了一些硬件,集中管理这些硬件势在必行
  • 为开源社区提供计算力

2021 年元旦开始在家部署自己的 home lab,从网上花了几百元买了个 800 mm 深,22 U 高的机柜,因为原本计划打算能放下类似 Dell R420 这样 600 多毫米深的服务器(其实想多了 T_T)。又碰上家里墙上的网口坏了,走明线着实是我不能接受的,打电话询问了下上门维修服务,得知上门费就要 100 元,于是一个人跑到隔壁村子里买了个网线钳(35 元)和墙上的水晶插排(8 元/个),最后还让老板免费送了两个水晶头。回到家各种修,顺便又把大学网线的线序复习了一遍。终于,从联通光猫到书房的网线通了,书房接了无线路由器(只做网络交换、DHCP 中继和 wifi 功能),从书房路由器进入机柜,机柜里准备了一个 8 口的二层交换机。所有内网 IP 由联通的光猫下发。

Go builder

机柜走线、电力、网络都搞定了,总得跑点儿什么吧。正好 Go 社区的 Meng Zhuo 同学在帮助社区部署新的给 WSL 用于测试的 builder,于是和他讨论了下,计划在这个 pool 里面加台机器,一方面是参与整个过程来学习了解 Google Golang 的测试 CI 机制和系统,另外也可以给社区贡献一部分计算资源,消除 WSL Pool 的单点和资源消耗问题。于是火速在淘宝下了单, amd64 架构 ASUS PN 系列的 mini 主机,作为常年开机的测试机,性能不用太高,但是功耗一定要小,另外由于是在家中,所以静音也很重要。

买回来机器内置的是 Win 10 Home 版,在某宝便宜购买正版激活码升级为 Pro,因为只有专业版才能使用 WSL 功能 (微软 WSL 安装文档)。接下来的几天一边升级操作系统准备硬件,一边给 golang 的 CI 系统提交变更,周知各位 google 大大要做的变更,得到社区的允许,可惜正好赶上西方的圣诞节和新年,等他们回来已经过去半个月了。

终于在我的各种邮件轰炸下,新的变更部署到 google 服务器了,builder 可以正式上线了,跑了一晚上发现所有的测试的失败了:

 linux-amd64-wsl at c3b4c7093ac46431b6e15cf1979bd9a251a400da

:: Running /tmp/workdir-host-linux-amd64-wsl/go/src/make.bash with args ["/tmp/workdir-host-linux-amd64-wsl/go/src/make.bash"] and env "GO_BUILDER_ENV=host-linux-amd64-wsl" "https_proxy=proxy.baokun.li:8888" "GOROOT=/usr/lib/go" "LESSCLOSE=/usr/bin/lesspipe %s %s" "TERM=xterm-256color" "LESSOPEN=| /usr/bin/lesspipe %s" "USER=root" "GOPROXY=https://goproxy.io,direct" "SHLVL=1" "http_proxy=proxy.baokun.li:8888" "GO111MODULE=on" "XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/go/bin" "MAIL=/var/mail/root" "OLDPWD=/root" "_=/usr/local/build/cmd/buildlet/stage0/stage0" "GO_STAGE0_NET_DELAY=1.6s" "GO_STAGE0_DL_DELAY=500ms" "WORKDIR=/tmp/workdir-host-linux-amd64-wsl" "GOROOT_BOOTSTRAP=/tmp/workdir-host-linux-amd64-wsl/go1.4" "GO_BUILDER_NAME=linux-amd64-wsl" "GO_BUILDER_FLAKY_NET=1" "GOROOT_BOOTSTRAP=/usr/lib/go" "GOBIN=" "TMPDIR=/tmp/workdir-host-linux-amd64-wsl/tmp" "GOCACHE=/tmp/workdir-host-linux-amd64-wsl/gocache"] in dir /tmp/workdir-host-linux-amd64-wsl/go/src

Building Go cmd/dist using /usr/lib/go. (go1.15.6 linux/amd64)
go tool dist: cannot invoke C compiler "gcc": exec: "gcc": executable file not found in $PATH

Go needs a system C compiler for use with cgo.
To set a C compiler, set CC=the-compiler.
To disable cgo, set CGO_ENABLED=0.

僵硬,没有安装 gcc,于是快速登录机器安装 gcc。继续观察发现又失败了。

 .......
ok  	math/bits	0.010s
ok  	math/cmplx	0.010s
ok  	math/rand	0.336s
ok  	mime	0.012s
ok  	mime/multipart	0.141s
ok  	mime/quotedprintable	0.021s
--- FAIL: TestInterfaceMulticastAddrs (0.00s)
    interface_test.go:158: num IPv6 multicast route clones = 0; want >0; summary: &{loop:1 other:1}, &{ipv4:2 ipv6:4}, &{ipv4:0 ipv6:0}
--- FAIL: TestIPConnRemoteName (0.00s)
    iprawsock_test.go:115: dial ip:tcp 127.0.0.1->127.0.0.1: socket: protocol not supported
--- FAIL: TestTCPListener (0.00s)
    listen_test.go:73: skipping tcp  test
    listen_test.go:73: skipping tcp 0.0.0.0 test
    listen_test.go:73: skipping tcp ::ffff:0.0.0.0 test
    listen_test.go:73: skipping tcp :: test
    listen_test.go:91: tcp 127.0.0.1 should fail
panic: test timed out after 3m0s

goroutine 4488 [running]:
testing.(*M).startAlarm.func1()
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1701 +0xe5
created by time.goFunc
	/tmp/workdir-host-linux-amd64-wsl/go/src/time/sleep.go:169 +0x45

goroutine 1 [chan receive, 2 minutes]:
testing.(*T).Run(0xc0004fea80, 0x6b165e, 0xa, 0x6c3d98, 0x48e201)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1240 +0x2da
testing.runTests.func1(0xc000001980)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1512 +0x78
testing.tRunner(0xc000001980, 0xc00012bd68)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1194 +0xef
testing.runTests(0xc00000e048, 0x847160, 0xee, 0xee, 0xbff76019a77735e0, 0x29e930f045, 0x84a920, 0x10)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1510 +0x2fe
testing.(*M).Run(0xc00012e000, 0x0)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1418 +0x1eb
net.TestMain(0xc00012e000)
	/tmp/workdir-host-linux-amd64-wsl/go/src/net/main_test.go:52 +0x39
main.main()
	_testmain.go:589 +0x165

goroutine 609 [chan receive, 2 minutes]:
testing.(*T).Parallel(0xc000662480)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1060 +0x119
net.TestLookupGmailNS(0xc000662480)
	/tmp/workdir-host-linux-amd64-wsl/go/src/net/lookup_test.go:169 +0x45
testing.tRunner(0xc000662480, 0x6c3a10)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1239 +0x2b3

goroutine 610 [chan receive, 2 minutes]:
testing.(*T).Parallel(0xc000662600)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1060 +0x119
net.TestLookupGmailTXT(0xc000662600)
	/tmp/workdir-host-linux-amd64-wsl/go/src/net/lookup_test.go:218 +0x45
testing.tRunner(0xc000662600, 0x6c3a18)
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
	/tmp/workdir-host-linux-amd64-wsl/go/src/testing/testing.go:1239 +0x2b3

goroutine 4312 [chan receive, 2 minutes]:
testing.(*T).Parallel(0xc0004fec00)
	/tmp/workdir-host
.......

哦? 难到是碰见了 go 的 bug 了?,有些测试没过,仔细看了下好像和 IPv6 有关,于是先暂时关闭了服务器上的 IPv6 ,但是后面的报错并没有消失。和 Meng Zhuo 研究了一番发现所有失败都和 kernel 有关系,于是怀疑是 WSL 有问题,经过执行 wsl --list --verbose 发现安装的 ubuntu 是跑在 WSL1 上的,奇怪了,分明是按照文档操作的啊。于是备份数据,尝试重新安装 WSL 2 的 Linux 系统,但是失败了,报了一个莫名其妙的错误,Linux 初始化失败,google 了很久也没有这个错误码,于是尝试重新安装 Win 10,但是错误依旧,根据文档的提示尝试使用新版的 wsl –install 命令,但是这个要求是 Win 10 Insider Preview 系统,于是加入这个计划,下载镜像,烧录 U 盘,安装系统,但是结果仍然失败了。

静下来回顾下,为什么另外一台在跑的 builder 没有问题呢,对比之后发现,这两个服务器型号不一样,CPU 也不一样,没有问题的是 AMD 的 CPU,有问题的是 Intel 的,WSL 2 相比 WSL 1 有了很大的提升,如下:

WSL 支持 Linux 完整的 kernel,并且网络隔离做的更好的。这就要求安装 WSL 2 的时候要开启 win 系统的虚拟化功能,但是这个功能底层依赖于 CPU 的虚拟化支持,想到这里心里咯噔一下,难道这个型号的 CPU 不支持虚拟化,这么新的型号不可能啊,下载 Intel 的工具进行查看确认是支持虚拟化的,难道 BIOS 里面没有开启吗?重启机器进入 BIOS 的 CPU 高级功能,果不其然。

OK,设置成 enable,保存重启,WSL 2 的 Linux 初始化成功。接着测试 buildlet 程序,编译 stage0,设置 HTTP 代理访问 google 服务器,一气呵成。

......
##### ../misc/cgo/test
PASS
ok  	misc/cgo/test	37.545s
PASS
ok  	misc/cgo/test	38.335s

##### ../misc/cgo/testgodefs
PASS

##### ../misc/cgo/testso
ok  	misc/cgo/testso	7.505s

##### ../misc/cgo/testsovar
ok  	misc/cgo/testsovar	7.724s

##### ../misc/cgo/errors
PASS

##### ../doc/progs
ok	run	31.86s

##### ../doc/articles/wiki
ok  	doc/articles/wiki	5.783s

##### ../doc/codewalk
ok  	command-line-arguments	10.390s

##### ../test/bench/go1

##### API check

All tests passed.

终于,home lab 的 Go builder 正式上线了,这是中国第三台 builder,世界各地给 Go 提交的相关 patch 代码会拉取到这台服务器上进行测试(目前速度不是特别理想,优化中),然后将测试结果传递回给 google 服务器,展示在页面上,日志临时存储在对象存储中。

Home lab 的布置才刚刚开始,期待有更多有意思的东西 后续可以和大家分享。