草庐IT

如何建设一个用于编译 iOS App 的 macOS 云服务器集群?

jingdongkeji 2023-12-18 原文

作者:京东零售 叶萌

现代软件开发一般会借助 CI/CD 来提升代码质量、加快发版速度、自动化重复的事情,iOS App 只能在 mac 机器上编译,CI/CD 工具因此需要有一个 macOS 云服务器集群来执行 iOS App 的编译。

今天就来谈谈如何建设 macOS 云服务器集群

购买 mac mini / Mac Studio 机器

最简单的方式就是购买一批 mac 机器,买它个 1000 台,买回来后放入机房,把其中一台机器作为管理机,申请办公网访问这台机器的网络权限,每次要维护这批机器里的软件时,先从办公网进入管理机,然后从管理机在远程连接到其他机器。

虚拟化 macOS 集群

借助 macOS 官方的Virtualization.Framework,可以分钟级创建 macOS 虚拟机,这种方式创建的虚拟机性能、稳定性、安全性都很高,可以持续采用更新、更快、更高级的 mac 硬件,最终实现更快的 App 编译速度。

在企业内部申请 macOS 机器,需要经历申请预算、领导审批、采购、运输、部署至机房等繁琐步骤,现在可通过购买高配置的 mac 机器,然后再将其按需配置成多台虚拟机,减少了硬件维护成本,提高了扩容效率。这方面代表性产品有

移动端 CI/CD 平台 bitrise 采用的是这种方式,只不过他们做了很多自研工作,打造了Gen2编译基础设施,宣称能让客户更快、更频繁的发布 App

云端管理 macOS 服务器

自行购买并维护 mac 机器还是不太方便,成本很高,如果能云端管理、按需付费就更好了。亚马逊的 AWS 解决了这个问题,他家的Amazon EC2 Mac Instances能让我们按需申请 macOS 服务器,如果能接受云端服务的话,其实这种方式最省事。与这种服务类似的产品有

在 linux 里运行 macOS 虚拟机

sickcodes/Docker-OSX是最近流行的一个项目。

  • 借助 KVM 技术,实现了在 linux 里运行 macOS 虚拟机

  • 借助 docker,简化了 macOS 虚拟机的部署

这个项目具有很多优势,例如

  1. 不依赖专门的 Apple 硬件,能够运行 KVM 的 x86_64 机器就行

  2. 能够通过 docker 容器来部署 macOS 虚拟机。未来借助 k8s,能够实现大规模 macOS 服务器的管理,轻易实现扩缩容

也有风险

  1. 不太合规,macOS 正常只能在 Apple 硬件上运行

  2. 在 KVM 里运行 macOS,兼容性、性能、稳定性需要评估。如果出现问题需要付费找项目维护者解决

我在裸金属上利用 Docker-OSX 项目确实跑起来了 macOS 虚拟机。运行该项目有以下几点要注意

  1. linux 宿主机需要支持嵌套虚拟化(Nested Hardware Virtualization)。开启硬件虚拟化后才能安装 kvm。裸金属和物理机正常都支持

  2. 对 Linux 内核有要求,操作系统最好比较新,CentOS 8 可以,CentOS 7 不行

在 Apple 硬件上用 k8s 来调度 macOS

有没有可能在私有云里实现 aws 这种 mac 管理体验呢?MacStadium家的 Orka 平台做到了。Orka 有以下好处

1 - 降低了 mac 集群的管理成本
花时间更少,例如管理服务器、在服务器上安装软件

利用 Kubernetes 调度 mac 服务器,这与 Linux 服务器的管理保持一致,方便融入公司已有技术栈

2 - 在真正的 Apple 硬件上运行 mac 虚拟机
不用担心兼容性、稳定性、性能问题

3 - 用心为开发者设计
提供多种操作方式(命令行、REST API)来管理 mac 虚拟机

对于企业来说,可以考虑购买 Orka 平台,在私有云里面搭建 macOS 云服务器集群。GitLab SaaS 版也是使用这种方式来提供托管的 macOS Runner 的

总结

我讲了建设 macOS 云服务器集群的 5 种方式,这些方式各有利弊,总的来说:

  • 如果能接受使用云服务器,建议直接购买 AWS 的 Amazon EC2 Mac Instances,方便、成本低

  • 自建机房,如果计划建设的 macOS 集群规模很大,建议购买 MacStadium 的 Orka 平台来建设,专业服务,避免踩坑,省时省力

  • 自建机房,如果 macOS 集群规模比较小,对自动化要求不高,建议购买高配的 apple 硬件,然后通过Virtualization.Framework虚拟化出多台 macOS 机器,整体架构比较简单,也能解决问题

有关如何建设一个用于编译 iOS App 的 macOS 云服务器集群?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  8. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  9. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  10. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

随机推荐