将云原生应用手动部署到 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 帐户。 然后在新的分支上:
- 选择“代码”。
- 选择“Codespaces”代码。
- 选择图标 + 以创建 codespace。
GitHub 需要几分钟时间来创建和配置 codespace。 完成此过程后,会显示练习的代码文件。
可选:Visual Studio Code 设置
若要使用 Visual Studio Code,请在你自己的 GitHub 帐户中创建 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops 存储库的分支并在本地克隆它。 然后:
- 安装系统要求以在 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 资源,创建一个用于你的映像的 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
应用命令部署 eShop 应用、前端 Blazor Web 应用和后端 REST API 产品服务,以及将流量路由到 AKS 群集的正确服务的入口规则。 如果在部署上收到任何错误,请重新运行此命令。应会看到类似于以下消息的输出:
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 操作来构建容器映像。