将云原生应用手动部署到 Azure Kubernetes 服务
在自动执行网站部署之前,需要手动将现有 eShop 应用部署到 Azure Kubernetes 服务(AKS)。 使用 Azure CLI 命令和 bash 脚本创建 Azure 资源并将应用部署到 AKS。 最后,创建一个 Azure Active Directory (Azure AD) 服务主体,以允许 GitHub Actions 部署到 AKS 和 Azure 容器注册表。
这些命令创建以下资源来部署更新版本的 eShop 应用。
- 预配 Azure 容器注册表(ACR),然后将映像推送到注册表中。
- 预配 AKS 群集,然后将容器部署到群集中。
- 测试部署。
- 创建服务主体以允许 GitHub Actions 部署到 AKS 和 Azure 容器注册表。
重要
在开始之前,请确保已完成 先决条件 。
开放开发环境
可以选择使用托管练习的 GitHub codespace,或者在 Visual Studio Code 中本地完成练习。
GitHub Codespaces 设置
将 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops 存储库分叉到你自己的 GitHub 帐户。 然后在新的分支上:
- 选择 Code。
- 选择“Codespaces”代码。
- 选择图标 + 以创建代码空间。
GitHub 需要几分钟才能创建和配置 codespace。 该过程完成后,你将看到练习的代码文件。
可选:Visual Studio Code 设置
若要使用 Visual Studio Code,请将 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops 存储库分叉到自己的 GitHub 帐户,并将其克隆到本地。 然后:
- 安装任何 系统要求 以在 Visual Studio Code 中运行开发容器。
- 确保 Docker 正在运行。
- 在新的 Visual Studio Code 窗口中,打开克隆存储库的文件夹
- 按 Ctrl+Shift+P 打开命令面板。
- 搜索:>开发容器:在容器中重新生成和重新打开
- Visual Studio Code 将在本地创建你的开发容器。
生成容器
在终端窗格中,运行以下 dotnet CLI 命令:
dotnet publish /p:PublishProfile=DefaultContainer
创建 Azure 资源
在终端窗格中,使用此 Azure CLI 命令登录到 Azure:
az login --use-device-code
查看所选的 Azure 订阅。
az account show -o table
如果选择了错误的订阅,请使用 az account set 命令选择正确的订阅。
运行以下 Azure CLI 命令,获取 Azure 区域列表及其关联的名称:
az account list-locations -o table
查找一个离你最近的区域并在下一步中用它替换
[Closest Azure region]
运行以下 bash 语句:
export LOCATION=[Closest Azure region] export RESOURCE_GROUP=rg-eshop export CLUSTER_NAME=aks-eshop export ACR_NAME=acseshop$SRANDOM
前面的命令将创建将在下一个 Azure CLI 命令中使用的环境变量。 需要将 LOCATION 更改为靠近你的 Azure 区域;例如 eastus。 如果要为资源组、AKS 群集或 ACR 使用不同的名称,请更改这些值。 若要在 Azure 门户中查看新存储库,请在容器注册表的访问控制(IAM)中自行分配为应用合规性自动化管理员。
运行以下 Azure CLI 命令:
az group create --name $RESOURCE_GROUP --___location $LOCATION az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Basic az acr login --name $ACR_NAME
如果在运行时收到身份验证错误
az acr login --name $ACR_Name
,则需要在“设置 - 访问密钥”下的 Azure 中打开新创建的容器注册中的管理员用户。 Azure 会提示输入这些凭据以继续。 你可能还需要使用az login --use-device-code
再次进行身份验证。这些命令创建一个资源组以容纳 Azure 资源,创建一个用于存储映像的 Azure 容器注册表 (ACR),然后登录该 ACR。 看到此输出可能需要几分钟时间:
... }, "status": null, "systemData": { "createdAt": "2023-10-19T09:11:51.389157+00:00", "createdBy": "", "createdByType": "User", "lastModifiedAt": "2023-10-19T09:11:51.389157+00:00", "lastModifiedBy": "", "lastModifiedByType": "User" }, "tags": {}, "type": "Microsoft.ContainerRegistry/registries", "zoneRedundancy": "Disabled" } Login Succeeded
若要标记映像并将其推送到创建的 ACR,请运行以下命令:
docker tag store $ACR_NAME.azurecr.io/storeimage:v1 docker tag products $ACR_NAME.azurecr.io/productservice:v1 docker push $ACR_NAME.azurecr.io/storeimage:v1 docker push $ACR_NAME.azurecr.io/productservice:v1
可以使用以下命令检查推送映像是否成功完成:
az acr repository list --name $ACR_NAME --output table
使用以下命令创建 AKS 并将其连接到 ACR:
az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --node-count 1 --generate-ssh-keys --node-vm-size Standard_B2s --network-plugin azure --attach-acr $ACR_NAME az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
上述命令创建单个节点 AKS 群集,将其连接到 ACR,然后将本地计算机连接到 AKS 群集。 上述命令可能需要几分钟才能完成。
使用以下命令检查新的 AKS 是否可以从 ACR 拉取映像:
az aks check-acr --acr $ACR_NAME.azurecr.io --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
应会看到与以下消息类似的输出:
[2023-10-19T13:33:09Z] Loading azure.json file from /etc/kubernetes/azure.json [2023-10-19T13:33:09Z] Checking managed identity... [2023-10-19T13:33:09Z] Cluster cloud name: AzurePublicCloud [2023-10-19T13:33:09Z] Kubelet managed identity client ID: 00001111-aaaa-2222-bbbb-3333cccc4444 [2023-10-19T13:33:09Z] Validating managed identity existance: SUCCEEDED [2023-10-19T13:33:09Z] Validating image pull permission: SUCCEEDED [2023-10-19T13:33:09Z] Your cluster can pull images from acseshop1251599299.azurecr.io!
现在可以针对新的 AKS 群集运行 kubectl 命令。 从输出复制完整的 ACR URL;例如,URL 上方是 acseshop1251599299。
检查 AKS 群集的状态:
kubectl get nodes -A
应会看到与以下消息类似的输出:
NAME STATUS ROLES AGE VERSION aks-nodepool1-37200563-vmss000000 Ready agent 3h44m v1.26.6
配置 Kubernetes 部署配置文件
现在 eShop 映像位于 ACR 中,可以更新 AKS 部署清单以使用这些新映像。
在 Visual Studio Code 的资源管理器面板中,选择项目根目录中 deployment.yml 文件。
在第 17 行上替换:
- image: [replace with your ACR name].azurecr.io/storeimage:v1
粘贴上一步复制的 ACR 名称 - 该行应类似于以下的 YAML 格式:
- image: acseshop1251599299.azurecr.io/storeimage:v1
对第 65 行重复这些步骤:
- image: [replace with your ACR name].azurecr.io/productservice:v1
使用 CTRL+S 保存文件。
在终端窗格中,使用以下 kubernetes 命令部署 NGINX 入口控制器:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.3/deploy/static/provider/cloud/deploy.yaml
上述
kubectl
命令将添加服务和组件,以允许进入 AKS 群集。 使用以下 kubernetes 命令检查入口是否已做好运行准备:kubectl get services --namespace ingress-nginx
应会看到与以下消息类似的输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 10.0.135.51 20.26.154.64 80:32115/TCP,443:32254/TCP 58s ingress-nginx-controller-admission ClusterIP 10.0.137.137 <none> 443/TCP 58s
使用以下命令部署 eShop 应用:
kubectl apply -f deployment.yml
kubectl
apply 命令将 eShop 应用程序部署到 AKS 群集,其中包括前端的 Blazor Web 应用和后端的 REST API 产品服务,同时添加入口规则以将流量路由到正确的服务。 如果在部署上收到任何错误,请重新运行此命令。应会看到与以下消息类似的输出:
deployment.apps/storeimage created service/eshop-website created deployment.apps/productservice created service/eshop-backend created ingress.networking.k8s.io/eshop-ingress created
使用以下命令检查是否部署了两个微服务:
kubectl get pods -A
应会看到与以下消息类似的输出:
NAMESPACE NAME READY STATUS RESTARTS AGE default productservice-7569b8c64-vfbfz 1/1 Running 0 3m56s default storeimage-6c7c999d7c-zsnxd 1/1 Running 0 3m56s ingress-nginx ingress-nginx-admission-create-szb8l 0/1 Completed 0 4m4s ingress-nginx ingress-nginx-admission-patch-czdbv 0/1 Completed 0 4m4s ingress-nginx ingress-nginx-controller-58bf5bf7dc-nwtsr 1/1 Running 0 4m4s
使用以下命令查看已部署的 eShop:
echo "http://$(kubectl get services --namespace ingress-nginx ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}')"
上述命令返回 Web 应用的外部 IP 地址。 按住 Ctrl 并单击链接以在新选项卡中打开应用。
创建用于从 GitHub 进行部署的服务主体
GitHub Actions 可以将容器映像发布到 Azure 容器注册表。 因此,GitHub 运行程序必须有权连接到 Azure。 以下步骤创建一个 Azure AD 服务主体,充当 Azure 中的 GitHub Actions 标识。
若要在环境变量中保存订阅 ID,请在终端中运行以下命令:
export SUBS=$(az account show --query 'id' --output tsv)
若要创建 Azure AD 服务主体以允许从 GitHub 访问,请运行以下命令:
az ad sp create-for-rbac --name "eShop" --role contributor --scopes /subscriptions/$SUBS/resourceGroups/$RESOURCE_GROUP --json-auth
随即显示以下输出的变体:
Creating 'Contributor' role assignment under scope '/subscriptions/ffffffff-aaaa-bbbb-6666-777777777777' The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli { "clientId": "00001111-aaaa-2222-bbbb-3333cccc4444", "clientSecret": "abc1A~abc123ABC123abc123ABC123abc123ABC1", "subscriptionId": "00000000-0000-0000-0000-000000000000", "tenantId": "00000000-0000-0000-0000-000000000000", "activeDirectoryEndpointUrl": "https://login.microsoftonline.com", "resourceManagerEndpointUrl": "https://management.azure.com/", "activeDirectoryGraphResourceId": "https://graph.windows.net/", "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/", "galleryEndpointUrl": "https://gallery.azure.com/", "managementEndpointUrl": "https://management.core.windows.net/" }
复制要在下一步中使用的 JSON 输出和括号。
创建 GitHub 密钥
GitHub Actions 运行器使用凭据来与容器注册表和 AKS 交互。 容器注册表的服务主体和凭据是敏感信息。 最好将敏感信息存储为安全位置的加密 机密 。 GitHub 提供用于存储机密和其他变量的内置位置。
完成以下步骤,安全地将敏感信息存储为存储库中的环境变量。 存储库管理员应管理 GitHub Actions 运行程序可以访问的机密。
在已分支的 GitHub 存储库中,转到 Settings>Secrets and variables>Actions。
在 Actions secrets and variables 页面上,选择 New repository secret。
在 New secret 页面上, Name输入 AZURE_CREDENTIALS,然后在下方 Secret输入从终端复制的 JSON 输出。
这些设置应类似于以下屏幕截图:
选择 Add secret。
在下一部分中,你将使用此 GitHub 机密来创建一个 GitHub 操作,以生成容器映像。