TeamCity On-Premises 2024.03 Help

为 Amazon EC2 设置 TeamCity

TeamCity Amazon EC2 集成使 TeamCity 能够自动缩放其构建资源,根据当前的构建队列工作负载自动启动和停止云托管的代理。

常见信息

您可以在 TeamCity 中设置各种类型的 EC2 集成。 根据您使用的设置和来源,云端 AWS 托管的代理可以运行在:

概览镜像
  • 从同一Amazon Machine Image(AMI)克隆的多个相同实例。 可以作为按需或Spot 实例启动。

  • 由 TeamCity 管理的单一永久 EC2 实例。 可以在多个 TeamCity 服务器之间共享。

  • 一组从 AWS 请求的Spot 实例(Spot Fleet)。

前提条件

此部分描述了在 AWS 帐户中必须完成的步骤,然后再在 TeamCity UI 中设置云配置文件。

创建并设置 EC2 实例

  1. 打开 Amazon EC2 控制台

  2. 创建所需的实例。 参考这些 Amazon 教程以获取更多信息:LinuxWindowsmacOS

  3. 在您的实例上安装代理。 根据操作系统的类型,所需的步骤可能会有所不同。 请参阅这些文章以获取更多信息:

  4. 安装运行构建步骤和 TeamCity 代理所需的任何额外软件:JDK 和 JRE、SDK、运行时框架、构建工具如 Git 和 Docker 等等。

  5. 运行代理,并确保它成功地连接到您的 TeamCity 服务器,并且与所有所需配置兼容。

  6. 将系统配置为在实例启动时TeamCity 代理

  7. 对于 Windows 实例,请按照以下步骤操作:Windows 代理的额外配置

  8. 重启您的实例,以确保构建代理自动启动并能够连接到服务器。

创建 AMI

如果您希望在上一步中创建的实例直接连接到 TeamCity 服务器,并且作为一个独立的代理机器服务,请跳过此部分。 否则,如果您希望 TeamCity 根据当前的工作负载自动调整活动云代理的数量,就从此实例创建一个 AMI。

  1. 停止构建代理。 对于 Windows 实例,停止代理服务,但保持其启动类型为 Automatic

  2. 从您的实例中删除所有临时和多余的数据:安装向导、下载的归档文件、构建日志等等。

  3. 可选:删除 <agent_home>/log<agent_home>/temp 目录。

  4. 可选:删除 <agent_home>/conf/amazon-* 文件。

  5. <agent_home>/conf/buildAgent.properties 文件中移除以下属性:

    • 名称 — TeamCity 将自动为您的实例分配唯一的名称。

    • serverUrl — 对于 EC2 集成插件,由于您将在设置云配置文件时为所有实例提供服务器 URL,因此可以安全地删除此属性。 其他插件可能需要此属性存在并设置为正确的值。

    • (可选) authorizationToken — 新的云代理会自动获得授权。

  6. 停止实例。

  7. 在您的实例概览页面上,点击 操作 | 镜像和模板 | 创建镜像

    创建 AMI

在 TeamCity 中设置 EC2 集成

在您创建了所需的实例或 AMI 之后,您可以在 TeamCity UI 中设置云配置文件。

创建云配置文件

云配置文件 是 TeamCity 启动虚拟机的一组通用设置。

  1. 导航至 Administration | <Required Project> | Cloud Profiles。 如果您希望此配置文件中的 cloud agents 具有全局可用性,请选择 <Root project>。 个别项目拥有的配置文件可用于生成只能在这些项目中使用的代理。

  2. 点击 创建新的配置文件

  3. Cloud type 设置为 "Amazon EC2"。

  4. 输入您的个人资料名称和可选描述。

  5. 在使用访问密钥/密钥对进行身份验证和在服务器机器上本地存储的凭据之间进行选择。 无论选择何种模式,TeamCity 用于访问 AWS 资源的用户或 IAM 角色都必须具有本节中列出的所有权限:所需的 IAM 权限

    此选项允许您指定 TeamCity 将用于访问您的 AWS 资源的凭证。 使用静态凭据是最不安全的方法,我们建议您使用 使用默认凭据提供程序链选项。

    5.1. 请前往 AWS Identity and Access Management(IAM)仪表板。

    5.2 切换到 Users 标签,并找到一个用户,其凭证可以被 TeamCity 用于访问您的 EC2 实例和 AMIs。

    5.3 切换到 Security Credentials 标签并滚动到 Access keys 部分。

    5.4 创建新的密钥。 将其 ID 和 secret 粘贴到 TeamCity UI 中的相关字段中。

    Use default credential provider chain 选项允许 TeamCity 查找存储在服务器机器上的 AWS 凭证。 通常,包含您的 AWS 凭据的 配置 文件位于 Linux 或 macOS 的 ~/.aws/config ,或者位于 Windows 的 C:\Users\USERNAME\.aws\config。 这种方法比使用静态访问密钥更稳定、更安全。

    有关本地存储的 AWS 凭证的更多信息,请参阅以下文章:配置和凭证文件设置

  6. 请选择托管您的实例的 AWS 区域。

  7. 设置代理限制。 此数字指定了从此配置文件的所有云镜像创建的代理的总体限制。

  8. 指定 TeamCity 服务器 URL。 这个值将自动传递给代理的 buildAgent.properties 文件。 如果未指定,代理将使用与 Administration | Global Settings 页面相同的值。

  9. 指定一系列准则,用于缩减活跃的云代理。 您可以选择代理程序处于空闲状态的时长,或者他们执行实际构建程序的时间多长。

    代理终止条件
  10. 点击 Apply changes 以保存配置文件并退出配置文件设置页面。

添加云镜像

云配置文件指定全局设置,例如授权凭据和实例区域。 每个配置文件可以有一个或多个 镜像 ,存储与应启动的特定类型的云实例相关的设置。 您可以根据需要向个人资料添加尽可能多的图片。 然而,请注意,所有镜像启动的代理总数不能超过在配置文件设置中设定的限制(以及您的许可证所允许的代理数量)。

  1. 点击添加图片按钮。

  2. 指定可选的镜像名称。

  3. 选择所需的镜像类型。

    选择 TeamCity 将用来生成相同实例的 AMI。

    3.1 如果您希望 TeamCity 导入并使用特定的 启动模板,请检查 使用启动模板 选项。 当服务器上的模板的默认/最新版本更新时,TeamCity会检测到这些变化并更新正在运行的实例。

    3.2. 选择所需的 AMI。

    • Own AMI — TeamCity 扫描在云配置文件设置中指定的凭据下可用的 AMI 集合。 您可以浏览找到的所有 AMIs,并选择所需的镜像。

    • 通过 ID 的 AMI — 允许您使用一个 共享的 AMI

    • 依照标签的 AMI — 指定一个由逗号分隔的 AWS 标签 列表,例如, Owner=Mike,Project=Glacier,Subnet=Public。 如果指定的标签指向多个 AMI,TeamCity 将使用最新创建的 AMI。 如果没有找到 AMIs,那么在 Agents 部分下的镜像名称将显示为“镜像名称(无数据)”,而不是“镜像名称(ami-xxxxxxxxx)”。

      无效的 AMI 标签

    3.3. 指定一个或多个 实例类型

    • 如果您只需要启动此特定类型的按需或Spot 实例(例如, t2.medium ),请指定一种类型。 您可以添加多个针对同一AMI的镜像,这些镜像具有不同的实例类型值。 通过这样做,您可以为每种类型设置不同的活动实例限制,并手动启动特定类型的实例。

    • 如果您计划订购Spot 实例,请设置多种类型(例如, t2.smallt2.mediumt2.large)。 这种方法可以增加您获得Spot 实例分配的机会。

    3.4. 可选:指定额外的镜像设置。

    • IAM 角色 — 所有启动的实例都将承担的 IAM 角色。 这个角色指定了在您的 EC2 实例上运行的应用程序被授予的权限 granted to applications。 由 TeamCity 使用的 AWS 帐户必须拥有 iam:ListInstanceProfilesiam:PassRole 权限,以便使用 IAM 角色。

    • 密钥对 — 如果您可能需要使用 SSH连接到 EC2 实例,则需要。

    • 用户数据 — 允许您指定一个在实例启动时运行的脚本。 了解更多:WindowsLinux

    • Tags — 这是逗号分隔的实例标签列表。 例如 LaunchedBy=TeamCity,TeamCityCloudProfileName=MyProfile1。 标记需要 ec2:*Tags 权限。 请参阅以下部分获取更多信息:标签功能

    3.5. 如果您更倾向于便宜的 Use spot instances 而非 On-Demand 实例, 请勾选 Use spot instancesMax price 字段允许您指定针对Spot 实例的最高出价(以美元计)。 如果未指定出价,将使用默认的按需价格。

    TeamCity 可以根据您的 spot placement scores 自动选择区域或可用区,使您的现货请求最有可能成功。 为了让 TeamCity 请求并使用这些分数,请添加 ec2:GetSpotPlacementScores IAM 权限

    3.6. 为您的 EC2 实例指定网络设置。

    这个选项允许您将特定实例添加到 TeamCity。 与允许 TeamCity 启动多个相同实例的 AMIs 相比,这种类型意味着您有一个静态虚拟机,TeamCity 可以启动和停止。

    3.1 请指定所需的 实例类型。 由于只能有一个活动实例,您只能选择一种类型。

    3.2 如果您可能需要Key pair连接到您的 EC2 实例,using SSH请选择。

    Amazon Spot Fleet 允许您根据给定的条件预定常规(按需)和 spot 实例的组合。 请参阅以下 AWS 文档文章以获取示例请求:Spot Fleet 示例配置

    3.1. 在 AWS Management Console中,前往 Instances | Spot Requests | Request Spot Instances

    3.2 指定所需的 AMI、最小计算单元、可用区以及其他请求详情。

    3.3. 点击 JSON config 以下载包含 spot fleet 配置参数的 JSON 文件。 请注意,只支持 SpotFleetRequestConfigData 类的字段。

    Amazon 中的 Spot fleet 配置生成按钮

    3.4. 将生成的 JSON 配置文件粘贴到 TeamCity 中的 Spot Fleet Request 字段中。

    要运行该镜像,TeamCity 将启动与 spot fleet 配置中指定的分配策略匹配的 spot 实例。

  4. 镜像优先级 字段中输入一个介于 -1000010000 之间的整数(默认优先级为 0)。 当 TeamCity 需要启动一个新的云代理时,它会选择优先级值最高的镜像。

    TeamCity 使用优先级值来排序所有现有配置文件的镜像。 例如,新排队的构建可以在从 A 和 B 配置文件生成的云代理上运行。 配置文件 A 有三个镜像,优先级分别为 20 、 40 和 60 。 配置文件B有10、30和50的优先级图片。 TeamCity 将按照以下顺序启动新的代理:

    • 配置文件 A ,镜像优先级 60。

    • 配置文件 B ,镜像优先级 50 。

    • 配置文件 A ,镜像优先级 40 ,等等。

    只有当优先级更高的可用镜像达到其活动代理限制时,才使用优先级较低的镜像。

  5. 设置从此镜像开始的活动云代理的最大数量。 请注意,从所有添加到配置文件的镜像中启动的代理总数不得超过在此配置文件的设置页面上设定的限制。

  6. 指定新创建的实例将属于哪个 代理池

  7. 点击 Save 以退出镜像设置页面。

在您配置了一个镜像之后,TeamCity 会为这个镜像启动一个测试代理,以测试它是否可以启动并连接到服务器。 当代理连接并获得授权后,TeamCity 会保存其参数,以正确地将构建分配给兼容的代理。

如果您的镜像已勾选使用Spot 实例设置,而测试实例当前无法启动(例如,没有可用的容量,或者您的出价过低),只要队列中还有可以在这个代理上运行的构建,TeamCity 就会每分钟尝试启动一个Spot 实例。

管理云代理

当构建进入队列时,TeamCity 首先尝试在常规(非云)代理上运行排队的构建。 如果当前没有可用的,TeamCity会找到一个兼容的云映像,并且(如果尚未达到同时运行实例的限制)启动一个新实例。

您可以从 Agents 标签手动启动和停止云代理。 请注意,如果活动云代理的数量达到了配置文件或镜像设置中指定的限制,Start 按钮将被禁用。

启动和停止云代理

运行实例板块显示了从这个特定镜像开始启动的所有代理。

  • 成功启动但尚未连接到 TeamCity 服务器的实例将使用 AWS 实例 ID 作为名称(“i-xxxxxxxxxxxx”)。

  • 已连接和获授权的实例名称由父镜像名称和 AWS 实例 ID 合并而成("Ubuntu-22.04-Large-i-xxxxxxxxxxxx")。

  • 如果已连接的代理报告出现了过时的构建工具,它将自动断开以进行升级。 一旦所有必需的软件都更新了,代理将重新连接到服务器。 TeamCity 会为过时的代理镜像显示相应的警告。

    过时的 agent 镜像

您可以通过 Open Terminal 按钮,打开任何活动的代理实例的 交互式终端。 终端允许您调试和维护您的云代理机器。

DSL 配置

以下的 Kotlin 片段展示了一个云配置文件的示例 DSL 配置,该配置文件使用本地存储的凭证并包含了三个具有不同设置的镜像。

import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.amazonEC2CloudImage import jetbrains.buildServer.configs.kotlin.amazonEC2CloudProfile // ... version = "2024.03" project { vcsRoot(MyRoot) buildType(Build) features { // Image 1: On-Demand Instances for a Specific AMI amazonEC2CloudImage { id = "PROJECT_EXT_14" profileId = "amazon-4" name = "Ubuntu-22.04-Large(AMI)" vpcSubnetId = "mySubnet123" iamProfile = "john-doe-ec2-role" keyPairName = "john-doe-u2204-key" instanceType = "t2.large" securityGroups = listOf("security-group-1") instanceTags = mapOf( "LaunchedBy" to "TeamCity" ) maxInstancesCount = 4 source = Source("ami-1234567890") } // Image 2: Spot Instances for an AMI Located by Tags amazonEC2CloudImage { id = "PROJECT_EXT_20" profileId = "amazon-4" name = "Ubuntu-22.04-Medium-Spot(Tags)" vpcSubnetId = "mySubnet123" instanceType = "t3a.medium,t3a.small" securityGroups = listOf("security-group-1,security-group-2") useSpotInstances = true spotInstanceBidPrice = 1.0 instanceTags = mapOf( "LaunchedBy" to "TeamCity" ) maxInstancesCount = 4 source = Source("tags") param("source-tags", "OS=Ubuntu, OSVersion=22.04") } // Image 3: A Single EC2 Instance amazonEC2CloudImage { id = "PROJECT_EXT_22" profileId = "amazon-4" agentPoolId = "-2" name = "Windows-Server2022(Instance)" vpcSubnetId = "mySubnet123" keyPairName = "john-doe-w2022s-keys" instanceType = "m2.xlarge" securityGroups = listOf("security-group-1") source = Source("i-1234567890") } // Parent Profile for All Images amazonEC2CloudProfile { id = "amazon-4" name = "AWS EC2 Profile" description = "A sample Amazon EC2 profile with AMI and Instance images" serverURL = "https://MyTeamCityBuildFarm.dev.gg" terminateIdleMinutes = 30 region = AmazonEC2CloudProfile.Regions.EU_WEST_DUBLIN maxInstancesCount = 20 authType = instanceIAMRole() param("terminate-after-build", "false") param("terminateTimeOut_checkbox", "true") } } } object Build : BuildType({ name = "Build" allowExternalStatus = true vcs { root(MyRoot) } steps { // Build Steps } triggers { vcs {} } features { // Build Features } }) object MyRoot : GitVcsRoot({ name = "https://github.com/...#refs/heads/main" url = "https://github.com/..." branch = "refs/heads/main" branchSpec = "refs/heads/*" authMethod = password { userName = "JohnDoe" password = "..." } param("oauthProviderId", "PROJECT_EXT_8") })

额外设置

所需的 IAM 权限

TeamCity 需要以下对 Amazon EC2 资源的权限:

  • ec2:Describe*

  • ec2:StartInstances

  • ec2:StopInstances

  • ec2:TerminateInstances

  • ec2:RebootInstances

  • ec2:RunInstances

  • ec2:ModifyInstanceAttribute

  • ec2:*Tags

要使用 spot instances,除了上述列出的权限外,还需要授予以下权限:

  • ec2:RequestSpotInstances

  • ec2:CancelSpotInstanceRequests

  • ec2:GetSpotPlacementScores (可选,允许 TeamCity 根据他们的 spot placement scores 选择 AWS 区域或可用区)。

要使用 Spot Fleets,需要以下额外的权限:

  • ec2:RequestSpotFleet

  • ec2:DescribeSpotFleetRequests

  • ec2:CancelSpotFleetRequests

  • iam:CreateServiceLinkedRole (如果您收到"The provided credentials do not have permission to create the service-linked role for EC2 Spot Fleet"错误;一旦服务角色已创建,您可以安全地撤销此权限)

要以假定的 IAM 角色启动实例(适用于从 AMIs 和启动模板克隆的实例),需要以下额外的权限:

  • iam:ListInstanceProfiles

  • iam:PassRole

要使用 加密的 EBS 卷,需要以下额外的权限:

  • kms:CreateGrant

  • kms:Decrypt

  • kms:DescribeKey

  • kms:GenerateDataKeyWithoutPlainText

  • kms:ReEncrypt

下面的代码片段展示了一个自定义的 IAM 策略定义,允许来自特定 IP 地址的 TeamCity 启动的所有 EC2 操作:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "1", "Action": [ "ec2:Describe*", "ec2:StartInstances", "ec2:StopInstances", "ec2:TerminateInstances", "ec2:RebootInstances", "ec2:RunInstances", "ec2:ModifyInstanceAttribute", "ec2:*Tags", "ec2:RequestSpotInstances", "ec2:CancelSpotInstanceRequests", "ec2:GetSpotPlacementScores", "ec2:RequestSpotFleet", "ec2:DescribeSpotFleetRequests", "ec2:CancelSpotFleetRequests" ], "Effect": "Allow", "Condition": { "IpAddress": { "aws:SourceIp": "<TeamCity server IP address>" } }, "Resource": "*" }, { "Sid": "2", "Action": [ "kms:CreateGrant", "kms:Decrypt", "kms:DescribeKey", "kms:GenerateDataKeyWithoutPlainText", "kms:ReEncrypt" ], "Effect": "Allow", "Condition": { "IpAddress": { "aws:SourceIp": "<TeamCity server IP address>" } }, "Resource": "*" }, { "Sid": "3", "Action": [ "iam:CreateServiceLinkedRole", "iam:ListInstanceProfiles", "iam:PassRole" ], "Effect": "Allow", "Condition": { "IpAddress": { "aws:SourceIp": "<TeamCity server IP address>" } }, "Resource": "*" } ] }

另请参见:示例政策(Linux)示例政策(Windows)

Windows 代理的额外配置

为了确保 TeamCity 代理 与 EC2 API(包括访问附加驱动器)在 Windows 上的正常通信,请在 TeamCity 构建代理 服务上添加一个来自 AmazonSSMAgentEC2Launch / EC2Config 服务的依赖项(该服务确保机器在使用 AWS 基础设施方面完全初始化)。 例如,这可以通过 Registry 或者使用 sc config 来完成(例如, sc config TCBuildAgent depend=EC2Config)。
或者,您可以使用 "Automatic (delayed start)" 服务启动模式。

Amazon EBS 优化实例

EBS optimization 在 TeamCity 中的表现与 EC2 控制台提供的类似。 在配置 Amazon cloud profile 的镜像时,可以使用 Instance Type 对应的框设置优化。 请注意:

  • EBS 优化默认为 c4.*d2.*m4.* (无法配置)打开;

  • EBS 优化默认情况下对于任何其他实例类型均被关闭,可用于支持它的实例(例如 c3.xlarge)。

标签功能

由 TeamCity 启动的实例标记

以下要求必须由 TeamCity 启动的标记实例满足:

即使没有标记权限,TeamCity 仍然可以启动没有应用标签的 Amazon AMI 和 EBS 镜像,但无法启动 Amazon EC2 竞价实例。

TeamCity 允许用户通过标记创建的实例来获得实例启动信息,标签中包含 teamcity:TeamcityData<服务器 UUID>:-<云配置文件 ID>:-<镜像引用>此标签对于 TeamCity 与 EC2 的整合是必要的,不得删除。

您可以将自定义标签应用于 EC2 云代理实例:在配置 Cloud 个人资料设置时, 在 添加镜像/编辑镜像 对话框中使用 实例标签 字段来指定以 <key1>=<value1>,<key2>=<value2> 格式的标签。 Amazon 标签限制 需要被考虑。

在标签值中使用等号(=)时,无需进行转义。 例如,字符串 extraParam=name=John 将被解析为 <key=extraParam> 和值 <name=John>.

标记实例依赖资源

在启动 Amazon EC2 实例时,TeamCity 会给所有与创建实例相关的资源(例如,卷和网络适配器)打标签,这对于评估实例的总成本(考虑到存储驱动器类型和大小,I/O 操作(对于标准驱动器),网络(传输出),等等)非常重要。

在多个 TeamCity 服务器之间共享一个 EBS 实例

如上文所述,TeamCity 会为其启动的每个实例打上 teamcity:TeamcityData 标签,该标签存储有关服务器、云配置文件和源(AMI 或 EBS 实例)的信息。 所以,当几个 TeamCity 服务器试图使用同一个 EBS 实例时,第二个服务器将会看到以下信息:"实例正在被另一个 TeamCity 服务器使用。 无法启动/停止它。 如果您确定没有其他的 TeamCity 服务器正在使用这个实例,您可以删除 teamcity:TeamcityData 标签,此实例将再次对所有 TeamCity 服务器开放。

代理设置

如果您的 TeamCity 服务器需要使用代理来连接 AWS API 端点,请配置以下服务器 内部属性 以连接到 Amazon AWS 地址。

  • teamcity.http.proxy.host.ec2 — 代理服务器主机名

  • teamcity.http.proxy.port.ec2 — 代理服务器端口

对于代理服务器验证:

  • teamcity.http.proxy.user.ec2 — 代理访问用户名

  • teamcity.http.proxy.password.ec2 — 代理访问用户密码

对于 NTLM 认证:

  • teamcity.http.proxy.domain.ec2 — 用于 NTLM 认证的代理用户域

  • teamcity.http.proxy.workstation.ec2 — 用于 NTLM 认证的代理访问工作站

估算 EC2 费用

标准的 Amazon EC2 定价适用。 Amazon 的收费可能取决于部署 TeamCity 所实施的特定配置。 我们建议您定期检查您的配置和 Amazon 帐户数据,以尽早发现并防止意外费用。

请注意,流量大小和必要的服务器及代理机器特性在很大程度上取决于 TeamCity 的设置和运行的构建性质。 参见 估计 TeamCity 的硬件需求

估算流量

以下是一些有助于您估算 TeamCity 相关流量的要点:

  • 如果 TeamCity 服务器不位于与 TeamCity EC2 设置中为代理程序配置的相同 EC2 区域或可用区内,则服务器和代理程序之间的流量将按照 Amazon EC2 的通常外部流量费用收费。

  • 在估计流量时,请记住与 TeamCity 相关的流量类型有很多(请参阅下面的不完全列表)。

服务器发起的外部连接

  • VCS 服务器

  • 电子邮件服务器

  • Maven 仓库

由服务器发起的内部连接

  • TeamCity 代理 (检查状态,发送命令,检索像线程转储等信息,等等)

由代理发起的外部连接

  • VCS 服务器(在代理端检出的情况下)

  • Maven 仓库

  • 任何来自构建过程本身的连接操作

由代理发起的内部连接

  • TeamCity 服务器(在服务器端检出或个人构建的情况下获取构建源、下载工件等)

服务器通常提供的连接

  • Web 浏览器

  • IDE 插件

正常运行时间成本

鉴于 Amazon 将某些配置的机器运行时间四舍五入至整小时(在 Amazon EC2 实例小时是如何计费的? 可查看更多信息),请根据您通常的构建长度调整 TeamCity 云集成设置中的 EC2 镜像设置的超时设置。

我们强烈建议为所有构建设置执行超时,以防止构建挂起导致实例长时间运行但无有效负载。

最后修改日期: 16日 7月 2024年