AWS CDK GitLab Runner 使用 docker+machine 执行器在 EC2 实例上自动扩展。
项目描述
EC2 上的 AWS CDK GitLab Runner 自动缩放
该项目提供了一个 CDK 构造,用于使用Docker Machine执行器在自动扩展的 EC2 实例上执行作业。
用完Runner 分钟,使用Docker-in-Docker (dind) ,使用共享 S3 缓存加速作业,交叉编译/构建环境多架构,在 EC2 上进行经济高效的自动扩展,直接从 AWS 账户部署(无需AWS 访问密钥),运行在Spot 实例上,具有更大的构建日志大小
安装
打字稿
npm install @pepperize/cdk-autoscaling-gitlab-runner
或者
yarn add @pepperize/cdk-autoscaling-gitlab-runner
Python
pip install pepperize.cdk-autoscaling-gitlab-runner
C#/.Net
dotnet add package Pepperize.CDK.AutoscalingGitlabRunner
爪哇
<dependency>
<groupId>com.pepperize</groupId>
<artifactId>cdk-autoscaling-gitlab-runner</artifactId>
<version>${cdkAutoscalingGitlabRunner.version}</version>
</dependency>
快速开始
-
使用projen在 TypeScript 中创建新的 AWS CDK 应用程序
mkdir gitlab-runner cd gitlab-runner git init npx projen new awscdk-app-ts -
配置你的项目
.projenrc.js- 添加
deps: ["@pepperize/cdk-autoscaling-gitlab-runner"],
- 添加
-
更新项目文件并安装依赖项
npx projen
-
注册一个新的跑步者
- 对于共享跑步者,请转到 GitLab 管理区域并单击概览 > 跑步者
- 对于组跑步者,请转到Settings > CI/CD并展开Runners部分
- 对于项目运行器,请转到Settings > CI/CD并展开Runners部分
可选启用:运行未标记的作业[x] 指示此运行器是否可以选择没有标记的作业
另请参阅注册令牌与身份验证令牌
-
检索新的运行器身份验证令牌
curl --request POST "https://gitlab.com/api/v4/runners" --form "token=<your register token>" --form "description=gitlab-runner" --form "tag_list=pepperize,docker,production"
-
将运行器身份验证令牌存储在 SSM ParameterStore 中
aws ssm put-parameter --name "/gitlab-runner/token" --value "<your runner authentication token>" --type "String"
-
添加到您的
main.tsimport { Vpc } from "@aws-cdk/aws-ec2"; import { App, Stack } from "@aws-cdk/core"; import { GitlabRunnerAutoscaling } from "@pepperize/cdk-autoscaling-gitlab-runner"; const app = new App(); const stack = new Stack(app, "GitLabRunnerStack"); const vpc = Vpc.fromLookup(app, "ExistingVpc", { vpcId: "<your vpc id>", }); const token = StringParameter.fromStringParameterAttributes(stack, "Token", { parameterName: "/gitlab-runner/token", }); new GitlabRunnerAutoscaling(stack, "GitlabRunner", { network: { vpc: vpc, }, runners: [ { token: token, configuration: { // optionally configure your runner }, }, ], });
-
创建服务链接角色
(如果请求 Spot 实例,默认:true)
aws iam create-service-linked-role --aws-service-name spot.amazonaws.com
-
配置 AWS CLI
-
部署 GitLab Runner
npm run deploy
例子
自定义缓存桶
默认情况下,创建一个 AWS S3 存储桶作为 GitLab Runner 的分布式缓存。它是加密的,公共访问被阻止。可以配置自定义 S3 存储桶:
const cache = new Bucket(this, "Cache", {
// Your custom bucket
});
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
},
],
cache: { bucket: cache },
});
请参阅示例, GitlabRunnerAutoscalingCacheProps
自定义 EC2 密钥对
默认情况下,amazonec2驱动程序将为每个运行器创建一个 EC2 密钥对。要使用自定义 ssh 凭证,请提供带有私钥和公钥文件的 SecretsManager Secret:
-
创建密钥对,下载私钥文件并记住创建的密钥对名称
-
生成公钥文件
ssh-keygen -f <the downloaded private key file> -y -
从密钥对创建 AWS SecretsManager 密钥
aws secretsmanager create-secret --name <the secret name> --secret-string "{\"<the key pair name>\":\"<the private key>\",\"<the key pair name>.pub\":\"<the public key>\"}" -
配置作业运行器
const keyPair = Secret.fromSecretNameV2(stack, "Secret", "CustomEC2KeyPair"); new GitlabRunnerAutoscaling(this, "Runner", { runners: [ { keyPair: keyPair, configuration: { machine: { machineOptions: { keypairName: "<the key pair name>", }, }, }, }, ], cache: { bucket: cache }, });
配置 Docker 机器
默认情况下,docker 机器配置为使用 OverlayFS 驱动程序CAP_SYS_ADMIN以支持Docker-in-Docker 的特权运行并使用multiarch
进行交叉编译/构建。
请参阅高级配置 中的runners.docker 部分
import { GitlabRunnerAutoscaling } from "@pepperize/cdk-autoscaling-gitlab-runner";
import { StringParameter } from "aws-cdk-lib/aws-ssm";
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
environment: [], // Reset the OverlayFS driver for every project
docker: {
capAdd: [], // Remove the CAP_SYS_ADMIN
privileged: false, // Run unprivileged
},
machine: {
idleCount: 2, // Number of idle machine
idleTime: 3000, // Waiting time in idle state
maxBuilds: 1, // Max builds before instance is removed
},
},
},
],
});
更大的实例类型
默认情况下,t3.nano 用于管理器/协调器,并且将生成 t3.micro 实例。对于更大的项目,例如使用webpack,这将是不够的内存。
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
manager: {
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.SMALL),
},
runners: [
{
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.LARGE),
token: token,
configuration: {
// optionally configure your runner
},
},
],
});
您可能必须禁用或配置Spot 实例
参见示例, GitlabRunnerAutoscalingManagerProps, GitlabRunnerAutoscalingJobRunnerProps
不同的机器图像
默认情况下,最新的Amazon 2 Linux将用于管理器/协调器。管理器/协调器实例的云初始化脚本需要安装yum,任何 RHEL 风格都可以工作。默认情况下,请求的运行程序实例使用 Ubuntu 20.04,任何由Docker Machine 配置程序实现的操作系统都应该可以工作。
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
manager: {
machineImage: MachineImage.genericLinux(managerAmiMap),
},
runners: [
{
machineImage: MachineImage.genericLinux(runnerAmiMap),
token: token,
configuration: {
// optionally configure your runner
},
},
],
});
参见示例, GitlabRunnerAutoscalingManagerProps, GitlabRunnerAutoscalingJobRunnerProps
多跑步者配置
每个运行器在配置文件[[runners]]中定义一个部分。当您想将跑步者用于特定项目时,请使用特定跑步者。
const privilegedRole = new Role(this, "PrivilegedRunnersRole", {
// role 1
});
const restrictedRole = new Role(this, "RestrictedRunnersRole", {
// role 2
});
const token1 = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token1",
});
const token2 = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token2",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token1,
configuration: {
name: "privileged-runner",
},
role: privilegedRole,
},
{
token: token2,
configuration: {
name: "restricted-runner",
docker: {
privileged: false, // Run unprivileged
},
},
role: restrictedRole,
},
],
});
请参阅示例, GitlabRunnerAutoscalingProps
现货实例
默认情况下,请求 EC2 Spot 实例。
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
machine: {
machineOptions: {
requestSpotInstance: false,
spotPrice: 0.5,
},
},
},
},
],
});
请参阅示例, EC2 现货价格, MachineConfiguration, MachineOptions, 高级配置 - runners.machine.autoscaling
使用 Multiarch 进行交叉编译
构建不同架构的二进制文件也可以使用Multiarch
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
docker: {
privileged: true,
},
},
},
],
});
配置你的.gitlab-ci.yml文件
build:
image: multiarch/debian-debootstrap:armhf-buster
services:
- docker:stable-dind
- name: multiarch/qemu-user-static:register
command:
- "--reset"
script:
- make build
在 AWS Graviton 上运行
要在AWS Graviton上运行您的作业,您必须为 arm64 架构提供 AMI。
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
instanceType: InstanceType.of(InstanceClass.M6G, InstanceSize.LARGE),
machineImage: MachineImage.genericLinux({
[this.region]: new LookupMachineImage({
name: "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-*-server-*",
owners: ["099720109477"],
filters: {
architecture: [InstanceArchitecture.ARM_64],
"image-type": ["machine"],
state: ["available"],
"root-device-type": ["ebs"],
"virtualization-type": ["hvm"],
},
}).getImage(this).imageId,
}),
},
},
],
});
自定义跑步者的角色
要从您的 GitLab Runner 实例中进行部署,您可以传递一个附加了 IAM 策略的角色。
const role = new Role(this, "RunnersRole", {
assumedBy: new ServicePrincipal("ec2.amazonaws.com", {}),
inlinePolicies: {},
});
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
role: role,
token: token,
configuration: {
// optionally configure your runner
},
},
],
});
请参阅示例, GitlabRunnerAutoscalingProps
虚拟个人电脑
如果没有现有的 Vpc 被传递,将创建一个具有 NatInstance (t3.nano) 和单个 AZ的廉价VPC 。
const natInstanceProvider = aws_ec2.NatProvider.instance({
instanceType: aws_ec2.InstanceType.of(InstanceClass.T3, InstanceSize.NANO), // using a cheaper gateway (not scalable)
});
const vpc = new Vpc(this, "Vpc", {
// Your custom vpc, i.e.:
natGatewayProvider: natInstanceProvider,
maxAzs: 1,
});
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
// optionally configure your runner
},
},
],
network: { vpc: vpc },
});
请参阅示例, GitlabRunnerAutoscalingProps
零配置
使用上述默认设置在 AWS EC2 上部署Autoscaling GitLab Runner。
对预设满意吗?
const token = StringParameter.fromStringParameterAttributes(stack, "Token", {
parameterName: "/gitlab-runner/token",
});
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
token: token,
configuration: {
// optionally configure your runner
},
},
],
});
请参阅示例, GitlabRunnerAutoscalingProps
ECR 凭证助手
默认情况下,GitLab amzonec2 驱动程序将配置为在运行程序的实例上安装 amazon-ecr-credential-helper 。
要进行配置,请覆盖默认的作业运行器环境:
new GitlabRunnerAutoscaling(this, "Runner", {
runners: [
{
// ...
environment: [
"DOCKER_DRIVER=overlay2",
"DOCKER_TLS_CERTDIR=/certs",
'DOCKER_AUTH_CONFIG={"credHelpers": { "public.ecr.aws": "ecr-login", "<aws_account_id>.dkr.ecr.<region>.amazonaws.com": "ecr-login" } }',
],
},
],
});
普罗延
本项目使用projen通过代码维护项目配置。因此,不应手动编辑使用 projen 合成的文件(事实上,projen 强制执行此操作)。
要修改项目设置,您应该与丰富的强类型类AwsCdkTypeScriptApp 交互并执行npx projen以更新项目配置文件。
简单来说,开发者只能修改
.projenrc.js配置/维护的文件和/src开发目录下的文件。