使用 GitHub Actions 将自动安全更新应用于 Azure Kubernetes 服务 (AKS) 节点

安全更新是维护 AKS 群集安全性与合规性的关键部分,具有用于基础 OS 的最新修补程序。 这些更新包括 OS 安全修复项或内核更新。 一些更新需要重启节点才能完成更新过程。

本文介绍如何使用 GitHub Actions 和 Azure CLI 自动执行 AKS 节点的更新过程,以创建基于 cron 自动运行的更新任务。

注意

还可以使用计划内维护自动执行节点映像升级并计划这些升级。 有关详细信息,请参阅自动升级节点映像

开始之前

  • 本文假设你有现有 AKS 群集。 如果需要 AKS 群集,请使用 Azure CLIAzure PowerShellAzure 门户创建一个。
  • 本文还假定你拥有 GitHub 帐户和用于托管操作的配置文件存储库。 如果没有该存储库,请创建一个与 GitHub 用户名同名的存储库。
  • 需要安装和配置 Azure CLI 版本 2.0.59 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

使用 az aks upgrade 更新节点

az aks upgrade 命令提供了一种无故障时间的方法来应用更新。 命令执行以下操作:

  1. 对所有群集节点应用最新更新。
  2. 隔离(使节点无法计划新工作负载)并排空(将现有工作负载移到其他节点)节点的流量。
  3. 重新启动节点。
  4. 使更新的节点能够再次接收流量。

如果使用其他方法更新节点,AKS 将不会自动重启节点。

注意

运行具有 --node-image-only 标志的 az aks upgrade 将只更新节点映像。 运行不带此标志的命令将升级节点映像和 Kubernetes 控制平面版本。 有关详细信息,请参阅节点的托管升级文档群集升级文档

所有 Kubernetes 节点都在标准基于 Windows 或 Linux 的 Azure 虚拟机 (VM) 中运行。 基于 Linux 的 VM 使用 Ubuntu 映像,其 OS 配置为每晚自动检查更新。

使用 az aks upgrade 命令时,Azure CLI 会创建大量具有最新安全性和内核更新的新节点。 这些新节点最初被隔离,以防止在节点上计划任何应用,直到更新完成。 更新完成后,Azure 会隔离并排空旧节点,然后取消隔离新节点,将所有计划的应用程序传输到新节点。

此过程要优于手动更新基于 Linux 的内核,因为 Linux 需要在安装新内核更新时重启。 如果手动更新 OS,则还需要重启 VM,手动隔离并排空所有应用。

创建定时 GitHub Action

cron 是一种实用工具,使你可按自动计划运行一组命令或作业。 若要创建作业以按自动计划更新 AKS 节点,你将需要一个存储库来托管操作。 通常,GitHub Actions 与应用程序在同一存储库中进行配置,但你可以使用任何存储库。

  1. 导航到 GitHub 上的存储库。

  2. 选择操作

  3. 选择“新建工作流”>“自己设置工作流”

  4. 创建一个名为“升级群集节点映像”的 GitHub 操作,计划触发器将每隔 15 天凌晨 3 点运行一次。 将以下代码复制到 YAML 中:

    name: Upgrade cluster node images
    on:
      schedule:
        - cron: '0 3 */15 * *'
    
  5. 创建一个名为 upgrade-node 的作业,此作业在 Ubuntu 代理上运行并连接到 Azure CLI 帐户,以执行节点升级命令。 将以下代码复制到 on 键下的 YAML 中:

    jobs:
      upgrade-node:
        runs-on: ubuntu-latest
    

在工作流中设置 Azure CLI

  1. 在“在市场中搜索操作”栏中,搜索“Azure 登录”

  2. 选择“Azure 登录”。

    显示两行的搜索结果,第一个操作名为“Azure 登录”,第二个操作名为“Azure 容器注册表登录”

  3. 在“安装”下,选择一个版本,例如 v1.4.6,然后复制安装代码片段

  4. 将安装代码片段中的 steps 键和以下信息添加到 YAML:

    name: Upgrade cluster node images
    on:
      schedule:
        - cron: '0 3 */15 * *'
    jobs:
      upgrade-node:
        runs-on: ubuntu-latest
        steps:
          - name: Azure Login
            uses: Azure/login@v1.4.6
            with:
              creds: ${{ secrets.AZURE_CREDENTIALS }}
    

为 Azure CLI 创建凭据

  1. 在新浏览器窗口中,使用 az ad sp create-for-rbac 命令创建新的服务主体。 请确保将 *{subscriptionID}* 替换为你自己的订阅 ID。

    注意

    此示例将在订阅范围内创建 Contributor 角色。 可以提供满足你的需求的角色和范围。 有关详细信息,请参阅 Azure 内置角色Azure RBAC 范围级别

    az ad sp create-for-rbac --role Contributor --scopes /subscriptions/{subscriptionID} -o json
    

    输出应类似于以下示例输出:

    {
      "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "displayName": "xxxxx-xxx-xxxx-xx-xx-xx-xx-xx",
      "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
    
  2. 复制输出并导航到 GitHub 存储库。

  3. 选择“设置”>“机密和变量”>“操作”>“新建存储库机密”

  4. 对于“名称”,请输入 AZURE_CREDENTIALS

  5. 对于“机密”,请复制创建服务主体时收到的输出的内容

  6. 选择“添加机密”。

创建执行 Azure CLI 命令的步骤

  1. 导航到工作流 YAML 的窗口。

  2. 在“在市场中搜索操作”栏中,搜索“Azure CLI 操作”

  3. 选择“Azure CLI 操作”

    “Azure CLI 操作”的搜索结果,第一个结果显示为 Azure 执行的操作

  4. 在“安装”下,选择一个版本,例如 v1.0.8,然后复制安装代码片段

  5. 将操作的内容粘贴到 *Azure Login* 步骤下的 YAML 中,类似于以下示例:

    name: Upgrade cluster node images
    on:
      schedule:
        - cron: '0 3 */15 * *'
    jobs:
      upgrade-node:
        runs-on: ubuntu-latest
        steps:
          - name: Azure Login
            uses: Azure/login@v1.4.6
            with:
              creds: ${{ secrets.AZURE_CREDENTIALS }}
          - name: Upgrade node images
            uses: Azure/cli@v1.0.8
            with:
              inlineScript: az aks upgrade --resource-group <resourceGroupName> --name <aksClusterName> --node-image-only --yes
    

    提示

    可以像 AZURE_CREDENTIALS 一样,通过新建存储库机密将 --resource-group--name 参数与命令分离。

    如果为这些参数创建机密,则需要将 <resourceGroupName><aksClusterName> 占位符替换为其机密对应项。 例如 ${{secrets.RESOURCE_GROUP_NAME}}${{secrets.AKS_CLUSTER_NAME}}

  6. 将 YAML 重命名为 upgrade-node-images.yml

  7. 选择“提交更改...”,添加提交消息,然后选择“提交更改”

手动运行 GitHub Action

除了计划的运行之外,还可以通过添加名为 workflow_dispatch 的新 on 触发器手动运行工作流。

注意

若要升级单个节点池而不是群集上的所有节点池,请将 --name 参数添加到 az aks nodepool upgrade 命令,以指定节点池名称。 例如:

az aks nodepool upgrade --resource-group <resourceGroupName> --cluster-name <aksClusterName> --name <nodePoolName> --node-image-only
  • on 键下添加 workflow_dispatch 触发器:

    name: Upgrade cluster node images
    on:
      schedule:
        - cron: '0 3 */15 * *'
      workflow_dispatch:
    

    YAML 应类似以下示例:

        name: Upgrade cluster node images
        on:
          schedule:
            - cron: '0 3 */15 * *'
          workflow_dispatch:
        jobs:
          upgrade-node:
            runs-on: ubuntu-latest
            steps:
              - name: Azure Login
                uses: Azure/login@v1.4.6
                with:
                  creds: ${{ secrets.AZURE_CREDENTIALS }}
              - name: Upgrade node images
                uses: Azure/cli@v1.0.8
                with:
                  inlineScript: az aks upgrade -g {resourceGroupName} -n {aksClusterName} --node-image-only --yes
              # Code for upgrading one or more node pools
    

后续步骤

有关 AKS 升级的详细信息,请参阅以下文章和资源: