写在前面
经过前两篇文章的学习,我们已经部署好了koji以及使用koji来构建出rpm包,包括x86_64和risc-v64.实际上,我们知道把一个软件的.src.rpm源码包或者scm(源代码管理系统)到rpm包的过程,手动执行rpmbuild -bb命令也可以完成,只是不过使用rpmbuild的时候是使用自己本地的环境进行构建。
这时候就会出现两个问题:1.构建环境可能不干净,受到构建机器的影响;2.构建速度太慢,自己的主机或者虚拟机受限于硬件性能。
所以我们要部署kojihub,使用开源的构建系统,它最大的好处就是分布式,构建机与发出构建包请求的机器分离,这样就可以利用远程的服务器资源,使用更加高级的intel i9,AMD r9甚至多路至强或epyc服务器CPU来加速构建的过程。
在前面的两篇文章中,我们在虚拟机里完成了kojihub的部署和rpm包的构建,虽然说也实现了一些功能,但是还没有体现出它“分布式”的特点,因为我们唯二的两个builder,一个是fedora虚拟机自己,一个是fedora虚拟机里开的fedora risc-v虚拟机。我们把fedora虚拟机看成是自己的主机的话,实际上还是在消耗本地的资源,这样的koji像一个玩具一样,真实的效率可能还不如手动执行rpmbuild -ba来得快一点。
所以本篇文章,就是要把koji从一个玩具变成一个实用的工具,这主要的工作就是让更多的机器作为builder加入进来,并且还要让更多设备能够访问我们部署好的kojihub,让更多人可以访问到我们部署好的网站,参与到rpm包的打包工作。在本篇文章中,我们主要解决的就是计算机网络的问题。
koji越往后学资料就越少,不过大家可以发挥主观能动性,主动去探究koji的更多作用、探索它的可玩性以及使用自带的plugins.
到目前为止,我们的koji还局限于虚拟机,只能在virt-manager这小小的窗口里“管中窥豹”。不过在这篇文章看完后,我们的koji会海阔天空,你可以在更多机器上访问kojiweb,查看的窗口也会和访问fedora koji和openkoji一样。
在这一个多月的探究koji的时间里我遇到的更多的是bug和莫名其妙的错误,我需要做一个总结。
由于我的fedora因为selinux-policy的更新导致无法运行systemd也就是无法正常进入系统,为了大家的安全,我们最好选择直接把selinux给封印掉,selinux由于fedora的rpm依赖问题可能无法完全卸载。
sudo vim /etc/default/grub
#在如下的选项里添加上selinux=0,意味着在内核层禁用selinux
GRUB_CMDLINE_LINUX="rhgb quiet selinux=0"
#重新生成grub的配置文件
sudo grub2-mkconfig -o /boot/grub/grub.cfg
我们只需要重启一下fedora,那么就可以和selinux说拜拜了。
此外,为了部署的koji的安全,搭建一套这样的环境也比较费时,建议在这里备份一下fedora的qcow2文件并且使用virt-manager拍一个快照,这样如果有突发问题可以跳回正常情况。
这也是使用虚拟机的好处。
在使用koji的过程中,提示ssl证书不通过并且提示“Name or service not known”,这貌似和计算机网络有关。一旦变成这个样子,kojiweb无法点击login按钮登陆,并且kojibuilder也无法与kojihub取得通信。
解决方法如下:
sudo vim /etc/koji-hub/hub.conf
打开kojihub的配置文件并且设置为禁用FQDN的检查。不过通常来说,在生产环境里是不能这么做的,万一访问者是一个黑客会很危险,koji部署做了这么多的限制都是“权限验证”、为了kojihub服务器的安全。我们部署在个人电脑里这一点倒是无所谓,管好访问的流量就好,反正一般来说只有自己的设备去访问。
然后重启Apache服务器,如果fedora虚拟机开机后显示host的x并且重启后没有用,日志里提示ssl,那么也重启一下httpd进程就好。
sudo systemctl restart httpd
一、从虚拟机到实体机访问
1、外部设备访问koji
我们现在可以在fedora虚拟机的firefox浏览器里的搜索栏键入"koji.april.com/koji"去查看kojiweb页面,这是因为我们打开了Apache服务器并且在/etc/hosts里做了一个映射:
127.0.0.1 koji.april.com
192.168.122.59 koji.april.com
当你访问这个url的时候,系统会去/etc/hosts里找到这一条映射,去访问你本地的ip地址。正是这条规则让我们的url变得真实起来。
现在,让我们把视线回到开启了fedora虚拟机的宿主机:
我的物理机的系统是Gentoo不过这并不太重要,无论你的宿主机是什么Linux发行版、甚至是Windows、MacOS、或者干脆也是在虚拟机里也没有关系。当你的宿主机开启一个虚拟机的时候,实际上它会起到一个路由器的作用,蓝色框里的192.168.122.1/24就是网关。而你的virt-manager开启的任何一台使用了NAT虚拟网络的虚拟机,它都会连接到这个网关对应的虚拟路由器。因此,实际上你的宿主机是可以直接ping通虚拟机,也可以访问到kojihub.
直接在物理机的浏览器里键入你的fedora虚拟机的ip地址即可访问。
sudo vim /etc/hosts
# IPv4 and IPv6 localhost aliases
127.0.0.1 localhost
::1 localhost
192.168.122.59 koji.april.com
同样地,我们只需要添加这样一条映射进去,就可以在物理机里访问kojiweb了。
不过这和在fedora虚拟机里访问的kojiweb还是有区别,物理机访问的kojiweb是没有kojiadmin权限的,也就是说你无法登陆。因为我们还没有在这个firefox里引入PKCS12证书。
这一点不难,如法炮制就好:
sudo scp /etc/pki/koji/certs/kojiadmin_browser_cert.p12 april_zhao@10.213.5.205:~
然后在物理机的firefox里引入这个文件,这样就能够以kojiadmin的身份去登陆了。
现在,我们要把服务推送到局域网里,也就是让和你连同一个WIFI的人也可以访问kojiweb,并且他也可以提交任务去构建rpm包,这其实和obs、ebs非常非常类似了。
但是到目前为止,外部设备是无法访问你的fedora虚拟机里部署的kojihub后端的,原因如下图所示:
这是我绘制的网络布局,在图中比较清晰地能看见几个重要的网络设备。
由于ipv4地址数量有限的限制,这么多的设备其实被拆成了两个局域网,上面一个是由路由器创建的,只要有线连接上去或者连上该路由器产生的WIFI则加入了上面的局域网。而下面的则是我的Gentoo通过qemu开启的虚拟机里的NAT网络,把Gentoo当成了一个网关。这里就产生了一个问题:上面局域网中的设备,licheepi4a开发板、opensuse、手机是可以与Gentoo进行数据互通的(可以互相ping);而下面局域网中的设备也可以互相ping。但是上面与下面的设备却ping不通,因为不在同一个局域网。
这样就出现了A能ping通B,B能ping通C,而A却无法和C进行数据交互的“难题”。
一开始我使用nginx做一个端口的转发代理,但是发现它好像会把客户端携带的ssl证书给丢失,大家知道这个证书是非常关键的,因此我换了一个新软件来做端口映射。
这里我要推荐一个非常方便、且容易使用的端口映射(重定向)软件redir
redir GitHubhttps://github.com/troglobit/redir比如说你把系统的20000端口映射为22端口的时候,你只需要使用ssh -p 20000 root@localhost那么你就可以ssh连接本地计算机而不是使用默认的22端口了,虽然最终访问的还是22端口,但是20000端口也变成了一个入口。
通过这个软件,我们就可以把Gentoo系统闲置的443端口转发给fedora虚拟机里已开启的443端口(提供kojihub的Apache服务器)。这样,只要和Gentoo实体机连上同一个网络的局域网设备都可以访问kojihub,当然在网页也是能够看到kojiweb界面。
# 如果你也用Gentoo
sudo emerge -av redir
# Fedora/CentOS
sudo dnf install redir
# Debian/Ubuntu/Deepin
sudo apt install redir
# Arch/Manjaro
yay -Sy redir
官方源里都会提供这个工具,用起来也很简单。
sudo redir :443 192.168.122.59:443
意思就是把当前设备的443端口映射到fedora虚拟机的ip的443端口。更多用法可以参考redir项目的README介绍,目前来说这一行代码已经足够使用了。
只是你每次开机都要执行这一行代码可能会有一些麻烦,所以可以写一个systemd服务,这样使用systemctl就可以控制端口映射。
sudo vim /etc/systemd/system/redir.service
[Unit]
Description=Redirect port 443 to the virtual machine
Documentation=https://github.com/troglobit/redir
After=libvirtd.service
[Service]
Type=idle
ExecStart=redir -n -l notice -s :443 192.168.122.59:443
TimeoutSec=60
[Install]
WantedBy=multi-user.target
sudo systemctl enable redir.service
这样就会开机自启动映射服务,并且只要stop这个服务那么映射也会取消,管理起来会非常方便。
journalctl -xu redir.service
可以通过journalctl来查看日志。我这里-l选项后面跟的是debug所以才会记录这么多日志,实际上也不必要记录这么多,你使用warn或者err也就足够了。
我们可以使用tcping这个命令来验证映射是否成立:
# Gentoo
sudo emerge -av tcping
# Fedora
sudo dnf copr enable cyqsimon/tcping-go
sudo dnf install tcping-go
# opensuse
sudo zypper install tcping
~ tcping 10.213.5.205 443
::1 port 443 closed.
没有做映射的时候会显示closed.tcping这个工具相当于是可以带端口号的ping命令,来测试网络是否连通。
~ tcping 10.213.5.205 443 ✔ 18:40:10
10.213.5.205 port 443 open.
如果映射成功了,就会显示open。
我在opensuse外部设备上进行测试:
做好这一个映射之后,我们需要关注的就是Gentoo物理机的ip地址,也就是上图的10.213.5.205.这是我的ip地址,大家自己的ip需要自己去查看。我们需要在要访问koji的设备上做一个ip映射。
10.213.5.205 koji.april.com
这样外部设备就可以通过url来访问你的物理机。对于外部设备而言,是无法直接访问fedora虚拟机的kojihub,是通过Gentoo物理机做中转,所以这里的ip地址你要写物理机的ip地址,不是以前那个192.168.开头的那个虚拟机ip了。
这里需要特别注意一下就是,如果你使用的是wifi连接到路由器,那么这个ip地址其实是DHCP协议自动分配的,也就是你每一次联网(开机),拿到的ip地址都不同。这样的话你的hosts文件每次都要修改会很麻烦。
所以我这里有如下方法:
1.关掉WIFI,使用有线连接,如果提供的网线接口有限,那么可以考虑用上交换机(这也是最稳妥的方法);我现在就用这种方法。
2.使用静态ip地址,简单配置可以使用nmtui命令。
sudo dnf install NetworkManager-tui
按照如图所示的配置,但是你不能抄我这样的写法,静态ip以及网关由实际情况决定。这里注意一下,你的静态ip最好设置成一个不会被占用的,如果这个ip已经被分配给别的设备了,那你就只能获取到一个别的ip,这样不是太方便。
注意静态ip的掩码前缀,如果你不知道你的子网掩码你可以使用ifconfig命令去查看。我现在的子网掩码是255.225.240.0,转换成二进制是11111111.11111111.11110000.00000000。因此前缀就是8+8+4=20,在静态ip后面写上"/20"即可。
3.找你的网络管理员或者运维人员固定你的ip,如果自己能够接触到路由器本机的话可以在路由器后台进行设置。
如上图所示,我现在可以在同一局域网的其他设备上访问自己部署的kojiweb.
对于其他设备而言,也只需要在/etc/hosts里添加规则就好,就可以使用url来访问。但是Android这里特殊一点,你需要解开bl锁、获取root权限并且还要进行模块挂载才能够修改hosts文件,这些涉及到安卓刷机了,我这里就不演示了。
现在我们已经打通了虚拟机到物理机的界限,但还受限于局域网,其实只需要使用内网穿透的软件其实就可以放置到公网上,任意网络即可访问。你实际上也可以把买一个公网ip和域名然后像这样映射到虚拟机的ip里,甚至还可以专门租一台服务器来运行自己的koji项目,就和Fedora/CentOS一样。我在使用Google的时候也搜索到过私人自建的koji项目。大家不妨动手尝试一下,也可以自建一个koji,无论是要创建一个自己的发行版还是单纯拿出来让大家体会构建的乐趣。
最终,我的网络布局大概是如图所示的这样,把与koji相关的设备可以通过有线连接到以太网交换机上,这些设备间的通讯可以比连到同一个路由器上要快一些,只有访问公网的时候才需要用到路由器。到目前为止,外部设备可以通过Gentoo访问koji,而虚拟机间也可以互相访问,这样才算是打通了一整个局域网。
上面的方法对于个人项目而言是比较方便的,如果你想让别人也访问到自己部署的koji,那么除了直接在vps上部署kojihub之外,还可以使用以下几种方法。
- 使用tailscale,使用这个工具可以让连接到不同局域网的设备通过vpn连接到一个虚拟机相同且的局域网,那么这个虚拟局域网里的所有设备都可以直接互通,而不需要考虑映射问题。
- 使用内网穿透软件直接把kojihub挂到公网,那么这个时候其实就相当于部署到云服务器上了,而且这样会更加安全一些,毕竟你不是真的拥有一台云服务器,不用怕被攻击。
如图所示就是内网穿透后的效果,可以很方便地使用公网url访问。注意公网的https协议是需要备案的,443端口的直接穿透,外部是无法访问。
2、为koji添加新用户
到目前为止,我们的koji还只有两个用户,必创建的管理员kojiadmin和仓库管理员kojira,实际上其他人并没有参与感,因为无法通过命令行或者kojiweb对kojihub进行什么数据操作。
大家可以查看fedora的kojiweb界面,有几千个Users,作为一个流行的发行版,fedora的打包参与者众多,社区的包维护人员参与感比较强。实际上fedora一直有package和package-zh的兴趣小组,加入这个小组之后就能够获得身份并且使用官方的koji进行打包。这个大家有兴趣可以去了解一下。
现在我们自建的koji也可以给外部人员、或者是兴趣小组的人员颁发ssl证书,一起使用koji来进行rpm包的打包工作。
koji add-user opensuse
我要给我的opensuse这台设备创建一个用户,假设这就是一个打包者
cd /etc/pki/koji
sudo ./cert-issue.sh opensuse
sudo ./PKCS12.sh opensuse
我们再回来这个梦开始的地方,签发SSL证书和PKCS12证书。
大家在新设备的firefox登陆之前请务必进入about:config里把配置给调好。
第一篇文章里有firefox的配置https://blog.csdn.net/qq_61653333/article/details/141553092?spm=1001.2014.3001.5502
这样,只要是同一局域网的设备都可以协作进行打包工作了。
但是目前来说这个新用户还没有分配权限,现在我们就来看一下koji用户有哪些权限。
~ koji list-permissions
Permission name Description
-----------------------------------------------------------------------
admin Full administrator access. Perform all actions.
appliance Create appliance builds - deprecated.
dist-repo Create a dist-repo.
draft-promoter The permission required in the default "draft_promotion" hub policy rule to promote draft build.
host Add, remove, enable, disable hosts and channels.
image Start image tasks.
image-import Import image archives.
livecd Start livecd tasks.
maven-import Import maven archives.
repo Manage repos: newRepo, repoExpire, repoDelete, repoProblem.
sign Import RPM signatures and write signed RPMs.
tag Manage packages in tags: add, block, remove, and clone tags.
target Add, edit, and remove targets.
win-admin The default hub policy rule for "vm" requires this permission to trigger Windows builds.
win-import Import win archives.
~ koji grant-permission host opensuse
我这里暂时先分配一个host,允许修改构建机情况的权限。
小结:大家从这里外部人员使用可以看出来,Fedora koji其实没有像OBS和EBS那样开放,这二者只需要注册一个账号就可以进行rpm包的构建,注册一下也就几分钟,而且也不需要和包管理的maintainer申请。并且全程只需要在网页操作就好,也不需要使用专门的命令才能构建。
而koji不一样,这个构建的权限被牢牢掌握在部署kojihub的人的手里,需要向maintainer申请,并且要同意且发放SSL证书后才能对koji进行操作,否则只有查看的权限。如果你不是Fedora的贡献者而只是一个普通的用户,则无法使用koji来打包rpm包。并且对于非rpm系Linux来说,如何使用koji这个命令都是一个问题,提交一个新的构建任务是需要koji命令的。比如我现在使用opensuse这个外部人员去访问kojihub ,就费了老大劲才能用上koji命令,而对面的osc命令则是在很多发行版都能直接用上。
在易用性方面,Fedora koji确实不如OBS和EBS,不过这也和Fedora是半社区半企业的特性有关。koji是RedHat公司在2005年之后开始创建,企业为了保证部署网站的安全性以及发布的rpm包的安全性,必须做好层层审核。Fedora本身是开放的,只是想成为maintainer并不这么容易。
二、添加risc-v实体机作为builder
我们目前已经有两个host,kojibuilder1对应的是fedora虚拟机里运行的kojid,是x86_64架构;kojibuilder2对应的是fedora risc-v 。现在我们就来添加物理机器作为builder,这样可以更加贴近真实的环境。
这个kojibuilder3的创建以及证书的生成和1、2是一模一样的,大家参考前面的内容就好,我们现在把注意力放到开发板上。
这是我的licheepi 4a开发板(荔枝派),我给刷成了Fedora Linux,现在我就在这个开发板(物理机)上部署kojid并且把它作为kojibuilder3.这样risc-v的构建机又添加一员大将(实际上也就是4个Hart)。不过我们只要把它给部署好,那么其他的risc-v设备就可以如法炮制,比如添加高性能64Hart的milk v pioneer作为host。我们这里使用荔枝派做一个例子。
由于开发板外接一个显示器非常麻烦,并且我的Fedora也没有安装图形界面,因此你在这里也最好固定一下开发板的ip地址(方法在上面)。否则每次开发板开机都要插上显示器查看ip地址会很麻烦!我这里按照上面的网络示意图所示,直接用网线连接到以太网交换机。
sudo dnf install koji koji-builder koji-builder-plugins mock
cd /etc/kojid/
安装好kojid包之后,要创建证书并且把证书通过网络发送到开发板。这些操作和前面部署kojibuilder2是一模一样的,这里也不演示了。
使用ssh连接到开发板或者用串口、HDMI查看到开发板提供的shell输出的时候,我们去修改/etc/hosts文件,使kojid守护进程能够访问到koji.april.com
vim /etc/hosts
# 添加url到Gentoo ip的规则
10.213.5.205 koji.april.com
# 保存并退出后测试一下
~ ping koji.april.com root@fedora-riscv 10:12:37
PING koji.april.com (10.213.5.205) 56(84) bytes of data.
64 bytes from koji.april.com (10.213.5.205): icmp_seq=1 ttl=64 time=0.310 ms
64 bytes from koji.april.com (10.213.5.205): icmp_seq=2 ttl=64 time=0.438 ms
64 bytes from koji.april.com (10.213.5.205): icmp_seq=3 ttl=64 time=0.463 ms
64 bytes from koji.april.com (10.213.5.205): icmp_seq=4 ttl=64 time=0.449 ms
64 bytes from koji.april.com (10.213.5.205): icmp_seq=5 ttl=64 time=0.311 ms
64 bytes from koji.april.com (10.213.5.205): icmp_seq=6 ttl=64 time=0.335 ms
^C
--- koji.april.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5043ms
rtt min/avg/max/mdev = 0.310/0.384/0.463/0.066 ms
能够访问之后,我们直接打开kojid守护进程,注意证书和kojid.conf要写正确。至此,我们的外部设备lichee pi 4a开发板已经成为了kojibuilder3。实际上你已经可以创建很多个builder了。
然后我们可以再提交一个risc-v的rpm包构建任务过去试试:
这样我的开发板就会忙碌起来,不会放着吃灰了。