使用 Azure 文件创建用于在 Azure Kubernetes 服务(AKS)上部署高度可用的 GitHub Actions 的基础结构

在本文中,你将使用 Azure 文件存储和 Helm 来创建在 AKS 上部署高可用性操作运行器控制器 (ARC) 基础结构所需的基础结构。

在您开始之前

设置环境变量。

设置以下环境变量以在本指南中使用:

export AKS_AND_STORAGE_ACCOUNT_RG="aks-files-actions"
export AKS_CLUSTER_NAME="aks-actions"
export STORAGE_ACCOUNT_NAME=""
export AKS_STORAGE_ACCOUNT_LOCATION="chinanorth3"
export GITHUB_CONFIG_URL="azure-files-samples/Workloads/azurefiles-actions-aks at master · Azure-Samples/azure-files-samples"

# Optional. Changes might require additional changes on ./install/*.yaml files.

export NAMESPACE_ARC_CONTROLLER="arc-systems"
export ARC_CONTROLLER_NAME="arc-controller"
export NAMESPACE_ARC_RUNNERS="arc-runners"
export ARC_RUNNER_SCALESET_NAME="arc-runner-set"
export ARC_RUNNER_GITHUB_SECRET_NAME=""

请确保替换以下 必需 变量的值:

  • AKS_AND_STORAGE_ACCOUNT_RG 使用存储帐户和 AKS 群集使用的资源组名称。
  • AKS_CLUSTER_NAME 使用 AKS 群集的名称。
  • STORAGE_ACCOUNT_NAME 使用存储帐户的名称。
  • AKS_STORAGE_ACCOUNT_LOCATION 包含要在其中创建资源的区域的名称。 在此示例中,我们将部署在 AKS 群集所在的同一区域中,以促进性能和成本管理。
  • GITHUB_CONFIG_URL 包含 GitHub 组织或存储库的 URL。

如果可能,请将以下 可选 变量保留为默认值:

  • NAMESPACE_ARC_CONTROLLER:运行 ARC 运行程序规模集控制器的 Kubernetes 命名空间的名称。
  • ARC_CONTROLLER_NAME:ARC 运行程序规模集控制器的名称。
  • NAMESPACE_ARC_RUNNERS:用于运行 ARC 自承载运行程序的 Kubernetes 命名空间的名称。
  • ARC_RUNNER_SCALESET_NAME:ARC 运行程序规模集的名称。
  • ARC_RUNNER_GITHUB_SECRET_NAME:GitHub 密钥的名称。

安装所需的扩展

aks-previewk8s-extensionamg 扩展提供了更多功能来管理 Kubernetes 群集和查询 Azure 资源。 使用以下 az extension add 命令安装这些扩展:

az extension add --upgrade --name aks-preview --yes --allow-preview true 
az extension add --upgrade --name k8s-extension --yes --allow-preview false 
az extension add --upgrade --name amg --yes --allow-preview false

创建资源组

使用 az group create 命令创建资源组。 此资源组将保存 AKS 群集和 Azure 文件存储存储帐户。

az group create \ 
    --name $AKS_AND_STORAGE_ACCOUNT_RG \ 
    --location $AKS_STORAGE_ACCOUNT_LOCATION

创建 AKS 群集

使用 az aks create 命令创建 AKS 群集。

az aks create --resource-group "${AKS_AND_STORAGE_ACCOUNT_RG}" --name "${AKS_CLUSTER_NAME}" \ 
    --os-sku AzureLinux \ 
    --node-count 1 \ 
    --enable-cluster-autoscaler \ 
    --min-count 1 \ 
    --max-count 3 \ 
    --node-vm-size standard_d4s_v5 \ 
    --max-pods=100 \ 
    --network-plugin azure \ 
    --network-plugin-mode overlay \ 
    --generate-ssh-keys

连接到 AKS 群集

若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 若要在本地安装 kubectl,请使用 az aks install-cli 命令。

  1. 配置 kubectl 以使用 az aks get-credentials command 来连接到你的 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。

    az aks get-credentials --resource-group "${AKS_AND_STORAGE_ACCOUNT_RG}" --name "${AKS_CLUSTER_NAME}"
    
  2. 使用 kubectl get nodes 命令验证与群集之间的连接。 此命令返回 AKS 群集中的节点列表。

    kubectl get nodes
    

创建 Azure 文件共享

在将 Azure 文件存储的文件共享用作 Kubernetes 卷之前,你需要先创建 Azure 存储帐户和文件共享。 本指南使用 Azure 文件共享高级 SMB 来支持元数据缓存。 对于创建的每个共享,最小值为 100 Gb

  1. 使用命令 az storage account create 创建存储帐户。 以下命令使用 Premium_LRS SKU 创建存储帐户。

    az storage account create --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${AKS_AND_STORAGE_ACCOUNT_RG}" \
        --location "${AKS_STORAGE_ACCOUNT_LOCATION}" \
        --sku Premium_LRS \
        --kind FileStorage
    
  2. 使用 az storage account show-connection-string 命令将连接字符串导出为环境变量,然后用于创建文件共享。

    export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${AKS_AND_STORAGE_ACCOUNT_RG}" --query connectionString -o tsv)
    
  3. 使用 az storage share create 命令创建 100 Gb 高级文件共享。 在此示例中,我们使用 元数据缓存 作为共享名称。 如果更改此名称,则还必须更改 arc-runners-set-pv.yaml 文件以反映此更改。

    az storage share create --name metadatacaching --quota 100 --connection-string "${AZURE_STORAGE_CONNECTION_STRING}"
    

安装 ARC 运行程序规模集控制器

使用下文的 helm install 命令安装 ARC 运行程序规模集控制器。

helm install "${ARC_CONTROLLER_NAME}" \ 
    --namespace "${NAMESPACE_ARC_CONTROLLER}" \ 
    --create-namespace \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller

创建 Kubernetes 机密

Azure 文件共享存储密钥机密

Azure 文件要求您在 AKS 上使用存储密钥创建一个机密,该密钥用于从 AKS Pod 容器连接 Azure 文件共享。

  1. 使用 az storage account keys list 命令将存储帐户密钥导出为环境变量。

    STORAGE_KEY=$(az storage account keys list --resource-group ${AKS_AND_STORAGE_ACCOUNT_RG} --account-name ${STORAGE_ACCOUNT_NAME} --query "[0].value" -o tsv) 
    
  2. 创建 Kubernetes 命名空间,以使用 kubectl create namespace 命令运行 ARC 自承载运行程序。

    kubectl create namespace "${NAMESPACE_ARC_RUNNERS}" 
    
  3. 使用 kubectl create secret generic 命令创建用于存储 Azure 文件共享存储密钥的 Kubernetes Secret。

    kubectl create secret generic azure-storage-secret \ 
       --namespace "${NAMESPACE_ARC_RUNNERS}" \ 
       --from-literal=azurestorageaccountname=${STORAGE_ACCOUNT_NAME} \ 
       --from-literal=azurestorageaccountkey=${STORAGE_KEY}
    

GitHub 应用机密

  1. 创建一个 GitHub 应用,以允许自托管运行器按照注册 GitHub 应用指南访问您的 GitHub 组织或存储库。 GitHub 创建过程提供以下参数:

    • GITHUB_APP_ID:GitHub 应用的 ID。
    • GITHUB_APP_INSTALLATION_ID:GitHub 应用的安装 ID。
    • github_app_private_key:GitHub 应用的私钥。 需要将 -----BEGIN RSA 私钥----- 部分替换为您的私钥。
  2. 使用kubectl create secret generic命令创建 Kubernetes 机密来存储 GitHub 应用凭据。 请确保将占位符替换为从 GitHub 应用创建过程获取的实际值。

    GITHUB_APP_ID="app-id-placeholder"
    GITHUB_APP_INSTALLATION_ID="installation-id-placeholder"
    
    kubectl create secret generic ${ARC_RUNNER_GITHUB_SECRET_NAME} \ 
        --namespace=${NAMESPACE_ARC_RUNNERS} \
        --from-literal=github_app_id=${GITHUB_APP_ID} \
        --from-literal=github_app_installation_id=${GITHUB_APP_INSTALLATION_ID} \
        --from-literal=github_app_private_key=' <Private Key read here>'
    

Azure 文件共享配置

你可以使用 AccessMode: ReadWriteMany 在多个 Pod 中装载 Azure 文件存储的文件共享,同时在 ARC Kubernetes 副本集创建的所有 Pod 中装载相同的文件共享。 我们以如下方式使用 Azure 文件共享:

  • 作为 持久 SMB 文件共享 ,用于缓存 .NET 示例应用程序使用的 NuGet 包。 arc-runners-set-pv-pvc.yaml 文件能创建规定的 PV 和 PVC,以在 ARC 运行程序规模集 Pod 中装载 Azure 文件存储的文件共享。 对于此第一个选项,建议使用 Azure 文件高级版。 按照下文示例所示,自定义 PV 和 PVC 清单上的 volumeAttributes 和所有命名空间参数:

    volumeAttributes: 
      resourceGroup: metadata-agroves  # Optional. Only set this when the storage account isn't in the same resource group as node. 
      shareName: metadatacaching
    nodeStageSecretRef:
      name: azure-storage-secret
      namespace: arc-runners
    
  • 作为 GitHub 运行程序工作文件夹的“临时卷”。 我们还创建了两个存储类:Azure 文件标准版(github-azurefile)和 Azure 文件高级版(github-azurefile-premium)。 这些类可以按需创建和删除卷。 运行 GitHub 作业时,会在 Kubernetes 上创建新的运行程序 Pod,并创建并装载新的 Azure 文件存储的文件共享。 卷仅存在在作业运行期间。 标准版本允许任何存储卷大小,高级版本允许至少 100 Gb 存储卷。 你可以选择任何你喜欢的课程。 请记住,Premium 为你提供更好的性能。 可以自定义 arc-runners-storage-class-files.yaml 文件,但这不是必需的。

创建永久性卷和永久性卷声明

  1. 使用 kubectl apply 命令创建永久性卷和永久性卷声明。

    kubectl apply -f ./install/arc-runners-set-pv-pvc.yaml --namespace "${NAMESPACE_ARC_RUNNERS}" --wait 
    
  2. 使用 kubectl apply 命令为 Azure 文件应用存储类。

    kubectl apply -f ./install/arc-runners-storage-class-files.yaml --wait 
    

安装 ARC 运行程序规模集

以下代码片段来自安装文件夹中的 arc-runners-set-values.yaml 文件,你可以在安装运行程序集 Helm 图表之前对其进行自定义。

containerMode: 
  type: "kubernetes" # Type can be set to dind or kubernetes 
  ## The following is required when containerMode.type=kubernetes 
  kubernetesModeWorkVolumeClaim: 
    accessModes: ["ReadWriteMany"] 
    storageClassName: "github-azurefile-premium" # or "github-azurefile" for Standard_LRS 
    resources: 
      requests: 
        storage: 100Gi # 100Gi minimum to premium or any size when using Standard_LRS "github-azurefile" storage class 
template: 
  spec: 
  securityContext: 
    fsGroup: 123 # Group used by GitHub default agent image 
  containers: 
  - name: runner 
    image: ghcr.io/actions/actions-runner:latest 
    command: ["/home/runner/run.sh"] 
    env: 
      - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER 
        value: "false" 
      - name: ACTIONS_RUNNER_CONTAINER_HOOK_TEMPLATE 
        value: "/home/runner/container-config/container-podspec.yaml" 
    volumeMounts: 
      - name: "container-podspec-volume" 
        mountPath: "/home/runner/container-config" 
      - name: azurefile 
        mountPath: /home/runner/.nuget/              
  volumes: 
    - name: "container-podspec-volume" 
      configMap: 
        name: hook-extension 
    - name: azurefile 
      persistentVolumeClaim: 
        claimName: azurefile 

在此示例中,我们使用 Kubernetes containerMode 的自定义版本将 Azure 文件存储的文件共享卷装载到 NuGet 包和临时_工作文件夹卷中。

以下参数不需要更改:

  • storageClassName:在“github-azurefile-premium”和“github-azurefile”之间进行选择。
  • storage:选择存储的大小。 高级版最低为 100 Gb。

使用选项在 helm install 选项在 --set 命令上设置其他 Helm 参数。

为了与 GitHub 工作流容器功能兼容以便在管道中运行容器,我们在使用容器功能运行工作流时,为 ARC 创建的工作流 Pod 装载有 pod 规范的 container-podspec-volume。 此 Pod 规格是从安装文件夹中的 arc-runners-set-container-pod-spec.yaml 文件创建的 ConfigMap 装载的。 不需要进行任何更改。

kubectl apply -f ./install/arc-runners-set-container-pod-spec.yaml 

ARC 运行程序规模集 Helm 图表参数

ARC 运行程序规模集 Helm 图表提供了几个参数。 在 AKS 上安装具有 Azure 文件共享卷装载的规模集时,以下参数是最重要的:

  • githubConfigUrl:GitHub 组织或存储库。
  • githubConfigSecret:用于从自托管运行器访问 GitHub 的 GitHub 应用程序密钥。
  • minRunners:规模集中等待 GitHub 新作业的最小运行程序数。
  • maxRunners:正在运行作业或等待 GitHub 新作业的最大运行程序数。
  • runnerGroup:ARC 运行器集使用的 GitHub 运行器组。

下载 ARC 运行程序规模集 Helm 图表

在 AKS 上安装 Helm 图表

使用 helm install 命令在 AKS 上安装 ARC 运行程序规模集 Helm 图表。

helm install "${ARC_RUNNER_SCALESET_NAME}" \ 
    --namespace "${NAMESPACE_ARC_RUNNERS}" \ 
    --create-namespace \ 
    --values ./install/arc-runners-set-values.yaml \ 
    --set githubConfigUrl="${GITHUB_CONFIG_URL}" \ 
    --set githubConfigSecret="${ARC_RUNNER_GITHUB_SECRET_NAME}" \ 
    --set minRunners=1 \ 
    --set maxRunners=3 \ 
    --set runnerGroup=default \ 
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set

升级运行程序规模集安装

如果想要升级 ARC 运行程序规模集上的任何配置,你可以 helm upgrade --install 命令,其参数与安装规模集的相同。 例如,如果要将 minRunners 参数从 1 更改为 2,可以运行以下命令:

helm upgrade --install "${ARC_RUNNER_SCALESET_NAME}" \
    --namespace "${NAMESPACE_ARC_RUNNERS}" \
    --create-namespace \
    --values ./install/arc-runners-set-values.yaml \
    --set githubConfigUrl="${GITHUB_CONFIG_URL}" \
    --set githubConfigSecret="${ARC_RUNNER_GITHUB_SECRET_NAME}" \
    --set minRunners=2 \
    --set maxRunners=3 \
    --set runnerGroup=default \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set

后续步骤

供稿人

Microsoft维护本文。 以下贡献者最初撰写了这篇文章:

  • 豪尔赫·阿尔特里奥 | 高级云倡导者
  • Jeff Patterson | 首席产品经理
  • Rena Shah |高级产品经理
  • 谢哈尔·辛格·索罗特 |Product Manager 2
  • Erin Schaffer | 内容开发人员 2