使用 GitHub Actions 将自定义容器部署到应用服务
Artículo 04/01/2024
6 colaboradores
Comentarios
En este artículo
可以通过 GitHub Actions 灵活地生成自动化软件开发工作流。 借助 Azure Web 部署操作 ,可以使用 GitHub Actions 自动执行工作流以将自定义容器部署到应用服务 。
工作流通过存储库的 /.github/workflows/
路径中的 YAML (.yml) 文件定义。 此定义包含工作流中的各种步骤和参数。
对于 Azure 应用服务容器工作流,文件包含三个部分:
部分
任务
身份验证
1.检索服务主体或发布配置文件。 2.创建 GitHub 机密。
生成
1.创建环境。 2.生成容器映像。
部署
1.部署容器映像。
先决条件
具有活动订阅的 Azure 帐户。 创建帐户
一个 GitHub 帐户。 如果没有该帐户,请注册免费版 。 你需要在 GitHub 存储库中具有代码才能部署到 Azure 应用服务。
一个有效的容器注册表和用于容器的 Azure 应用服务应用。 本示例使用 Azure 容器注册表。 请确保完成对用于容器的 Azure 应用服务的完整部署。 与常规 Web 应用不同,用于容器的 Web 应用没有默认登录页。 发布容器以获得一个可正常工作的示例。
生成部署凭据
对于 GitHub Actions,若要通过 Azure 应用服务进行身份验证,建议使用发布配置文件。 也可以使用服务主体或 Open ID Connect 进行身份验证,但该过程需要更多步骤。
将发布配置文件凭据或服务主体另存为 GitHub 机密 ,以便使用 Azure 进行身份验证。 你将在工作流中访问机密。
发布配置文件是应用级凭据。 将发布配置文件设置为 GitHub 机密。
在 Azure 门户中转到应用服务。
在“概述”页上,选择“获取发布配置文件” 。
注意
从 2020 年 10 月起,Linux Web 应用在下载文件之前,需要将应用设置 WEBSITE_WEBDEPLOY_USE_SCM
设置为 true
。 未来将删除此要求。 请参阅在 Azure 门户中配置应用服务应用 ,了解如何配置常用 Web 应用设置。
保存下载的文件。 你将使用该文件的内容来创建 GitHub 机密。
可以使用 Azure CLI 中的 az ad sp create-for-rbac 命令创建服务主体 。
az ad sp create-for-rbac --name "myApp" --role contributor \
--scopes /subscriptions/<subscription-id>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name> \
--json-auth
在示例中,请将占位符替换为你的订阅 ID、资源组名称和应用名称。 输出是一个 JSON 对象,包含的角色分配凭据可提供对应用服务应用的访问权限。 复制此 JSON 对象供以后使用。
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
重要
始终应授予最小访问权限。 上一个示例中的范围仅限于特定的应用服务应用而不是整个资源组。
OpenID Connect 是一种使用短期令牌的身份验证方法。 使用 GitHub Actions 设置 OpenID Connect 的过程会更复杂,能提供更强的安全性。
如果没有现有的应用程序,请注册一个可访问资源的新 Active Directory 应用程序和服务主体 。 创建 Active Directory 应用程序。
az ad app create --display-name myApp
此命令将输出 JSON,其中 appId
为你的 client-id
。 保存该值,稍后将其用作 AZURE_CLIENT_ID
GitHub 机密。
使用图形 API 创建联合凭据时,将使用 objectId
值,并将其引用为 APPLICATION-OBJECT-ID
。
创建服务主体。 将 $appID
替换为 JSON 输出中的 appId。
此命令使用不同的 objectId
生成 JSON 输出,将在下一步中使用。 新的 objectId
是 assignee-object-id
。
复制 appOwnerTenantId
以在稍后用作 AZURE_TENANT_ID
的 GitHub 机密。
az ad sp create --id $appId
按订阅和对象创建新的角色分配。 默认情况下,角色分配将绑定到默认订阅。 将 $subscriptionId
替换为你的订阅 ID,将 $resourceGroupName
替换为你的资源组名称,将 $assigneeObjectId
替换为生成的 assignee-object-id
。 了解如何使用 Azure CLI 管理 Azure 订阅 。
az role assignment create --role contributor --subscription $subscriptionId --assignee-object-id $assigneeObjectId --assignee-principal-type ServicePrincipal --scopes /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/sites/
运行以下命令,为 Active Directory 应用程序创建新的联合标识凭据 。
将 APPLICATION-OBJECT-ID
替换为 Active Directory 应用程序的 objectId(在创建应用时生成)。
为 CREDENTIAL-NAME
设置一个值供以后引用。
设置 subject
。 此项的值由 GitHub 根据工作流定义:
GitHub Actions 环境中的作业:repo:< Organization/Repository >:environment:< Name >
对于未绑定到环境的作业,请根据用于触发工作流的 ref 路径包括分支/标记的 ref 路径:repo:< Organization/Repository >:ref:< ref path>
。 例如 repo:n-username/ node_express:ref:refs/heads/my-branch
或 repo:n-username/ node_express:ref:refs/tags/my-tag
。
对于由拉取请求事件触发的工作流:repo:< Organization/Repository >:pull_request
。
az rest --method POST --uri 'https://microsoftgraph.chinacloudapi.cn/beta/applications/<APPLICATION-OBJECT-ID>/federatedIdentityCredentials' --body '{"name":"<CREDENTIAL-NAME>","issuer":"https://token.actions.githubusercontent.com","subject":"repo:organization/repository:ref:refs/heads/main","description":"Testing","audiences":["api://AzureADTokenExchange"]}'
若要了解如何在 Azure 门户中创建 Active Directory 应用程序、服务主体和联合凭据,请参阅连接 GitHub 和 Azure 。
在 GitHub 中,浏览你的存储库。 选择“设置”>“安全性”>“机密和变量”>“操作”>“新建存储库机密”。
若要使用应用级凭据 ,请将下载的发布配置文件的内容粘贴到机密的值字段中。 将机密命名为 AZURE_WEBAPP_PUBLISH_PROFILE
。
配置 GitHub 工作流时,在部署 Azure Web 应用操作中使用 AZURE_WEBAPP_PUBLISH_PROFILE
。 例如:
- uses: azure/webapps-deploy@v2
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
在 GitHub 中,浏览你的存储库。 选择“设置”>“安全性”>“机密和变量”>“操作”>“新建存储库机密”。
若要使用用户级凭据 ,请将 Azure CLI 命令的整个 JSON 输出粘贴到机密的“值”字段中。 为机密指定名称,如 AZURE_CREDENTIALS
。
以后配置工作流文件时,请使用该机密作为 Azure 登录操作的输入 creds
。 例如:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
需要向登录操作提供应用程序的“客户端 ID”、“租户 ID”和“订阅 ID” 。 这些值可直接在工作流中提供,或可存储在 GitHub 机密中并在工作流中引用。 将这些值保存为 GitHub 机密是更安全的选择。
打开 GitHub 存储库,然后转到“设置”>“安全性”>“机密和变量”>“操作”>“新建存储库机密”。
为 AZURE_CLIENT_ID
、AZURE_TENANT_ID
和 AZURE_SUBSCRIPTION_ID
创建机密。 将 Active Directory 应用程序中的这些值用于 GitHub 机密。 可以通过搜索 Active Directory 应用程序在 Azure 门户中找到这些值。
GitHub 机密
Active Directory 应用程序
AZURE_CLIENT_ID
应用程序(客户端)ID
AZURE_TENANT_ID
目录(租户)ID
AZURE_SUBSCRIPTION_ID
订阅 ID
通过选择“添加机密”来保存每个机密。
定义要用于 Docker 登录操作的机密。 本文档中的示例使用 Azure 容器注册表作为容器注册表。
在 Azure 门户或 Docker 中转到你的容器,然后复制用户名和密码。 可在 Azure 门户中的“设置” “访问密钥”下找到注册表的 Azure 容器注册表用户名和密码。
为名为 REGISTRY_USERNAME
的注册表用户名定义新机密。
为名为 REGISTRY_PASSWORD
的注册表密码定义新机密。
生成容器映像
以下示例演示生成 Node.JS Docker 映像的部分工作流。 使用 Docker 登录 登录到专用容器注册表。 此示例使用 Azure 容器注册表,但相同的操作也适用于其他注册表。
name: Linux Container Node Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.cn
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.cn/myapp:${{ github.sha }}
docker push mycontainer.azurecr.cn/myapp:${{ github.sha }}
还可使用 Docker 登录 同时登录多个容器注册表。 此示例包括两个新的 GitHub 机密,用于向 docker.io 进行身份验证。 此示例假设注册表的根级别处有一个 Dockerfile。
name: Linux Container Node Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.cn
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: azure/docker-login@v1
with:
login-server: index.docker.io
username: ${{ secrets.DOCKERIO_USERNAME }}
password: ${{ secrets.DOCKERIO_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.cn/myapp:${{ github.sha }}
docker push mycontainer.azurecr.cn/myapp:${{ github.sha }}
部署到应用服务容器
若要将映像部署到应用服务中的自定义容器,请使用 azure/webapps-deploy@v2
操作。 此操作有七个参数:
参数
解释
app-name
(必需)应用服务应用的名称
publish-profile
(可选)适用于 Web 应用(Windows 和 Linux)和 Web 应用容器 (linux)。 多容器场景不受支持。 具有 Web 部署机密的发布配置文件 (*.publishsettings) 内容
slot-name
(可选)输入生产槽以外的现有槽
package
(可选)仅适用于 Web 应用:包或文件夹的路径。 *.zip、*.war、*.jar 或要部署的文件夹
images
(必需)仅适用于 Web 应用容器:指定完全限定的容器映像名称。 例如“myregistry.azurecr.cn/nginx:latest”或“python:3.7.2-alpine/”。 对于多容器应用,可提供多个容器映像名称(多行分隔)
configuration-file
(可选)仅适用于 Web 应用容器:Docker-Compose 文件的路径。 应为完全限定的路径或相对于默认工作目录的路径。 对于多容器应用是必需的。
startup-command
(可选)输入启动命令。 例如,dotnet run 或 dotnet filename.dll
name: Linux Container Node Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.cn
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.cn/myapp:${{ github.sha }}
docker push mycontainer.azurecr.cn/myapp:${{ github.sha }}
- uses: azure/webapps-deploy@v2
with:
app-name: 'myapp'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
images: 'mycontainer.azurecr.cn/myapp:${{ github.sha }}'
on: [push]
name: Linux_Container_Node_Workflow
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# checkout the repo
- name: 'Checkout GitHub Action'
uses: actions/checkout@main
- name: 'Sign in via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.cn
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.cn/myapp:${{ github.sha }}
docker push mycontainer.azurecr.cn/myapp:${{ github.sha }}
- uses: azure/webapps-deploy@v2
with:
app-name: 'myapp'
images: 'mycontainer.azurecr.cn/myapp:${{ github.sha }}'
- name: Azure logout
run: |
az logout
on: [push]
name: Linux_Container_Node_Workflow
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# checkout the repo
- name: 'Checkout GitHub Action'
uses: actions/checkout@main
- name: 'Sign in via Azure CLI'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.cn
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.cn/myapp:${{ github.sha }}
docker push mycontainer.azurecr.cn/myapp:${{ github.sha }}
- uses: azure/webapps-deploy@v2
with:
app-name: 'myapp'
images: 'mycontainer.azurecr.cn/myapp:${{ github.sha }}'
- name: Azure logout
run: |
az logout
后续步骤
可在 GitHub 上找到分组到不同存储库中的操作集,其中每一个都包含文档和示例,帮助你将 GitHub 用于 CI/CD 并将应用部署到 Azure。