设计和实施微软 DevOps 解决方案:AZ-400 考试指南(四)

原文:annas-archive.org/md5/eb2d156388068d02b11a808e92183ccf

译者:飞龙

协议:CC BY-NC-SA 4.0

第十六章:容器

在过去几年中,容器已成为热门话题。它们允许您打包任何应用程序或工具,使用任何语言编写,并在基本主机或集群上部署。在实施 DevOps 时,容器可以提供巨大的价值。这就是为什么 DevOps 和容器经常被同时提及的原因。然而,它们并不是同一回事。虽然 DevOps 是一种文化,但容器是一种技术,是一种托管应用程序的替代方式。

在本章中,您将学习有关容器及其工作原理的更多信息。通过练习,可以创建自定义容器镜像,并在不同的托管平台上运行,例如 Azure 容器实例和 Kubernetes。

本章将涵盖以下主题:

  • 容器简介

  • 构建容器镜像

  • 在 Azure DevOps 中构建镜像并在 Azure 中运行

  • Kubernetes 简介

  • Kubernetes 实践

  • 升级容器

  • 扩展容器和 Kubernetes

  • 使用 Azure DevOps 部署到 Kubernetes

技术要求

要尝试本章描述的技术,您需要以下一项或多项:

  • Docker Desktop

  • Visual Studio 2019/Visual Studio Code

  • Azure 订阅

  • Azure 命令行界面(CLI)

所有这些都可以免费获取,或者可以免费获取一段时间用于评估。

容器简介

容器是虚拟化的进化。通过虚拟化,物理机的资源被多个虚拟机共享。共享这些资源意味着所有虚拟机都有自己的操作系统。但是使用容器时情况有所不同。容器不仅共享资源,还共享操作系统内核,因此与虚拟机镜像相比,它非常小。

由于共享操作系统内核,容器也非常易于移植。镜像可以部署在支持运行容器的任何类型的主机环境上。这是因为所有应用程序的二进制文件和配置都存储在容器内部。因此,容器外部的环境变量不会影响应用程序。

当然,有一些注意事项,例如容器共享操作系统内核。

容器提供了在单个操作系统上运行多个工作负载的能力。下图展示了常规托管、虚拟机托管和容器之间的区别:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_01.jpg

图 16.1 – 从虚拟化到容器

如果您听说过容器,几乎肯定也听说过 Docker。这是因为 Docker 是最知名的容器引擎之一,可用于运行容器。

下一节将深入探讨 DevOps 和容器,而本章的其余部分将更详细地介绍容器的技术细节。

DevOps 和容器

如在介绍中所提到的,DevOps 和容器并不是同一回事。容器是让 DevOps 变得更容易的技术。这是因为容器具有使其成为 DevOps 完美工具的优势:

  • 一致性:因为您构建了容器镜像,"它在我的机器上可以工作"这一障碍被消除了。

  • 关注点分离:使用容器时,您的应用程序将被分布在多个独立的容器中,这使得维护和分离进程变得更加容易。

  • 平台:该解决方案可以在不同的平台上运行。无论是在 Microsoft Azure、Amazon Web Services、Google Cloud,还是本地环境中,包括甚至是您的开发机器上,都不重要。

此外,DevOps 更偏向文化而非技术,正如在第一章《DevOps 简介》中提到的那样,技术组件用于支持 DevOps。在本章的其余部分,我们将关注技术层面的内容。

托管选项

如前所述,容器的一个好处是它们具有极强的可移植性。这也意味着容器可以托管在多种平台和技术上。

为了运行容器,您有许多选项,这些选项将根据您的使用场景有所不同。以下是其中一些选项:

  • Azure 应用服务

  • Azure 服务网格

  • Docker Swarm

  • Docker Desktop

  • Kubernetes

根据应用程序/容器的需求,它可以在前面提到的所有选项中运行。

用于运行容器的镜像(容器镜像)也需要托管。这些镜像托管在所谓的容器注册表中。在容器注册表中,它们可以是私有发布或公开发布的。最著名的两个注册表是 Docker Registry 和 Azure 平台中的 Azure Container Registry。

现在我们已经了解了一些有关容器的背景信息,接下来我们将深入探讨容器背后的技术,了解创建自定义容器镜像所需的内容。

构建容器镜像

本节将带您了解构建容器镜像并在本地系统上执行它的过程。为此,我们将首先创建一个应用程序,然后为其添加 Docker 支持,接着创建镜像并最终进行测试。那么,开始吧!

创建应用程序

要测试和检查容器中正在运行的内容,需要一个应用程序。为此,可以创建一个新的应用程序,也可以使用现有的应用程序。

在创建一个新的应用程序时,最简单的选择是在 Visual Studio 2019 中使用默认的 ASP.NET Core 网站模板。容器支持可以通过几个点击轻松添加。只需在创建项目时勾选启用 Docker框即可:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_02.jpg

图 16.2 – 带有 Docker 支持的 ASP.Net Core 新应用程序

保持新应用程序打开,或者打开现有的应用程序。在下一部分,我们将探讨如何向现有应用程序添加 Docker 支持。

向现有应用程序添加 Docker 支持

向现有应用程序添加 Docker 支持只需要几个简单步骤:

  1. 在 Visual Studio 2019 中打开项目/解决方案,并右键单击项目。

  2. 选择添加并选择Docker 支持

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_03.jpg

图 16.3 – 带有 Docker 支持的 ASP.Net Core 现有应用程序

根据客户端工具和 Visual Studio 配置,也可能会有一个容器编排器支持选项。通过此选项,可以选择您选择的云编排器。在此示例中,我们使用了 Docker Compose,因为这种格式得到了主要容器编排器的支持。然而,确实存在其他云编排器选项:

  • Docker Swarm

  • Kubernetes

  • Mesos Marathon

根据使用的云编排器,项目中会添加一个特定格式的文件,适用于该编排器。

通过添加 Docker 支持,项目中会添加一个名为 Dockerfile 的新文件。Dockerfile 是容器镜像的规范。Docker 可以读取该文件,将其视为指令。该文件是一个文本文件,包含单独的命令,这些命令也可以在命令行工具中调用以组装镜像:

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 555
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["WebApplication2.csproj", "."]
RUN dotnet restore "WebApplication2.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "WebApplication2.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApplication2.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication2.dll"]

这个示例使用了一种称为多阶段构建文件的技术。这是因为该文件使用了多个FROM语句,其中有对特定镜像的引用。

在多阶段构建之前,无法使用多个 FROM 语句。在那时,构建高效的容器镜像是非常困难的。文件中的每个语句代表镜像上的一个附加层,导致镜像变得越来越大。

在此构建过程中,还需要移除一些在该过程中需要的组件。因此,在开发和生产环境中使用单独的 Dockerfile 文件是非常常见的做法。

如前所述,Dockerfile 包含了一些指令,最常用的指令如下:

  • FROM 命令用于指定镜像将基于哪个操作系统或基础镜像。在前面的示例中,使用 mcr.microsoft.com/dotnet/aspnet:3.1 AS 基础镜像来构建应用程序的生产版本。

  • RUN 命令用于在容器镜像的构建过程中安装组件或执行操作。

  • ENTRYPOINT 命令指定容器镜像的入口点。在前面的示例中,入口点指定为一个 .NET 应用程序,该应用程序引用了在编译过程中构建的库。

到目前为止,我们已经创建了应用程序并添加了 Docker 支持。接下来,我们将学习如何使用该应用程序创建镜像。

使用应用程序创建镜像

为了能够创建 Docker 镜像,必须安装 Docker Desktop,因为 Visual Studio 使用它来构建镜像。完成 Dockerfile 后,可以使用以下步骤构建镜像:

在 Visual Studio 中右击 Dockerfile 并选择构建 Docker 镜像

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_04.jpg

图 16.4 – 一个 Asp.Net Core 应用程序构建的 Docker 镜像

在编译和构建镜像时,查看输出窗口。查看它将为你提供有关容器镜像分层方法的更多见解。

Docker Desktop 还可以让你在本地运行和存储镜像。构建镜像后,打开终端并运行以下命令:

docker images

该命令显示机器上当前所有的镜像。在此列表中,也列出了在创建镜像时下载的基础镜像:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_05.jpg

图 16.5 – Docker 镜像列表

我们已经看过如何添加 Docker 支持并为现有和新的 ASP.NET Core 应用程序制作 Docker 镜像。接下来的部分将探讨如何运行容器镜像。

运行容器镜像

容器镜像可以通过在 Docker 中运行来本地启动。现在我们有了容器镜像,可以创建一个容器:

  1. 运行以下 docker container run 命令:

    docker container run --publish 8123:80 --detach --name [container name] [image name]
    

前述命令将在命令末尾指定的容器镜像启动。此外,还指定了不同的参数:

  • publish 参数从主机打开一个端口到容器。如前一部分中的示例所述,这将打开端口 8123 并将流量路由到容器内的端口 80

  • detach 参数将使容器在后台运行,并打印出其特定的 ID。

  • Name: 容器在 Docker 中的名称。

  1. 要列出所有正在运行的容器,请在终端中使用docker ps命令。

  2. 容器运行后,打开浏览器并访问 http://localhost:8123。如果一切正常,应该会显示一个默认的 ASP.NET Core 网页:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_06.jpg

图 16.6 – ASP.Net Core 默认欢迎页面

由于在本地构建东西并在你的机器上运行并不是 DevOps 的做法,接下来的章节中我们将转向不同的托管平台。

在 Azure DevOps 中构建镜像并在 Azure 中运行

为了支持持续集成和持续交付,源文件需要在一个仓库中共享。因此,让我们在 Azure Repos 中共享资源,并尝试通过 Azure Pipelines 构建我们的容器。在构建容器镜像之后,还需要一个存储镜像和运行容器的位置。在 Azure 平台上,有两个非常适合这种场景的服务:

  • Azure 容器注册表 (ACR):该服务是基于开源 Docker 注册表的托管私有 Docker 注册表。在这里,您可以维护和注册容器镜像。

  • Azure 容器实例Azure 容器实例,也称为 ACI,是一种运行隔离容器的解决方案,无需大量管理。

重要提示

为了简化本指南,文件已被添加到仓库中,Azure 资源也已创建。

在下一部分中,我们将探索如何在 ACR 中创建镜像并通过 Azure DevOps 在 ACI 中运行它们。

创建服务端点

正如本书中已讨论的,Azure DevOps 与外部服务(如 Azure 和容器注册表)的连接是通过服务端点配置的。由于 ACI 需要访问镜像,因此必须将镜像发布到容器注册表。Azure DevOps 到注册表的连接是通过服务连接进行配置的。

执行以下步骤来配置服务连接:

  1. 在 Azure DevOps 项目中,打开项目设置。

  2. 在项目设置中,点击 服务连接

  3. 在服务连接概述中,点击 创建服务连接 并选择 Docker 注册表

  4. 在弹出的菜单中,填写正确的信息并保存连接:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_07.jpg

图 16.7 – 新的 Azure 容器注册表服务连接

保存连接将为项目添加一个服务连接,管道可以使用该连接,或者您将来创建的管道也可以使用它。

创建新管道

为了开始构建容器镜像并将其发布到注册表,我们将创建一个新的管道。在这个例子中,我们将使用 YAML 管道体验。

执行以下步骤以开始使用管道:

  1. 打开您的 Azure DevOps 项目并点击 Pipelines

  2. 在管道概述中,点击 新建管道

  3. 选择 Azure Repos Git,选择正确的仓库,然后选择 Starter pipeline

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_08.jpg

图 16.8 – Azure DevOps – 配置新管道

  1. 从启动管道中,删除两个虚拟脚本任务并打开助手。

  2. 在助手中,搜索 Docker 任务并将任务添加到管道中。

  3. 选择为容器注册表创建的服务连接,并保持其他信息为默认值。

重要提示

请确保将任务的buildContext属性更改为指向正确的目录。这是 Docker 能够引用正确路径构建镜像所必需的。

添加后,YAML 应如下所示:

- task: Docker@2 
  inputs:
    containerRegistry: 'MSFT Container Registry' 
    repository: 'azuredevops'
    command: 'buildAndPush' 
    Dockerfile:'**/Dockerfile' 
    buildContext:
'$(System.DefaultWorkingDirectory)/ExistingDevOpsProject'
  1. 保存并运行管道。在第一次运行后,容器镜像被创建并发布到容器注册表。

容器注册表中的镜像可以通过使用预定义的 URL 进行检索。该 URL 由几个特定的组件组成:

[container registry]/[repository]:[tag]:
  • 容器注册表:容器注册表的基础 URL。

  • 仓库:在发布镜像过程中指定的仓库。

  • BuildId

  1. 现在我们已经获得了容器镜像的引用,ACI 应该能够检索容器并运行它。所需的唯一操作是一个 Azure CLI 命令:

    az container create --resource-group [resource group] --name [ACI name] --location westeurope --image [Image reference] --dns- name-label [dns reference] --ports 80 --registry-username [username of the registry] --registry-password [password of the registry]
    

由于每个构建的图像引用不同(对于标签值是BuildId),因此通过 Azure CLI 命令中的$(Build.BuildId)变量获取BuildId

az container create --resource-group aci-rg-devops --name aci- demo-app --location westeurope --image msftazuredevops.azurecr.io/azuredevops:$(Build.BuildId) --dns- name-label aci-msft-demo --ports 80 --registry-username
$(username) --registry-password $(password)

要执行上述脚本,需要将 Azure CLI 任务添加到管道中。在此任务中,我们通过服务端点配置正确的订阅,并设置内联脚本。

脚本将在aci-rg-devops资源组中创建一个名为aci-demo-app的容器实例,并从msftazuredevops.azurecr.io仓库中检索azuredevops容器镜像。

该任务的完整 YAML 配置如下:

- task: AzureCLI@2 
  inputs:
  azureSubscription: 'Subscription MPN' 
  scriptType: 'bash'
  scriptLocation: 'inlineScript'
  inlineScript: 'az container create --resource-group aci-rg- devops -
name aci-demo-app --location westeurope --image msftazuredevops.azurecr.io/azuredevops:$(Build.BuildId) --dns- name-label aci-msft-demo --ports 80 --registry-username
$(username) --registry-password $(password)'

运行此管道将在 Azure 中生成一个 Azure 容器实例。该容器将运行与本地运行的完全相同的应用程序:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_09.jpg

图 16.9 – 一个运行在 ACI 中的 aci-demo-app 实例

在 Azure 门户中打开 Azure 容器实例时,您会看到它是一个正在运行的实例,并且在 Azure CLI 命令中会看到dns-name-label,例如aci-msft-demo.westeurope.azurecontainer.io。在浏览器中打开该 URL,查看我们已经推送到容器中的应用程序:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_10.jpg

图 16.10 – aci-demo-app 欢迎页面

它显示的内容与本地启动的容器相同。这是因为,在两个地方都启动了相同的容器镜像。

在这一部分,我们启动了 ACI 上的容器,但当容器出现问题时,我们如何管理正在运行的容器并重新启动它们呢?这就是 Kubernetes 的作用。

Kubernetes 简介

Kubernetes 是另一个用于运行容器的服务。Kubernetes 是由 Google 最早开发的集群编排技术。它现在是一个开源平台,用于自动化部署、扩展和操作跨主机集群的应用程序容器,从而提供面向容器的基础设施。术语 Kubernetes 通常缩写为K8s。这是通过将单词ubernete中的八个字母替换为数字 8 生成的。

Kubernetes 的功能

如前所述,容器为你提供了一个打包应用程序的好方法。在运行这些应用程序时,你需要确保应用程序保持运行,这就是 Kubernetes 发挥作用的地方,因为它具有以下核心功能:

  • 服务发现和负载均衡:容器的暴露方式由 Kubernetes 内部控制,此外,它还能够在调度中平衡流量。

  • 存储编排:将不同种类的存储提供商挂载到平台的能力。

  • 发布和回滚:Kubernetes 可以自动为指定的部署创建并重启容器。

  • 自我修复:当容器发生故障时,Kubernetes 可以修复容器。

  • 秘密和配置管理:Kubernetes 内置了管理秘密(如令牌、密码和密钥)的功能。

为了提供这些功能,Kubernetes 由多个组件组成。

Kubernetes 核心组件和服务

Kubernetes 由几个核心组件组成,这些组件共同构成一个出色且稳定的容器运行与管理产品。接下来的几个子部分将逐一介绍这些组件。

主节点

Kubernetes 中的一个重要组件是主节点。该节点管理集群。它包含所有的 Kubernetes 核心组件,以便管理集群:

  • kubectl 和 Kubernetes 仪表盘。

  • etcd:用于维护 Kubernetes 集群的状态。

  • kube-scheduler:一个选择节点以便 Pods 运行的组件。

  • kube-controller-manager:控制器管理器负责监督多个小型控制器,执行如复制 Pods 和管理节点操作等任务。

通过使用这些组件,主节点可以保持集群所需的状态。需要知道的是,当你与 Kubernetes 交互时,实际上是在与主节点进行通信。然后,主节点会与集群内的其他组件进行通信。

普通节点

这些是将运行容器的节点。有时它们被称为工作节点。它们可以是虚拟机,甚至是物理机器。在这些机器上,安装了所谓的 kubeletkubelet 是用于在节点内运行 Pods/容器的代理。

正如你在前面的章节中所注意到的,Kubernetes 中还有其他核心服务,我们接下来将讨论它们。

Pod

在 Kubernetes 中,Pods 用于运行应用程序。在 Pods 内部,指定了运行应用程序所需的资源。Kubernetes 中的调度器(kube-scheduler)会根据需求和与集群连接的节点来决定应用程序的运行位置。

Pods 有有限的生命周期,在新版本部署时会被移除。此外,当节点发生故障时,Pods 可以由同一节点或另一节点上的 Pods 替代。

服务

该服务有时也被称为负载均衡器,用于提供 Pods 的逻辑分组,并为它们提供连接性(连接的方式)。

三个主要服务如下:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_11.jpg

图 16.11 – K8s 服务关系图

三个主要服务如下:

  • 集群 IP:为服务添加一个内部 IP。选择此选项时,服务只能从集群内部访问。这是标准的服务类型。

  • 节点端口:节点端口服务在每个集群节点上建立一个端口,因此得名,并将到达该端口的流量路由到底层服务。它将服务暴露给外部客户端。

  • 负载均衡器:此服务添加一个负载均衡资源,并在负载均衡器上配置一个外部 IP 地址。在外部,负载均衡器将根据负载均衡器中配置的规则将流量路由到特定节点,并在内部路由到正确的 Pod。

通过这些服务,Pods 的内部和外部连接得以安排。服务和 Pods 都在一个部署中被指定。

部署

Kubernetes 部署是一个资源对象,概述了应用程序的预期状态。它指定副本数量以及应用程序的更新策略。Kubernetes 会监控 Pods 的健康状况,并根据需要删除或添加 Pods,以达到部署中指定的期望状态。

这些部署在 YAML 文件中被指定。例如,在 Kubernetes 中运行容器时,必须指定副本集。副本集确保在任何给定时刻运行指定数量的 Pod 副本。

Kubernetes 操作

当你刚接触容器,尤其是 Kubernetes 时,很难立即弄清楚。为了帮助你理解这个概念,看看下面的图示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_12.jpg

图 16.12 – Kubernetes 操作概览

将容器部署到 Kubernetes 集群中是通过所谓的部署文件 (1) 来定义的。在这些部署文件中,应用程序的期望状态被描述。这个期望状态被描述为一个 YAML 文件。

在这个例子中,期望的状态是一个负载均衡服务和三个 Pods (2)。这些 Pods 由 Kubernetes API 在运行容器的节点上划分 (3)。部署文件中定义的服务确保流量被路由到特定的 Pods。通过更新部署,可以更改部署。

调度器也可以在配置了应用程序的自动扩展时更改部署。在这种情况下,可以向集群中添加第四个 Pod。在服务中,也可以有一个外部负载均衡器,将流量路由到 Kubernetes 的内部负载均衡器 (4)。

Azure Kubernetes 服务

Azure Kubernetes 服务AKS)是微软实现的 Kubernetes。设置常规 Kubernetes 集群需要很多工作,但使用 AKS 后,操作变得更加简便。这是因为 AKS 是一个托管平台,几乎所有操作任务都由平台本身处理。

AKS 的一些关键功能如下:

  • Azure 管理关键任务,如健康监控、扩展和维护,包括根据配置和管理需求进行的 Kubernetes 版本升级和修补。

  • Kubernetes 的主节点完全由 Azure 管理。

  • 主节点是免费的,您只需为运行代理节点付费。您只需为工作节点付费;主节点是免费的,因为 Kubernetes 集群的主节点由 Azure 管理。您管理集群的代理节点,并仅为运行节点的虚拟机VMs)付费。

使用 AKS 后,Kubernetes 集群可以在几分钟内投入使用,主节点由 Azure 管理,因此重点将放在应用程序开发和部署上。现在,让我们尝试运行一个带有自定义镜像的 Kubernetes 集群。

Kubernetes 实践

在本章的前几个部分中,我们创建了一个容器并将其部署到 Azure 容器实例。现在,让我们将这个容器部署到 Kubernetes 集群中。

创建集群可以通过 Azure CLI 或 Azure 资源管理器ARM)模板进行。为了便于演示,将使用 Azure CLI。

首先,需要创建一个新的资源组来托管 Azure Kubernetes 集群:

az group create --name mpn-rg-kubernetes --location westeurope

现在,我们可以创建我们的 Kubernetes 集群。

创建 Kubernetes 集群

当资源组创建后,可以将新的 Kubernetes 集群添加到该组中:

az aks create --resource-group mpn-rg-kubernetes --name mykubernetescluster
--node-count 1 --enable-addons monitoring --generate-ssh-keys

该命令创建了一个名为 mykubernetescluster 的新 Kubernetes 集群,并且只包含一个节点。这意味着将在 Azure 门户中创建一个 VM,并将其配置为 Kubernetes 集群的节点。此外,将启用集群上的监控插件。

创建该集群将需要几分钟时间。在 Azure 中,将在指定的资源组中创建 mykubernetescluster 服务。除了该资源组,Azure 平台本身还将创建另一个资源组。

Kubernetes 基础设施

在该资源组中,创建了运行集群所需的所有虚拟化基础设施。这也意味着将来可以根据应用程序的需求将新组件添加到此资源组中:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_13.jpg

图 16.13 – mpn-rg-kubernetes 资源组

在创建的资源组中,您将找到所有运行集群所需的上述资源:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_14.jpg

图 16.14 – 运行集群所需的一些资源列表

现在 Kubernetes 基础设施已启动并运行,可以开始管理和部署资源。

管理 Kubernetes

要管理 Kubernetes,使用 kubectl 命令行工具,并且在本地安装(或者在 Azure Cloud Shell 中使用)。这是一个与 Kubernetes API 通信的命令行界面工具。让我们看看如何使用这个命令行与 Kubernetes 一起工作:

  1. 首先,下载并安装 kubectl,如果您尚未安装 Azure CLI,请运行以下命令以在您的计算机上安装 Azure CLI:

    az aks install-cli
    
  2. 要连接到集群,需要检索凭据并将其保存到本地系统。可以使用 az aks get-credentials 命令并指定资源组和集群名称来完成此操作:

    az aks get-credentials --resource-group mpn-rg-kubernetes -- name mykubernetescluster
    
  3. 配置好所有前提条件后,可以对 Kubernetes 集群执行大部分基本功能。举个例子,看看这两个命令:

    • 检索集群的节点:

      kubectl get nodes
      
    • 获取集群中的 Pods:

      kubectl get Pods
      
  4. 除了前面的命令外,您还可以尝试以下 Azure CLI 命令来打开 Kubernetes 仪表盘。该仪表盘是构建在 Kubernetes API 之上的管理界面,可以与 kubectl 命令行一起使用:

    az aks browse --resource-group mpn-rg-kubernetes --name mykubernetescluster
    

仪表盘如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_15.jpg

图 16.15 – 查看 Kubernetes 仪表盘

需要创建一个部署文件,以便在集群内运行容器。那么,让我们看看如何做到这一点。

部署容器镜像

我们将创建一个部署文件并将其部署到 Kubernetes。为此,请执行以下步骤:

  1. 在您喜欢的文本编辑器中创建一个新文件,命名为 deploy.yaml。将以下信息添加到 deploy.yaml 文件中:

    apiVersion: apps/v1 
    kind: Deployment 
    metadata:
      name: kubernetes-deployment 
      labels:
        app: customapplication 
    spec:
    replicas: 3
    selector:
      matchLabels:
        app: customapplication 
    template:
      metadata: 
        labels:
          app: customapplication 
      spec:
        containers:
        - name: azuredevops
          image: msftazuredevops.azurecr.io/azuredevops:586 
          ports:
          - containerPort: 80
    

在这个示例中,以下内容已被指定:

  • 部署使用名称 kubernetes-deployment 创建(metadata.name)。

  • 部署将创建指定容器的三个副本(spec.replicas)。

  • 选择器与 labels 标签结合使用,用于指定该部署文件将在 Kubernetes 中管理哪些组件。

  • 部署文件将为 msftazuredevops.azurecr.io/azuredevops:586 镜像文件创建一个容器。

  1. 要将此文件部署到 Kubernetes,我们将再次使用 kubectl 命令行,并利用 apply 命令:

    kubectl apply -f deploy.yaml
    

-f 参数用于指定使用本地路径作为部署文件的引用。执行命令后,您可以打开 Kubernetes 仪表盘查看状态,甚至可能观察到错误。

重要提示

可能会遇到一个错误,提示从您的位置拉取镜像失败。这可能是一个安全问题。在底层,AKS 使用的是服务主体。在创建新的 Kubernetes 集群时,您应该也会看到这个问题。确保为该服务主体授予 Azure 容器注册表的访问权限。

  1. 执行成功后,尝试执行 get Pods 命令,查看系统中是否有三个 Pod。如果一切顺利,Kubernetes 中应该运行着三个 Pod,但应用程序仍然无法对外界可用。

为了让它可用,我们需要在部署文件中添加一个服务。

重要提示

如果你想在同一个文件中添加服务,可以在部署之间添加一行包含 --- 字符的分隔符。如果你定义了单独的部署文件,则不需要这么做。

deploy.yaml 文件中,添加以下部分:

---
apiVersion: v1 
kind: Service 
metadata:
  name: customapplication-service 
spec:
  type: LoadBalancer 
  ports:
  - port: 80 
  selector:
    app: customapplication

这个 YAML 部分会创建一个负载均衡器,并将其附加到指定的选择器(spec.selector.app),这意味着它将用于之前指定的 Pods。

在后台,Kubernetes 会创建一个 Azure 负载均衡器,并为与 Pods 连接分配一个公共 IP 地址。

  1. 若要检索服务的外部 IP 地址,请使用以下命令,直到它显示出外部 IP 地址为止:

    kubectl get service
    

这将返回所有服务及其外部 IP 地址(如果存在)。同时,快速查看 Kubernetes 的附加资源组,看看哪些 Azure 资源已被创建。

做得好!在本节中,你学习了如何创建 Kubernetes 集群,并通过 kubectl 和部署文件将容器镜像部署到其中。在下一节中,我们将继续学习如何升级这些容器。

升级容器

在 Kubernetes 中,应用程序非常容易更新。为此,Kubernetes 使用滚动更新,意味着在替换容器之前,容器的流量会先被清空。在应用程序升级过程中,Kubernetes 会部署一个额外的 Pod,并通过一些指定的探针来运行它。

探针是对 Pod 进行定期检查状态的诊断工具。在升级或创建 Pod 期间,Kubernetes 会启动额外的 Pod,并确保它通过存活探针和就绪探针。

如果新创建的 Pod 成功通过了两个探针,流量将从一个旧 Pod 中断开,转而指向新 Pod。对于这种终止,Kubernetes 使用终止宽限期。在此期间,与负载均衡器的连接被停止,活跃连接会被成功处理,新的流量会被路由到正在运行的 Pod。在默认的 30 秒宽限期内,Pod 处于终止状态,所有到该 Pod 的流量将被转发到其他 Pods。

这个过程会持续进行,直到所有 Pod 被新版本替换。这些都是 Azure Kubernetes 中的默认行为。只需调整部署文件并使用与之前相同的命令应用它,就可以触发部署:

Kubectl apply -f [file]

默认情况下,httpGet 探针会被添加到正在暴露的 Pods 中,但也可以通过在部署文件中添加就绪探针或存活探针来自定义它们:

readinessProbe:
    httpGet:
        scheme: HTTPS
        path: /index.xhtml
        port: 8483 
        initialDelaySeconds: 5
        periodSeconds: 5
        successThreshold: 1

此就绪探测在 Pod 上执行httpGet请求,并具有以下选项:

  • path: 执行httpGet请求时应调用的路径。

  • port: 用于调用的端口号。这也在我们的部署文件中配置。

  • initialDelaySeconds: 容器启动后运行探测前等待的秒数。

  • periodSeconds: 探测在超时之前等待的秒数。

  • successThreshold: 探测所需的最小成功次数为1

如前所述,部署配置了默认的滚动升级场景。可以使用以下命令检索滚动部署的配置:

kubectl describe deployment kubernetes-deployment

重要提示

如果您有兴趣这样做,请在 Kubernetes 内构建并升级容器的新版本。在运行升级之前,请确保打开了仪表板,在更新过程中刷新页面,您将看到额外的 Pod 出现并且旧的 Pod 被终止。

在本节中,我们学习了如何升级容器,这将帮助您保持最新版本。接下来,在下一节中,我们将进一步探讨容器和 Kubernetes 的扩展。

扩展容器和 Kubernetes

随着应用程序需求的增长,您需要扩展应用程序。可以通过多种方式进行应用程序的扩展,可以扩展不同的组件:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_16.jpg

图 16.16 – AKS 中的自动缩放器

上图显示了应用程序或集群扩展的不同方式,我们将在接下来的小节中讨论。

手动扩展 Pod

可以通过更新副本数量轻松扩展 Pod。尝试使用kubectl get Pods命令获取您的 Pod,并使用以下命令增加副本数量:

kubectl scale --replicas=[number of Pods] deployment/[deploymentname]

此命令根据副本数量调整 Pod 的规模。规模按照部署配置进行调整。

Pod 自动缩放

AKS 也支持自动缩放。调度程序将根据 CPU 利用率或其他可用的指标更新 Pod 的数量。

Kubernetes 使用度量服务器进行此操作。度量服务器从集群中的节点上运行的 kubelet 代理的摘要 API 中收集度量。

自动缩放功能还需要在 Kubernetes 部署端进行一些配置。对于部署,您需要指定运行容器的请求和限制。这些值针对特定的度量标准进行指定,例如 CPU。

在以下示例中,为 CPU 度量标准指定了请求和限制。CPU 度量标准以 CPU 单位进行测量。在 Azure 中,一个单位代表一个核心。在不同的平台上,一个单位可能有不同的含义:

resources: 
  requests:
    cpu: 0.25 
limits:
    cpu: 0.5

可以将此部分添加到部署文件的容器中,这将确保在需要大量请求时可以自动扩展 Pod。

使用更新后的部署文件,部署它并在 Kubernetes 集群中设置自动扩展规则:

kubectl autoscale deployment [deployment name] --cpu-percent=60 --min=1 --max=10

该规则将更新部署并添加自动扩展功能。如果所有 Pods 的平均 CPU 利用率超过它们请求的使用量的 60%,则自动扩展器将增加 Pods 数量,最多可增加至 10 个实例。然后,为该部署定义了最小实例数为 1:

创建自动扩展器后,您可以通过运行以下命令来检查它:

kubectl get hpa

提示

HPA 代表 Horizontal Pod Autoscaler(水平 Pod 自动扩展器)。

尝试在应用程序中创建一个 CPU 密集型操作,并在执行期间检查自动创建的 Pod。Kubernetes 集群会注意到 CPU 使用量的显著增加,并会通过创建多个 Pod 自动扩展集群。

一旦密集型操作完成,Kubernetes 会将 Pods 数量缩减至最小值。

缩放节点

除了缩放 Pods 外,Kubernetes 还可以缩放 Kubernetes 集群中运行的节点数量。可以使用以下命令缩放节点数量:

  1. 首先,通过请求节点的数量,获取与当前环境相关的信息:

    az aks show --resource-group mpn-rg-kubernetes --name mykubernetescluster --query agentPoolProfiles
    
  2. 然后,使用此命令更新nodepool。从上一个命令的结果中提取nodepool的名称:

    az aks scale --resource-group mpn-rg-kubernetes --name mykubernetescluster --node-count 2 --nodepool-name nodepool1
    

增加节点数量可以大幅提升性能,但这也会使集群变得更加昂贵。通过缩减集群节点数量,可以降低成本,同时只使用应用程序实际需要的资源。为了跟踪这一点,节点也可以进行自动缩放。

自动缩放节点

除了手动缩放节点外,还可以通过更新 Kubernetes 集群来实现节点的自动缩放。这可以通过使用az aks update命令来完成。通过此命令,您可以设置节点的最小和最大数量。然后,自动扩展器将确保在需要时创建节点:

az aks update --resource-group mmpn-rg-kubernetes --name mykubernetescluster  --update-cluster-autoscaler --min-count 1 --max-count 5

AKS 还提供了使用 ACI 扩展的选项。要使用此选项,在创建 AKS 集群时需要应用特定的配置。这是因为 ACI 需要虚拟网络中的特定子网。

在这一部分,我们学习了如何缩放容器和集群,从而大幅提升性能。接下来是通过 Azure DevOps 进行部署,以实现持续部署。

使用 Azure DevOps 部署到 Kubernetes

我们已经看到了许多通过命令行部署和配置 Kubernetes 集群的选项。然而,在与 DevOps 一起工作时,变更需要以持续的方式进行应用。

为此,Azure DevOps 中有 Kubernetes 清单任务,包含许多功能来管理 Kubernetes 集群:

task: KubernetesManifest@0 
  inputs:
  action: 'deploy'
  kubernetesServiceConnection: '[service connection name]' 
  manifests: '[path to your deployment file]'
  containers: 'msftazuredevops.azurecr.io/azuredevops:$(Build.BuildID)'

在前面的示例中,配置了以下内容:

  • action:我们希望执行的操作类型。在这个示例中,使用deploy操作,因为我们要部署/应用部署文件。

  • kubernetesServiceConnection:与 Kubernetes 集群的服务连接。

  • manifests:清单文件的路径。由于我们使用的是部署操作,因此这应该是对部署文件的引用。

  • containers:一个特殊字段,可以覆盖正在部署的容器的版本。通过指定前述内容,部署清单中的每个镜像都会使用msftazuredevops.azurecr.io引用,并且azuredevops存储库将被替换为此字段中配置的新值。

在 Azure DevOps 管道中使用 Kubernetes 目标环境的另一个优点是可以看到 Azure DevOps 中运行的环境。这将显示集群中正在运行的 Pods 数量。

尝试使用以下阶段配置进行构建,该构建将发布部署文件到 Azure DevOps 的工件位置:

stages:
  - stage : Build 
    displayName : Build 
    jobs:
    - job:
      pool:
        vmImage: 'ubuntu-latest' 
      continueOnError: false 
      steps:
      - task: Docker@2 
      inputs:
        containerRegistry: '[Container Registry service connection]' 
        repository: 'azuredevops'
        command: 'buildAndPush' 
        Dockerfile: '**/Dockerfile'
        buildContext: '$(System.DefaultWorkingDirectory)/[folder path for docker]'
    - task: CopyFiles@2 
      inputs:
        SourceFolder: '$(system.defaultworkingdirectory)/[path to the deployment manifest files]'
        Contents: '*'
        TargetFolder: '$(build.artifactstagingdirectory)' flattenFolders: true
    - task: PublishBuildArtifacts@1 
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)' 
        ArtifactName: 'drop'
        publishLocation: 'Container'

在构建阶段旁边,添加以下发布阶段。在管道首次执行后,Azure DevOps 中将会有一个新的环境。在发布创建的环境中,连接 Kubernetes 集群以查看运行中的 Pods 信息:

- stage : Release 
  displayName : Release 
  jobs:
  - deployment: KubernetesDeploy 
    displayName: Deploy Kubernetes 
    pool:
      vmImage: 'ubuntu-latest' 
    environment: 'Kubernetes' 
    strategy:
      runOnce: 
        deploy:
          steps:
          - task: DownloadPipelineArtifact@2 
            displayName: 'Download pipeline artifacts' 
            inputs:
              buildType: 'current'
              targetPath: '$(Pipeline.Workspace)'
          - task: KubernetesManifest@0 
            inputs:
              action: 'deploy'
              kubernetesServiceConnection: '[Kubernetes service connection]'
              manifests: '$(Pipeline.Workspace)[deployment manifest]' 
              containers: '[container registry]:$(Build.BuildID)

在示例中,为多阶段管道指定了两个阶段。第一个阶段将通过 Docker 任务构建容器镜像,并将其发布到容器注册表。在发布镜像后,它还会发布多个构建工件——在此例中为 Kubernetes 清单。

第二个阶段将部署到名为 Kubernetes 的特定环境。如果该环境尚未添加,它也会在 Azure DevOps 中创建。在过程的其余部分,它会检索构建阶段发布的工件,并使用 Kubernetes 清单任务部署 Kubernetes 资源。

总结

在本章中,你了解了容器是什么以及它们如何与 DevOps 相关。DevOps 更多的是一种文化,而容器则是支持它的技术方式。你还学习了如何通过 Dockerfile 创建容器镜像,特别是通过使用多阶段构建文件。最后,我们深入探讨了 Kubernetes,学习了如何使用kubectl命令托管容器并管理正在运行的容器。

使用本章中获得的知识,你现在可以将应用程序部署到 Kubernetes,并确保其能够根据收到的请求数量进行扩展。

在下一章中,你将学习如何通过使用 Azure DevOps 来促进 DevOps 流程。你将了解哪些方法适合你的组织和团队,哪些方法不适合,并学习如何使用 Azure DevOps 实现这些结构和方法。

问题

在总结部分,这里列出了几个问题,帮助你测试自己对本章内容的掌握情况。你可以在附录章节的评估部分找到答案:

  1. 容器对 DevOps 有哪些好处?

  2. 一个特定的容器可以托管在不同的平台上(Azure/Amazon Web ServicesAWS)/Google Cloud PlatformGCP))——对还是错?

  3. 是否可以为现有应用程序添加容器支持?

  4. Dockerfile 中的 RUN 命令是用来做什么的?

  5. Kubernetes 可以在不同组件上进行扩展。它们是什么?

练习

  • 让我们创建并将我们的应用程序镜像发布到 Azure 容器注册表,并在 Azure Kubernetes 集群上进行部署。

  • 本实验需要配置以下 Azure 资源:

    • ACR

    • AKS

  • 设置环境 – 创建 AKS 和 ACR:

    az aks create  --resource-group az400-dev --name  packtsbookaci --generate-ssh-keys --location eastus 
    az acr create --resource-group  az400-dev  --name packtbookacr --sku Standard --location eastus 
    
  • 配置 ACR 与现有 AKS 集群的集成:

    az aks update -n 'packtsbookaci' -g 'az400-dev' --attach-acr 'packtbookacr'
    
  • 请参考仓库中的 azurecontainercluster-pipelines.yml 文件,或者创建一个包含以下内容的新 YAML 文件:

    trigger:
    - main
    pool:
      vmImage: ubuntu-latest
    variables:
      buildConfiguration: 'Release'
    steps:
    - script: echo Hello, world!
      displayName: 'Run a one-line script'
    # Authenticate nuget.exe, dotnet, and MSBuild with Azure Artifacts and optionally other repositories
    - task: NuGetAuthenticate@1
      #inputs:
        #nuGetServiceConnections: MyOtherOrganizationFeed, MyExternalPackageRepository # Optional
        #forceReinstallCredentialProvider: false # Optional
    
    - task: DotNetCoreCLI@2 
      displayName: Restore
      inputs:
        command: restore
        projects: '**/*.csproj'
        feedsToUse: config
        nugetConfigPath: $(Build.SourcesDirectory)/nugget.config
    - task: DotNetCoreCLI@2 
      displayName: Build
      inputs:
        command: build
        projects: '**/*.csproj'
        arguments: '--configuration $(buildConfiguration)' # Update this to match your need
    - task: Docker@2
      displayName: Build an image to container registry
      inputs:
        command: build
        repository: 'SampleStarter'
        dockerfile: '**/Dockerfile'
        containerRegistry: 'packtbookacr'
        tags: $(Build.BuildId)
        arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: push
        repository: 'SampleStarter'
        dockerfile: '**/Dockerfile'
        containerRegistry: 'packtbookacr'
        tags: $(Build.BuildId)
    
  • 请注意,containerRegistry 名称是 packtbookacr,与创建 AKS 和 ACR 时使用的名称相同。containerRegistry 名称 packtbookacr 必须是全球唯一的,因此你不能使用相同的名称。

  • 使用以下内容更新 dockerfile

重要提示

在以下示例中,端点被 *** 遮蔽。请使用适当且有效的端点来处理你的 NuGet feed。

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
COPY ["packtbookslibrary-api.csproj", "."]
COPY ./nuget.config .
ARG FEED_ACCESSTOKEN
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/*****/PacktBookLibrary/_packaging/PacktBooksLibraryFeed/nuget/v3/index.json\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
RUN dotnet restore "./packtbookslibrary-api.csproj" --interactive
COPY . .
WORKDIR "/src/."
RUN dotnet build "packtbookslibrary-api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "packtbookslibrary-api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "packtbookslibrary-api.dll"]
  • 我们在这里使用 Azure Artifact Credential Provider 来自动获取还原 NuGet 包所需的凭据。

  • 在通过 Azure DevOps 构建管道成功执行 azurecontainercluster-pipelines.yml 文件后,你会注意到 ACR 中创建了带有标签的镜像:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_17.jpg

图 16.17 – 一个 ACR 列表

  • 你可能需要建立并授权一个 Azure DevOps 服务连接与 ACR,如前面段落所创建的,以成功执行构建管道:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_16_18.jpg

图 16.18 – 建立 ACR 服务连接

进一步阅读

第十七章:规划您的 Azure DevOps 组织

在前几章中,您学习了许多与 DevOps 相关的技术和实践。本章中,我们将退后一步,看看如何构建一个强大的 DevOps 组织,并在构建时需要考虑的事项。之后,您将了解这对于安全性和可追溯性所能带来的影响。从那里开始,您将学习如何整合您的工具链组合,从而将开发生命周期的标准化主要集中在使用 Azure DevOps 上。

我们将从创建一个 Azure DevOps 组织开始,您将在其中学习如何在工具中布局您的产品和团队,并了解许可和不同方法的安全影响。之后,您将学习可追溯性及其如何用于创建可验证的软件开发过程。接下来是工具的整合。在您推进 DevOps 之旅的过程中,您可能会发现每个团队都在使用不同的工具,他们对这些工具很熟悉且喜欢使用。尽管 DevOps 的核心是赋能团队,但某种程度的标准化是可能需要的,您将学习如何进行这一操作。最后,您将学到,您可能必须接受一个事实,那就是您永远无法完全完成 DevOps 的采纳。

本章将涵盖以下主题:

  • 设置 Azure DevOps 组织

  • 确保可追溯性

  • 工具整合

  • 接受没有最终状态的事实

技术要求

要跟随本章的实践部分,您需要以下其中之一:

  • 一个 Microsoft Live 帐户,也叫个人帐户

  • 一个工作或学校帐户

设置 Azure DevOps 组织

要练习前几章中描述的一个或多个技术和方法,可能已经专门为此用途创建了一个 Azure DevOps 组织,或者可能已有一个可用于此目的的组织。然而,从零开始为公司创建一个组织需要更多的考虑。花时间合理规划组织的布局,能为以后节省大量时间。

本节描述了 Azure DevOps 的组成部分,如何使用这些组件来组织合适的安全模型,以及许可选项和成本。

Azure DevOps 是如何组织的

Azure DevOps 中的顶级构造被称为组织。对于大多数公司来说,一个组织就足够了,但也可以创建多个组织。

每个 Azure DevOps 组织都托管在特定的区域内。大部分组织的数据(源代码和工作项)都保证位于该组织所在的区域,但由于服务的全球覆盖,一些信息总是存储在其他数据中心。拥有跨不同地理位置的团队和产品的分布式组织可能是使用多个组织的原因之一。例如,如果某些团队位于澳大利亚,而另一些团队位于西欧,创建两个独立的组织并将所有团队托管在离他们最近的地理区域是有意义的。这样可以确保大多数 Azure DevOps 服务托管在一个物理上更接近团队的区域的数据中心,从而大大减少在使用 Azure DevOps 时的延迟。

一个组织可以与Azure Active DirectoryAAD)进行链接。如果启用此链接,只有位于该特定 AAD 中的用户(包括成员和访客账户)才能访问该组织。使用公司 AAD 不是强制性的;也可以使用 Microsoft 账户创建组织。管理员还可以允许拥有 GitHub 账户的用户访问该组织。然而,必须注意的是,当使用工作账户创建组织时,它将自动链接到与 AAD 账户关联的主(默认)租户。租户管理员可以防止其工作账户被链接到新的组织。

在每个组织中,可以创建一个或多个项目。一个项目是一个孤立的工作项容器,包含源代码控制库、管道定义以及所有其他 Azure DevOps 工件。项目之间的共享和链接可能性是有限的。在本文撰写时,仅有工作项、管道和代理池可以跨项目关联。通过这种方式,项目可以作为强隔离边界,用于在需要时强制实施产品或团队之间的严格安全性。通常建议尽量减少项目数量,当团队数量非常少(<10)时,最好只有一个项目。

下图展示了一个可能的 Azure DevOps 组织和项目的结构。图中显示有两个组织连接到 AAD。一个位于西欧,另一个位于澳大利亚。在西欧的组织中有两个项目,而在澳大利亚只有一个:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_01.jpg

图 17.1 – Azure DevOps 组织与项目

如前所述,推荐的做法是尽量减少组织和项目的数量。但在此示例中,从澳大利亚到西欧的延迟是一个合理的理由,可以将组织拆分为两个,以便将 Azure DevOps 托管在接近团队的地方。西欧的两个项目拆分可能是由于团队 4 在开发产品 3 时需要较高的隔离级别。

将团队 1 到 3 和产品 1 和 2 合并为一个项目是有意为之。这样做的原因是在单个项目中,可以定义多个产品区域和多个团队。将这些全部放在一个项目中,可以方便地将工作项链接到项目组合管理中。这样,一个团队的工作项也可以与另一个团队在其他产品上的提交或拉取请求相关联。如果功能分布在多个产品或应用(组件)中,这样做会很有帮助。

Azure DevOps 提供区域路径、团队和迭代,帮助你组织和执行产品待办事项的生命周期流程。因此,你必须谨慎选择粒度层级,以在开发生命周期中实现更高程度的并行性。以下是几个简单的规则:

  • 避免将用户链接到多个团队。相反,应将团队创建为一个逻辑上的、独立的单元。

  • 为组织中的每个主要产品(或团队)创建一个区域路径。根据需要创建子区域路径。

  • 仅在需要对 DevOps 生命周期的各个方面进行精细控制时,才创建独立的团队项目。

要在单个项目中定义所有产品和所有团队,了解 Azure DevOps 安全模型以及如何使用该模型实施访问控制非常重要。

创建 Azure DevOps 组织和项目

创建新的 Azure DevOps 组织和一个或多个项目通常由管理员完成,管理员也将负责后续的环境管理。这些组织很可能与Azure Active Directory (AAD) 关联。为了创建用于私人用途或培训和学习的组织,最好使用个人账户。

使用个人账户创建新组织,请执行以下操作:

  1. 访问 dev.azure.com

  2. 选择开始免费以开始创建新的 Azure DevOps 组织。

  3. 在弹出登录对话框时,使用个人账户登录。

  4. 登录后,选择正确的居住国家,并使用以下对话框选择是否启用提示和其他服务更新:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_02.jpg

图 17.2 – 为你的 DevOps 组织选择国家/地区

  1. 继续按钮创建新组织。

组织创建完成后,系统将自动启动新向导以创建第一个项目。要创建项目,请执行以下操作:

  1. 提供项目名称。

  2. 选择将项目设为公开还是私有。私有项目是默认设置,旨在组织内创建软件,并且不允许匿名访问。公开项目则用于开源开发。

一旦创建了新的组织和项目,就可以通过管理界面对这些选择进行更改。

重要提示

请记住,重命名组织或项目会更改 URL,因此所有现有的集成和链接可能会失效。

甚至可以在稍后更改组织的位置。这需要提出请求,并且不像更改其他设置那样简单。

一旦组织和项目可用,就可以开始设置安全性。

Azure DevOps 安全模型

在 Azure DevOps 中,授权可以分配给单个用户或安全组。安全组可以是现有 AAD 组的逻辑封装,也可以在 Azure DevOps 中自行定义。一般建议尽可能将授权分配给组,并限制单个用户的分配。

配置用户或安全组的授权时,有两种互补的方式可供选择:

  • 组织级和项目级授权

  • 对象级授权

在使用本地产品 Azure DevOps Server 时,还有可用的服务器级安全组和设置:

重要提示

在 Azure DevOps Services 中,组织称为项目集合,项目称为团队项目。有时,这些名称也用于 Azure DevOps。

  • Project Collection Build Administrators,或 [ProjectName]\Build Administrators,默认情况下具有查看、管理和编辑构建定义及构建资源的权限。

在组织和项目级别可以设置的权限会自动应用于组织或项目中的所有单个资源。

  • 对象级授权:在 Azure DevOps 中,大多数对象都可以为用户或组分配个别权限。这些权限通过对象本身上的访问控制列表ACL)进行设置。以下示例展示了一个经典的构建定义:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_03.jpg

图 17.3 – 为项目设置权限

对于每个组、每个操作,可以配置允许拒绝未设置允许继承)权限。当操作配置为拒绝时,即使用户属于具有允许授权的组,也永远不会允许访问。换句话说,当存在两个冲突的分配(允许拒绝)时,拒绝将优先于允许未设置应解释为隐式拒绝,不具有优先权。换句话说,当存在两个冲突的分配(未设置允许)时,用户将被允许访问。

Azure DevOps 中的一些工件属于层级结构的一部分。例如,管道可以位于文件夹中。每当启用继承时,来自层级中更高(父级)级别的权限将传播到该工件。这意味着,当用户访问一个管道文件夹时,如果没有更具体的授权设置,那么他们的所有权限将传播到所有下层文件夹和管道。

虽然安全模型决定了用户拥有的授权类型,但用户的操作也受到其分配的访问级别的限制,这一点来自于他们的许可证。

Azure DevOps 许可证

创建 Azure DevOps 组织的另一个方面是管理许可证。在 Azure DevOps 中,每个用户在登录产品之前都需要分配一个访问级别。定义了三种访问级别:

  • 利益相关者:利益相关者是免费的用户,他们可以登录产品,但只能访问其功能的部分内容。利益相关者可以管理工作项、管理管道并查看仪表板。他们无法访问产品的其他区域,因此该许可证级别仅适用于非开发角色。

  • 基本:基本用户拥有付费许可证,允许他们访问产品的所有部分,除了测试管理和高级测试执行功能。

  • 基本和测试计划:使用“基本和测试计划”许可证选项的用户可以访问 Azure DevOps 的所有部分。他们与基本用户拥有相同的访问权限,但还可以访问测试管理工具,以及用户验收测试、测试执行和测试结果报告功能。

每个组织的前五个基本许可证是免费的。这意味着可以在没有产生任何费用的情况下,尝试使用产品并学习如何使用它。此外,Visual Studio 订阅者也可以获得免费的许可证。专业订阅者可以获得一个免费的基本许可证,而企业订阅者则可以获得免费的基本许可证和测试计划许可证。

许可证可以在任何时候分配和重新分配,因此对于拥有大量人员进出(如加入和离开的公司或团队),不需要购买超过当前活跃人员数量的许可证。

许可证费用并不是使用 Azure DevOps 唯一的费用;了解按需付费的费用也同样重要。

如需更多信息,请参阅此链接:docs.microsoft.com/en-us/azure/devops/organizations/security/access-levels

基于消费的费用

许可证为用户提供了对产品的访问权限,之后他们可以按固定费用使用产品中的所有服务,但以下两项除外:

  • Azure Pipelines 并行执行

默认情况下,每个 Azure DevOps 组织都会提供一个由 Microsoft 托管的并行执行作业,且每月的执行时间是有限的。这意味着虽然可以根据需要定义多个流水线,但每次只能有一个流水线在执行。当然,这个数量可以增加,但这需要额外购买更多由 Microsoft 托管的并行执行作业。

作为替代方案,还可以购买自托管作业。对于这些作业,执行代理并不是由 Microsoft 提供,而是需要由组织自行提供,并需额外付费。这为完全控制硬件提供了机会(和责任)。

  • Azure Artifacts 存储

在使用 Azure Artifacts 源时,前 2 GB 的存储是免费的。任何额外使用的存储将根据价格表另行收费。

随着团队中越来越多的用户获得 Azure DevOps 许可证并在其中完成工作,可以利用这一点来提高软件开发的可追溯性。

请参考此链接以了解更多有关 Azure DevOps 计费的信息:docs.microsoft.com/en-us/azure/devops/organizations/billing/overview

确保可追溯性

Azure DevOps 相较于本书中提到的其他工具的优势之一在于,它是一个完全集成的工具套件,每个工具都支持特定的 DevOps 流程。这种端到端的集成允许从看板上的工作到相关的二进制文件部署到环境中的整个过程都能进行详细且长时间的追溯。

当与一组只支持部分 DevOps 流程的其他工具一起使用时,通常是可以将它们集成在一起的,当然,这样会产生一定的可追溯性。例如,在使用 Jira 和 GitHub 时,可以将 GitHub 中的提交、拉取请求和其他更改与 Jira 中描述的工作关联起来。当通过 Jenkins 获取合并的更改以构建和部署产品时,Jenkins 也会有从 Jenkins 返回到 GitHub 的可追溯性。然而,无法直接查看哪个工作项与哪个 Jenkins 部署一起完成。

其缺点是,使用 Jira 工具的产品负责人无法看到一个完成的用户故事是否已经关联到某个发布版本。他们必须访问多个工具才能找到这个问题的答案;在 GitHub 中,他们需要找到与该故事相关的所有提交,然后查看这些提交是否已经通过 Jenkins 发布。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_04.jpg

图 17.4 – 工具之间的可追溯性选项

在使用 Azure Boards、Repos 和 Pipelines 时,这是不同的。当使用所有 Azure DevOps 服务时,追踪性可以从故事到部署,反之亦然。以下是一个示例,突出显示如何查看哪些提交首次部署到具有特定部署的环境中:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_05.jpg

图 17.5 – 查看作为管道运行一部分的提交

拥有这种端到端的追踪性可以迅速回答多个问题,包括以下几个:

  • 这项工作是否已经开始?(分支和拉取请求可以与工作项相关联。)

  • 这项工作已经包含在我们的夜间构建中吗?(提交和构建管道可以与工作项相关联。)

  • 这个 bug 是否已经修复,并且解决方案是否已经在第二环中向我们的客户提供?(发布和环境显示了哪些新的提交和工作项是最新部署的一部分。)

重要提示

在谈到追踪性时,一个特别重要的观点是,它不是关于责备的。追踪性不是用来查找谁犯了哪个错误,而是用来找出当前事物的状态以及对象之间的关系。一旦追踪性成为责备的依据,工程师们很快就会找到隐藏自己工作的方式。这将导致更多错误和更少的可见性,问题只会变得更糟。

在追踪性优势明确的情况下,让我们探讨整合工具如何帮助我们获得这些好处。

工具整合

市场中可以观察到的一个趋势是,追踪性和 DevOps 产品扩展其服务内容,不仅仅包括源代码控制、管道或部署。比如 GitHub 和 GitLab,它们正在添加新的服务。越来越多的集成应用生命周期管理ALM)或 DevOps 套件正在涌现,但 Azure DevOps 已经提供这些服务多年了。

然而,许多公司并没有实施这些集成套件。团队在不同的生态系统中运作,导致不同的工具选择。或者也许团队只是有不同的偏好,或在不同的时间点开始采用 DevOps 实践,且有其他工具可供选择。不论原因如何,许多公司在处理同一工作时有多个工具在运行。

不幸的是,使用断开连接的工具或多个工具处理相同事情会带来一些缺点:

  • 如果团队使用不同的工具,协作将受到阻碍。不论开发人员的个人偏好如何,当组织的一半使用 Jenkins 而另一半使用 Azure Pipelines 时,这会证明是生产力的障碍。更进一步说,当切换团队或帮助他人时,如果他们使用的是另一种工具,效率将受到严重影响。

  • 工具越多,成本也就越高。即使所有工具都是开源且免费的,仍然会有成本。这些成本可能包括例如支持合同或请求、培训,或者解决特定问题所需的时间。升级和维护也是如此。工具越多,整体成本就越高。

  • 多个分布式工具意味着需要进行更多的安全和监控工作,这可能会导致许多问题和漏洞。

为了克服这些挑战,许多大公司决定标准化所使用的工具,无论是完全标准化,还是至少在某些程度上进行标准化。作为替代或中间解决方案,也可以通过工具之间的集成来启动整合。

工具标准化

为了应对这些缺点,大多数公司接受了两种策略之一:

  • 集中决策,选择一个工具(对于每个 DevOps 领域)作为整个公司的标准工具

  • 集中采用有限的工具集,团队可以从中选择要采用的工具

完全集中化中,由一个中央团队或部门代表所有人决定,在组织内使用哪些 DevOps 工具。一旦做出并实施此决策,就能减少成本,并使工程师能够更轻松地协助其他团队。

当然,缺点是,单一工具不一定是最适合所有人的选择,而对整个组织而言,所选择的工具可能是最优的——这种标准化可能在一些边缘情况下造成损害。

有限集中化是一些公司为避免这种情况所采用的方法。与只选择一个工具不同,这些公司选择了一组工具作为公司的标准。现在,各团队可以根据自己的具体需求,在两三个工具中做出选择。这种方式在不牺牲拥有非常具体需求的团队生产力的情况下,限制了完全去中心化的许多缺点。

采用这两种策略之一可能意味着一些现有的工具会被弃用或完全淘汰。这可能是一个缓慢而痛苦的过程,尤其是在大型组织中,往往存在相互冲突的利益。有许多方法可以实现这一目标,但也有一些策略可以让这种迁移变得不那么痛苦。

迁移策略

减少使用的 DevOps 工具数量通常意味着必须淘汰一个或多个工具。这可能会很困难,因为这些工具通常用于实现治理和合规性,以符合法律和法规的要求。实际上,这意味着可以采取以下两种做法之一:

  • 旧工具并非完全淘汰,而是仅不再使用,以保持变更历史。

  • 在旧工具被淘汰之前,历史数据也必须迁移到新工具中。

选择迁移时,有四种方法可以实现:

  • 从 Azure DevOps Server 迁移到 Azure DevOps Services

  • 大爆炸式迁移

  • 同步

  • 重建

提示

Azure DevOps Server 以前被称为团队基础服务器TFS)。较旧版本的 TFS 需要升级到最新版本的 Azure DevOps Server,才能导入到 Azure DevOps Services 中。导入服务始终支持 Azure DevOps Server 的最新两个版本。

以下章节将详细介绍这四个步骤。

从 Azure DevOps Server 到 Azure DevOps Services 的迁移

对于希望从 Azure DevOps Server 切换到 Azure DevOps Services 的组织,提供了高保真度的迁移服务。当前存在于本地 Azure DevOps Server 环境中的每个项目集合都可以使用 Azure DevOps Server 导入服务迁移到 Azure DevOps 组织。所有当前存在于本地项目集合中的资产都将被迁移到 Azure DevOps:工作项、源代码控制库以及构建和发布定义。

项目集合的迁移包括以下高级步骤:

  1. 验证项目集合是否准备好进行迁移:此步骤不会做任何更改,只是检查迁移的所有前提条件是否已满足。

  2. 准备迁移:在此步骤中,生成一个描述如何执行迁移的 JSON 文件。如果需要,还可以提供第二个文件,将本地身份与 AAD 身份关联,以确保迁移后所有历史记录仍然正确地与进行更改的人员关联。

  3. 会进行一次迁移的演练,以验证导入过程是否能够产生预期的结果。

  4. 实际迁移:在此步骤中,项目集合将下线,从项目集合数据库中生成数据层应用程序包DACPAC),然后上传第 2 步的 DACPAC 文件和其他文件,并启动迁移。

  5. 导入完成后,需要验证所有资产,并且在某些特定场景下,必须采取一些导入后的操作。

使用迁移服务时,提供了包含清单和逐步说明的全面指南,具体链接在本章末尾。

大爆炸迁移

第二种可能的策略是“大爆炸”迁移。在某个时刻,旧工具被关闭,所有数据迁移到新工具,并启用新工具。这种方式存在较高的问题风险,通常也没有回头路。通常来说,这并不是一个好的迁移策略。

然而,在某些情况下,这种方法可能有意义,比如源代码控制的迁移。现在有一些工具可以将不同来源的代码迁移到任何类型的托管 Git 解决方案,包括 Azure DevOps。源代码控制的优势在于,变更历史深深嵌入到系统中,因此带着历史进行迁移往往比其他类型的数据更容易。

同步

另一种迁移策略是允许一段时间内同时使用两种工具。

其中一种方法是使用一种工具来同步旧工具和新工具之间的数据。这可以是单向同步,从旧工具到新工具,或者双向同步。这样,就创造了一个过渡的情况,在这个过程中,两个工具可以同时使用。每个团队可以选择在一定的时间窗口内进行迁移。这避免了强制迁移的窗口。团队也可以选择在一段时间内并行使用这两个工具。这样,他们可以学习新工具,同时如果遇到压力,仍然可以切换回他们熟悉的工具。经过一段过渡期后,旧工具可以设置为只读,或完全淘汰。这种方法通常对于工作跟踪系统效果较好。在这些系统之间,概念通常非常相似(史诗、特性、故事和冲刺),这使得同步成为一种可行的方案。

重建

一个略微不同的方法是要求团队在新工具中重新构建。这种方法也创造了一个并行的情况,但没有自动迁移或同步。团队将不得不在新工具中重新做他们的流程或工作方式。由于这可能需要一些时间,旧工具将继续存在,直到团队完成这项工作。一个常见的适用场景是构建和/或发布流水线。

无论选择哪种策略,在所有情况下,确保新工具或工具集对团队来说优于现有工具都是很重要的。这应该提升性能、可追溯性、易用性或与其他公司工具的集成。任何迁移过程中的积极氛围都能显著改善结果。

作为迁移到单一工具的替代方案,工具之间的集成可以用来将现有工具结合在一起。

集成工具

作为替代不再优选工具的方案,也可以将它们与首选工具集成。特别是当决定迁移到 Azure DevOps 时,这可以成为一种强大的策略。在前面的许多章节中,对于每个主题,都列出了与 Azure DevOps 集成的不同工具。

在追求端到端可追溯性的过程中,这些集成可以作为使工具更加紧密结合的一种手段。考虑以下示例。

一个组织正在使用 Azure DevOps 来管理工作项、托管 Git 仓库和执行构建流水线。由于历史原因,部署工作是通过 Octopus Deploy 完成的。由于完全迁移成本过高,作为替代方案,选择了集成策略。通过 Azure DevOps 自动触发 Octopus Deploy 而非手动触发,达成了多个目标:

  • 实现端到端自动化。

  • 现在,发布管理也可以在 Azure DevOps 中完成,即便在 Azure DevOps 中的每次部署仅仅是触发 Octopus Deploy。

  • 现在在 Azure DevOps 中进行发布管理,可以实现端到端的可追溯性。

在整合工具和所有与 DevOps 相关的事情时,必须准备好接受一个事实,那就是你永远不会完成。

接受没有终点状态

合理预期,在任何时候,团队都会有一个或多个改进点,想要对他们的应用程序、工具链或工作方式进行改进。为了应对这一点,建议不要一直不断地改变一切。

相反,尝试分批或通过一系列明确定义的步骤来实施变更。同时,需要注意的是,事情是有自然顺序的。如果没有先建立合适的持续集成CI)流程,是不可能实践持续部署CD)的。另外,当应用代码的 CD 流程已经就绪时,采用基础设施即代码IaC)将带来最大的价值。接下来,自动化治理和安全措施在基础设施和配置代码已成为常规实践的情况下效果最佳。一旦所有这些实践都已实施,新的事物将出现在雷达上——未来可能需要的改进。

除了这一系列的改进外,还需要意识到,并不是每个团队都在这条旅程中的同一位置,并不是每个团队都能以相同的速度前进,而且开发并非总是线性的。

但这并不意味着无法跟踪和规划未来的变化,并将一个团队的经验教训应用到其他团队中。跟踪这一过程的一种过于简化的方式可以是使用表格,如下所示。

在这里,我们可以看到五个团队在采纳不同的 DevOps 实践或理念。所有团队都在实践 CI。一些团队在实践 CD,而团队 3 仍在进行进行中的工作WIP),第五个团队还没有开始。最后,团队 2 已经在试验 IaC。最终,由于没有终点状态,下一种实践或理念的出现只是时间问题,某个团队将开始进行实验:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_06.jpg

如果像前面所示的表格那样定期更新、评估并扩展,它有助于促进持续学习,并改进软件的创建和交付方式。学习和改进将成为标准,这将有助于提升向最终用户交付价值的效率。它还表明,采用 DevOps 永远不会“完成”。

它还提供了一个途径,可以看到哪些团队走在前列,哪些团队在跟随。通过给处于领先位置的团队更多的实验空间,并与其他团队分享知识,组织可以鼓励他们的领先团队进一步改进,同时也加速其他团队的进步。

关于持续学习、实验和自我提升的这一点,正是一个很好的时机来结束这本书。让我们在下一节中回顾这一章的内容。

总结

本章中,你学会了如何配置 Azure DevOps 组织以及如何为你的产品和团队创建布局。你了解了不同配置选项的影响以及如何应用这些配置。之后,你学会了如何利用 Azure DevOps 为你的开发过程增加可追溯性。你学会了如何在故事和任务中捕捉想法和任务,并且这些可以追溯到部署过程,反之亦然。接下来,你学习了如何在组织内整合使用的工具,并了解了何时不再尝试整合工具。最后,你了解到持续改进的重要性。

通过本章所学的内容,你现在可以为你的团队、多个团队或整个组织设置和配置 Azure DevOps。你可以创建一个适合你组织的结构,并开始使用它,支持一个或多个团队。同时,你还能够逐步标准化工作方式,并将团队统一在同一套工具上。

本书的最后一章已完成。你可以参考这本书来帮助你准备 AZ-400 考试,因为大多数话题都是类似的。不过,为了充分准备考试,我建议你从其他资源中阅读更多相关内容,并尽可能多地进行实践。在本章的结尾,有一份模拟考试,帮助你为最终考试做好准备。

祝你好运!

问题

在本章总结时,以下是一些问题,供你测试自己对本章内容的掌握情况。你可以在附录评估部分找到答案:

  1. 对或错:用户在 Azure DevOps 中存储的所有数据都保证包含在一个区域内。

  2. 按照以下顺序重新排列 Azure DevOps 的概念,使得每个元素都作为下一个概念的容器:

    • 工作项

    • 组织

    • 区域

    • 项目

  3. 对或错:通常的建议是为你的组织开发的每个应用创建一个新的项目。

  4. 哪两个元素限制了任何用户在 Azure DevOps 中可以执行的操作?

  5. 使用单一工具进行 ALM/DevOps 与使用一套工具套件相比,主要的好处是什么?

活动

假设你的组织正在计划开发下一代客户关系管理在线服务。工程团队按照部门进行组织,每个部门负责为某个特定领域构建产品或服务。以下图示总结了这一点:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/dsn-impl-ms-dop-solu-az400-exgd/img/B18655_17_07.jpg

图 17.6 – 组织结构

在每个部门内部,会有多个功能团队(例如,基础设施、网页、移动、核心 API 等)负责这些产品或服务的开发。

对于正在评估的场景,请确定使用项目、区域路径和团队设置 DevOps 组织的方法。需要考虑的一点是,每个部门希望完全拥有他们的 DevOps 组件和项目生命周期。

进一步阅读

第十八章:AZ-400 模拟考试

设计 DevOps 策略

  1. 你被要求将 Azure DevOps 引入你的组织。目前,组织中有许多其他工具在用于部署。你被问到哪些工具可以与 Azure DevOps 集成。[可以有多个答案。]

    1. Octopus Deploy

    2. Jira

    3. Jenkins

    4. 应用中心

  2. 你被要求为你的团队创建一个显示其工作信息的仪表板。你应该专注于显示鼓励敏捷和 DevOps 工作方式的度量和图表。你选择哪些度量标准?[选择三个。]

    1. 一个显示工作项平均周期时间的部件

    2. 一个显示最近部署结果(成功或失败)的部件

    3. 一个显示每天添加的代码行数的部件

    4. 一个显示团队当前打开的拉取请求数量的部件

  3. 你被要求在项目中实现静态代码分析。最合适的时间是什么时候?

    1. 在构建阶段,发布工件之前

    2. 在部署阶段,实际部署到目标环境之前

  4. 你正在为每个项目集合运行 import 服务。

  • DevOps 的核心原则之一是持续为最终用户交付价值。以下哪项不是为实现这一目标而使用的?

    1. 人员

    2. 实践

    3. 过程

    4. 产品* 你在一家大型企业工作,需要为新员工自动分配许可证。为此,你创建了一个与人力资源应用程序连接的小型应用程序。你在应用程序和 Azure DevOps 之间使用哪种授权方式?

    5. 用户账户

    6. 个人访问令牌

    7. OAuth 令牌

    8. 一次性秘密* 你需要将现有的 Git 仓库迁移到 Azure DevOps。你需要做什么?[选择两个。]

    9. 创建一个初始化的 Git 仓库。

    10. 创建一个未初始化的 Git 仓库。

    11. 执行 git remote rm origin; git remote add origin <new-repository-url>; git push

    12. 执行 git remote redirect origin <new-repository-url>; git push。* 你在一个异构环境中工作,不同团队使用不同的 DevOps 工具。你的一个构建在 Azure DevOps 中运行,但另一个团队希望从其他工具中获取你的管道工件。你可以使用以下哪些工具来暂存构建工件,以便从其他工具进行连接?

    13. 管道工件

    14. Artifactory

    15. Octopus Deploy 二进制服务器

    16. 工件源/通用包* 你被要求在 Azure DevOps 中为你的团队配置源控制。以下哪些要求只能通过使用团队基金版本控制TFVC)来实现?

    17. 你需要执行四眼原则。

    18. 你需要为特定用户配置对特定文件夹的访问权限。

    19. 你需要为特定用户配置对特定文件的访问权限。

    20. 你需要连接到经典构建管道。* 你需要执行并记录探索性测试会话。除了执行测试外,你还应该能够自动在 Azure Boards 的待办事项中报告缺陷。你计划使用 Test & Feedback 扩展来实现这一目标,并为所有测试人员分配测试许可证。这完成了目标吗?

    21. 是的

    22. 不是* 你需要执行并记录探索性测试会话。除了执行测试外,你还应该能够自动在 Azure Boards 的待办事项中报告缺陷。你计划使用 Test & Feedback 扩展来实现这一目标,并为所有测试人员分配基本许可证和测试许可证。这达成了目标吗?

    23. 是的

    24. 不是* 你需要执行并记录探索性测试会话。除了执行测试外,你还应该能够自动在 Azure Boards 的待办事项中报告缺陷。你计划使用 Test & Feedback 扩展来实现这一目标,并为所有测试人员分配基本许可证。这达成了目标吗?

    25. 是的

    26. 不是* 你负责识别可用于衡量采用 DevOps 影响的指标。以下哪些你建议使用?[选择两个]

    27. 同时进行的工作量

    28. 敏捷度

    29. 周期时间

    30. Sprint 持续时间* 以下哪项不是 DevOps 习惯?

    31. 团队自治与企业对齐

    32. 最大化未完成工作的量

    33. 假设驱动开发

    34. 实时站点文化* 你负责为你和你的团队正在创建的新应用程序制定测试策略。以下哪些建议你应该给出?

    35. 为了验证最关键的用户场景是否仍然正常工作,应该编写一个或多个系统测试。

    36. 为了验证最关键的用户场景是否仍然正常工作,在每次部署之前应该执行压力测试。

    37. 每十个单元测试中,应该至少有一个集成测试。

    38. 在生产环境启用新功能之前,应该在生产环境中执行最终烟雾测试。* 源代码是你公司最有价值的资产之一。当用户未通过公司网络连接时,你希望为 Azure DevOps 访问实施多因素身份验证。你可以使用以下哪项来做到这一点?

    39. Azure Active Directory 条件访问

    40. Azure Active Directory 网络许可

    41. Azure DevOps 网络控制

    42. Azure Active Directory 帐户组* 你正在一个为其他团队提供 Azure 订阅和资源组的团队中工作。作为你工作的一个部分,你希望监控所有团队是否实施了推荐的 Azure 安全最佳实践。你会使用以下哪项?

    43. Azure 策略

    44. Azure 安全中心(现为 Microsoft Defender for Cloud)

    45. Azure Key Vault

    46. Azure Security Monitor* 你负责提供从 Azure DevOps 内启动 SonarCloud 扫描的方式。以下哪些步骤能创建一个完整的解决方案?[选择两个]

    47. 更新 Azure DevOps 项目中的 SonarCloud 配置。

    48. 创建新的 SonarCloud 服务连接。

    49. 激活 SonarCloud 集成包。

    50. 安装 SonarCloud 扩展。* 你需要对 Kubernetes 中的部署进行更新—你应该使用哪个命令?

    51. kubectl apply

    52. kubectl deployments

    53. kubectl get services

    54. kubectl deploy 你在管理 Azure Kubernetes 集群时需要使用的基本工具是什么?[选择所有适用项]

    55. Azure CLI/PowerShell

    56. kubectl

    57. Azure DevOps

实施 DevOps 开发流程

  1. 你正在开发一个 Microsoft .NET Core 应用程序,并希望分析该应用程序,检查是否使用了任何具有已知安全漏洞的开源库。你可以使用以下哪些产品进行此类分析?[选择两个]

    1. Jenkins

    2. WhiteSource Bolt

    3. Snyk

    4. App Center

  2. 你当前使用 (i) JIRA, (ii) GitLab 和 (iii) Octopus Deploy 来处理部分 DevOps 流程。你想整合你的 DevOps 工具,并选择使用 Azure DevOps。你应该使用哪些 Azure DevOps 服务来替代这些工具?[匹配三个对]

    1. Azure Pipelines

    2. Azure Repos

    3. Azure Boards

    4. Azure Artifacts

  3. 你正在评估不同的构建代理选项。选择私有代理而非 Microsoft 托管代理的有效理由是什么?[选择两个]

    1. 你需要在任何作业执行之前,确保代理上已经有了自定义软件。

    2. 你需要确保在销毁之前,只有一个管道作业使用相同的环境进行执行。

    3. 你需要从构建代理直接连接到本地网络。

    4. 你需要确保始终使用最新的镜像。

  4. 你负责管理团队部署到 Azure App Service 的应用程序设置。以下哪些服务无法用于实现这一目标?

    1. Azure App Configuration

    2. ARM 模板

    3. Azure Policy

    4. Azure Key Vault

  5. 你负责为团队创建大量的构建管道。几乎所有管道都需要相同的结构。哪个 Azure DevOps Pipelines 构件可以帮助你?

    1. 分支策略

    2. 任务组或模板

    3. Azure Artifacts

    4. 部署组

  6. 你正在使用 Entity Framework 作为应用程序的数据库访问层。你负责管理数据库升级,并希望使用 Entity Framework 来管理数据库模式。你应该使用哪种类型的模式迁移?

    1. 基于迁移

    2. 基于最终状态

  7. 你需要将本地更改保存到 Git 仓库。你需要使用哪些命令?[选择两个]

    1. git clone 和 git push

    2. git commit 和 git push

    3. git add, git commit, 和 git push

    4. git add 和 git commit

  8. 你需要防止任何人在变更无法编译或单元测试失败时合并到主分支。以下哪些可以实现这一目标?

    1. 分支保护中心

    2. Azure Repos 分支策略

    3. Azure Repos 分支安全性

    4. 这在 Azure DevOps 中不可行;你需要使用其他产品,例如 GitHub。

  9. 你的公司使用 GitHub Enterprise 本地部署作为源代码托管服务。为了实现持续集成和持续部署,你打算使用 Azure DevOps。以下哪些组件组成了一个完整的解决方案,使这成为可能?[选择两项]

    1. 外部 Git 服务连接

    2. 打开防火墙,以允许 Azure Pipelines 从 GitHub Enterprise 进行 HTTPS 连接

    3. 一个用于 HTTP 的 Git 源代理

    4. 本地代理

  10. 一个新团队加入公司,他们必须开始开发一个新应用。他们请求你推荐一个分支策略,允许他们并行开发多个功能,并随时部署新版本,同时减少后期合并更改的需要。你推荐哪种方法?

    1. 为每个团队成员创建一个永久分支,并挑选提交进行合并。

    2. 为每个功能创建一个分支,并在完成后合并该分支。

    3. 为每个任务创建一个分支,并在完成后合并该分支。

    4. 在完成可以交付的工作时,尽可能频繁地创建并合并分支。

  11. 你被任务分配为在 Azure DevOps 中为你的团队配置源代码管理。你会选择哪种源代码控制系统,最好是?

    1. TFVC

    2. Git

  12. 以下哪项是正确的?

    1. 在 Azure DevOps 项目中,你可以有任意数量的 Git 仓库和 TFVC 仓库。

    2. 在 Azure DevOps 项目中,你最多可以有一个 Git 仓库和一个 TFVC 仓库。

    3. 在 Azure DevOps 项目中,你最多可以有一个 TFVC 仓库和任意数量的 Git 仓库。

    4. 在 Azure DevOps 项目中,你只能选择使用 Git 仓库或 TFVC 仓库,不能同时使用两者。

  13. 你的团队正在开发一个移动应用,并希望使用 App Center 将应用分发到应用商店和团队内部的测试人员。以下哪项是你应该使用的?[选择两项]

    1. 仅限邀请的预发布组

    2. 推送到商店的集成

    3. 存储连接

    4. 分发组

  14. 你正在为一个新项目创建一系列微服务。你希望找到一种方式从集中位置管理配置。许多配置设置在微服务之间共享。以下哪个解决方案最适合这个用例?

    1. Azure 密钥保管库

    2. Azure 应用配置

    3. Azure 配置中心

    4. ARM 模板

  15. 你必须确保在代码至少被两个人查看过之前,无法将其提交到仓库的主分支。以下哪项是一个完整的解决方案?[选择三项]

    1. 强制要求通过拉取请求来合并更改到主分支。

    2. 在向分支推送新提交时,重置拉取请求的批准投票。

    3. 最少有两个审核者,但允许每个人合并自己的更改。

    4. 至少需要一个审阅者,并且该审阅者不能是提交拉取请求的人。

  16. 你必须为团队生产的二进制文件(DLL)签名,以便其他团队可以验证这些二进制文件没有被修改,并且确实是来自你的团队。你必须安全地存储用于签名的证书。你可以在哪里做到这一点,并且仍然能够在管道中使用该文件?如果有多个答案适用,请选择最简单的解决方案。

    1. Azure Pipelines 库

    2. Azure Key Vault

    3. 在源代码控制中加密

    4. Azure DevOps 证书存储

  17. 你必须确保每个构建管道都包含一个由你的团队预共享的任务组。你可以使用以下哪个 Azure DevOps 构件来做到这一点?

    1. 管道装饰器。

    2. 管道验证器。

    3. 管道执行前任务。

    4. 这是不可能的——你必须实现手动审核过程。

  18. 你的源代码存储在 Subversion 源代码控制系统中。你希望迁移到 Azure DevOps Pipelines 进行持续集成,但又不希望迁移源代码并连接 Pipelines 到 Subversion。这样做可能吗?

    1. 是的

    2. 不是

  19. 开发团队正在创建一个容器化应用程序。该解决方案需要部署到 Azure 中的 Kubernetes 集群。你需要创建该集群并确保应用程序按预期运行。请选择你应执行的命令,并将其按执行顺序排列。

    1. kubectl apply

    2. az group create

    3. az aks create

    4. az appservice plan create

    5. kubectl get deployments

    6. az aks get-credentials

    7. kubectl get hpa

    8. kubectl get services

  20. 运行容器而非虚拟机的一个巨大优势是容器共享操作系统内核。这也使得容器镜像比虚拟机镜像更小。这是否正确?

    1. 是的

    2. 不是

实现持续集成

  1. 根据测试范围的大小对以下类型的测试进行排序,从最小范围的测试类型开始。

    1. 集成测试

    2. 单元测试

    3. 系统测试

  2. 以下哪些是正确的?[选择多个答案。]

    1. 压力测试通过对系统施加不断增长的负载,来识别系统的断点。

    2. 集成测试始终包括数据库。

    3. 性能测试用于测量系统执行给定任务的速度。

    4. 可用性测试用于识别系统响应过慢的使用场景。

  3. 你正在创建一个 Azure DevOps 仪表板,以便为团队提供关于编写代码质量的洞察。以下哪个小部件不属于该仪表板?

    1. 一个显示最近部署及其是否成功的小部件

    2. 一个显示每天提交次数的小部件

    3. 一个显示单元测试代码覆盖率随时间变化的小部件

    4. 一个显示最新构建是否失败的小部件

  4. 以下哪个不是有效的合并策略?

    1. 压缩提交

    2. 变基

    3. 交错

    4. 合并提交

  5. 以下哪项不是 OWASP Top 10 的一部分?

    1. 注入漏洞

    2. 敏感数据暴露

    3. 最小权限原则违规

    4. 使用已知漏洞的依赖项

  6. 你的团队正在创建容器镜像,这些镜像以后将部署到 Azure。以下哪些选项可以用来存储你的镜像?[选择两个]

    1. Azure 容器实例

    2. Azure 容器注册表

    3. Azure Kubernetes 服务

    4. Docker Hub

  7. 你希望在任何集成构建失败时收到通知,并在 Azure DevOps 项目中配置了电子邮件订阅。这样能达到目标吗?

  8. 你希望在 Azure Artifacts feed 中托管的工件有新版本时触发 YAML 管道。这可能吗?

  9. 你希望在多阶段 YAML 管道的同一阶段中使用托管代理、云中的私有代理和本地代理的组合。这可能吗?

  10. 你希望创建一个每天固定时间触发的发布管道,并排除周日。这可能吗?

  11. 开发团队正在创建一个容器托管应用,并希望在互联网上共享该镜像。团队通过 Docker 构建镜像,并尝试通过 Kubernetes 托管它。这是正确的做法吗?

  12. 以下哪些是可以存储容器镜像的位置?[选择所有适用的选项]

    1. Azure 容器实例

    2. Docker Hub

    3. Azure 容器注册表

    4. Azure 容器存储

实施持续交付

  1. 你所在的公司使用 ServiceNow 作为变更管理系统。规定应使用 ServiceNow 跟踪每次部署到生产环境的情况。你负责确保,如果变更管理系统中没有注册有效的变更,你的应用不会部署到生产环境。以下哪些操作可以实现这一目标?[选择两个]

    1. 你实施一个部署回调,以检查 ServiceNow 中的有效变更。

    2. 你将部署门作为生产阶段的前置条件进行部署。

    3. 你在 QA 阶段完成部署时,添加了一个部署门作为后置条件。

    4. 你创建一个环境,命名为 Production-ServiceNow check

  2. 你需要将一个应用部署到十二台本地虚拟机上,并将它们分为三个子网。为了完成这个任务,应该执行以下哪些操作?[选择三个]

    1. 创建一个新的部署组,并将正确的代理添加到该组。

    2. 在需要部署的所有虚拟机上下载并安装私有代理。

    3. 在发布管道中添加选择作业,以选择要使用的部署组。

    4. 在每个子网中精确地在一台虚拟机上下载并安装私有代理。

    5. 在发布管道中添加一个部署组作业,执行部署应用所需的任务。

    6. 在部署管道上配置用户名和密码,配置如何连接到代理。

  3. 你需要配置一个发布管道,以满足在可以开始部署到生产环境之前的几个条件。这些条件是:(i)审批委员会中至少四个成员中的两个应批准部署;(ii)发布后的第一小时内,应该检查 Azure Monitor 是否有任何警报。这可以使用 Azure DevOps Pipelines 完成吗?

    1. 是的

  4. 你正在使用 SQL Server 数据工具 (SSDT) 来描述数据库架构作为代码。你还希望使用 SSDT 进行架构升级。你应该使用哪种类型的架构迁移?

    1. 基于迁移

    2. 基于最终状态

  5. 你正在使用无模式数据库。这是否完全消除了架构管理的问题?

    1. 是的

  6. 你的团队必须遵守规定,要求每个新版本必须由测试经理手动批准,才能部署到生产环境。以下哪个更改最能有效满足这一要求?

    1. 你在生产阶段添加了一个部署前门控,验证在自建系统中的签署情况,该系统记录所有已签署的应用版本。

    2. 你在 QA 阶段添加了一个部署后门控,当所有自动化测试成功时,测试经理在指定系统中进行审批。

    3. 你在 QA 阶段添加了一个部署后审批,必须由测试经理批准。

    4. 你禁用了生产阶段的自动批准,并指示所有人只有在咨询包含所有测试经理签署的系统后才开始部署。

  7. 你正在为你的团队创建多个发布管道。许多管道将在某些任务中使用相同的配置值。以下哪项可以帮助你以完整的解决方案重复这些值?

    1. 变量组

    2. 任务组

    3. 变量容器

    4. Azure 密钥保管库

  8. 你希望从部署中自动生成发布说明。你希望做到这一点而不使用任何扩展或插件—只使用 Azure DevOps 的内建功能。这可能吗?

    1. 是的

  9. 你想从 Azure DevOps 部署应用到 Azure Service Fabric。你需要为此安装任务扩展吗?

    1. 是的

  10. 你需要在 Kubernetes 中应用更新。你应该使用哪个命令?

    1. kubectl apply

    2. kubectl deployments

    3. kubectl get services

    4. kubectl deploy

  11. 在 Azure DevOps 中用于将容器部署到 Azure Kubernetes 的任务是什么?

    1. Kubernetes 清单

    2. Kubernetes

    3. Kubernetes 常规任务

    4. Kubectl

  12. 什么类型的文件最适合部署资源到 Kubernetes 集群?

    1. ARM 模板

    2. Terraform 文档

    3. PowerShell 脚本

    4. YAML 部署文件

实现依赖管理

  1. 你正在使用 Azure Artifacts 托管团队创建的 NuGet 包。你有一个新需求,需要将你创建的一个(且仅一个)包提供给你组织中的所有其他团队。以下哪些是有效的解决方案?[选择多个。]

    1. 你创建了一个新的 feed,并允许 Azure Active Directory 中的任何用户使用该 feed 中的包。你将包移动到这个 feed 中进行共享。

    2. 你允许组织内的所有用户使用你现有的 feed。

    3. 你创建了一个新的 feed,并允许你组织中的任何用户使用该 feed 中的包。你将包移动到这个视图中进行共享。

    4. 你在现有的 feed 中创建了一个新的视图,并将要共享的包发布到该视图。接下来,你配置所有组织成员可以从该视图读取包。

    5. 你将现有的 feed 添加为上游源到其他团队使用的 feed,以便他们也能拉取你的包。

  2. 以下哪些理由支持将你的解决方案拆分为多个较小的解决方案,并使用共享包或库来从这些较小的解决方案组装完整的应用程序?[选择两个。]

    1. 你的一个解决方案中有超过 25 个 C# 项目。

    2. 你的代码库变得越来越大,以至于编译和/或运行单元测试开始变得非常耗时。

    3. 你的团队变得太大,已经分为两部分。将解决方案拆分也可以明确划分所有权:每个团队一个解决方案。

    4. 你的 Git 仓库中的文件数已接近 10,000 个限制。

  3. 对于以下哪些情况,Azure Artifacts 支持上游源?[选择两个。]

    1. Composer

    2. Python

    3. Gems

    4. Maven

  4. 你正在使用 Azure Artifacts 提供的依赖管理服务。你正在依赖一个通过 NuGet 公共可用的库。以下哪些方式可以用来通过现有的 feed 消耗这个包?

    1. 上游源

    2. 外部视图

    3. 上游视图

    4. 依赖视图

  5. 你有一个在两个应用程序中使用的库,但仅在你自己团队内使用。以下哪种策略是共享这个库的最佳方法?

    1. 将共享库链接为两个使用方解决方案中的共享项目。

    2. 将库放在一个单独的仓库中,使用构建管道构建库并将其作为 NuGet 包上传到 Azure Artifacts。在你的两个应用程序中从那里消费它。

  6. 你希望使用通用包从 Azure DevOps 向不同的部署协调器分发应用程序组件。这可能吗?

实现应用程序基础架构

  1. 你正在开发一个将部署在两个不同的 Azure 区域的应用程序,以支持故障转移场景。以下哪些组合构成一个有效的解决方案?[选择两个。]

    1. 你创建了一个包含两个参数文件的 ARM 模板。第一个参数文件对应第一个 Azure 区域,第二个参数文件对应第二个 Azure 区域。你使用 ARM 模板来更新基础设施。

    2. 你创建了一个 ARM 模板和参数文件,只更新一个区域的基础设施。另一个区域的基础设施手动更新,以防止配置漂移。

    3. 你先在两个区域更新基础设施。只有当基础设施成功更新后,才会将应用程序部署到两个区域。

    4. 你先在一个区域更新基础设施,然后部署应用程序。只有当这一步成功后,才会在另一个区域更新基础设施并将应用程序部署到该区域。

  2. 你需要通过 Azure DevOps 管道将一个 Azure 资源管理器模板部署到 Azure 资源组。你需要使用的一些参数存储在 Azure 密钥保管库中。以下哪个选项组合不是完整解决方案的必要部分?

    1. 创建一个新的变量组,并通过服务连接将其链接到正确的密钥保管库。

    2. 给 Azure Active Directory 服务主体在正确的 Azure 密钥保管库上分配 Reader RBAC 角色。

    3. 在你的 Azure DevOps 项目中配置一个新的 Azure 资源管理器服务连接,并以此方式创建一个新的 Azure Active Directory 服务主体。

    4. 给 Azure Active Directory 服务主体在正确的密钥保管库上分配以下访问策略:listget

  3. 你需要在 Azure 中创建和配置多个虚拟机。你应该使用哪些工具的组合?[选择两个。]

    1. Azure 自动化 DSC

    2. Azure 运行时运行簿

    3. ARM 模板

  4. 你正在配置将来应用程序将被部署到的 Azure 资源组。你已获得一个用于从 Azure DevOps Pipelines 进行部署的预创建服务主体。你应当为该服务主体分配什么 RBAC 角色,以便部署资源?

    1. 读取者

    2. 贡献者

    3. 部署者

    4. 拥有者

  5. 你需要为你的团队设置 RBAC 角色分配。你希望遵循最小权限原则,同时确保需要访问资源的团队成员能够访问资源。以下哪个解决方案最为合适?

    1. 你将用于部署的服务主体和所有团队成员添加到一个 Azure Active Directory 组中。你将此 Azure Active Directory 组分配为 Azure 资源组的贡献者角色。

    2. 你给用于部署的服务主体在资源组上分配贡献者权限,并给所有团队成员分配读取者角色。

    3. 你创建了两个新的 Azure Active Directory 组:reader 和 writer。你将用于部署的服务主体添加到 writer 组中,并将所有团队成员添加到 reader 组中。你将读取者角色分配给 reader 组,将贡献者角色分配给 writer 组。

    4. 您创建了一个新的 Azure Active Directory 组。您将用于部署的服务主体添加到该组中,并为该组分配贡献者角色。您为团队成员创建了一个升级流程,以便他们可以暂时被添加到此 Azure Active Directory 组中。

  6. 以下哪些工具不能用于管理 Azure 资源?

    1. Terraform

    2. Azure DevOps CLI

    3. Azure PowerShell

    4. CloudFormation

  7. 您正在实践基础设施即代码,并希望将 ARM 模板从 Azure DevOps 部署作为部署过程的一部分。以下哪种解决方案以最简单的方式完成此操作?

    1. 您从部署管道中的 Cmd 任务执行 Azure CLI 脚本。

    2. 您从部署管道执行 PowerShell 脚本。

    3. 您使用内置任务来部署 ARM 模板。

    4. 您将模板上传到 Azure 存储帐户,并使用 HTTP REST 调用启动 ARM 模板的部署。

  8. 您正在通过实践一切即代码来改变团队交付应用程序的方式。以下哪些不能使用 Azure 蓝图或 ARM 模板创建?

    1. Azure 订阅

    2. Azure Active Directory 安全组

    3. Azure RBAC 自定义角色

    4. Azure RBAC 角色分配

  9. 您正在为一个团队提供 Azure 订阅和资源组,作为工作的一部分,您希望限制团队可以创建的 Azure 资源类型。您使用以下哪种工具?

    1. Azure RBAC 角色和角色分配

    2. Azure 策略

    3. OWASP Zed 攻击代理

    4. Azure 安全中心(现在是 Microsoft Defender for Cloud)

  10. 使用基础设施和配置即代码工作有哪些不是好处?

    1. 最小化配置漂移

    2. 同行评审支持

    3. 降低配置更改的前置时间

    4. 配置更改的源代码控制历史

实现持续反馈

  1. 您需要收集您的团队创建的应用程序的崩溃报告。您可以使用哪些工具来完成此任务?[选择两个。]

    1. Snyk

    2. Raygun

    3. App Center

    4. Azure Automation

  2. 您正在配置许多警报。某些警报需要通过电子邮件发送警告,其他则是严重错误,需要通过短信发送。无论警报是警告还是错误,您还需要更新家庭构建系统,以便警报被触发。

您创建了以下解决方案:一个用于警告的操作组既发送电子邮件,也调用家庭构建系统的 WebHook。一个用于错误的操作组既发送短信,也调用家庭构建系统的 WebHook。对于警告类型的警报,您配置操作组一;对于错误类型的警报,您配置操作组二。

这是一个完整且正确的解决方案吗?

  1. 是的

  2. 您正在配置许多警报。某些警报需要通过电子邮件发送警告,而其他则是严重错误,需要通过短信发送。无论警报是警告还是错误,您还需要更新家庭构建系统,以便警报被触发。

您创建以下解决方案:一个动作组发送电子邮件、发送短信文本消息,并在主构建系统上调用 WebHook。您在所有警报上配置此警报组,并添加警报条件配置,以仅在警告时发送电子邮件,并仅在错误时发送短信文本消息。

这是一个完整且正确的解决方案吗?

  1. 您正在配置许多警报。某些警报需要通过电子邮件发出警告,而其他警报则是严重错误,需要发送短信文本消息。无论是警告还是警报,您还需要更新主构建系统以处理已触发的警报。

您创建以下解决方案:一个警告动作组发送电子邮件。第二个错误动作组发送短信文本消息。第三个动作组在主构建系统上调用 WebHook。对于警告警报,您配置动作组一和二。对于错误,您配置动作组二和三。

这是一个完整且正确的解决方案吗?

  1. 您希望邀请用户在您的产品上提供想法和建议。这应该在公共场所进行,以便其他用户可以评论和投票这些建议。以下哪些工具可以以最简单的方式实现这一点?[选择两个。]

    1. Azure Blob 存储静态站点

    2. GitHub 问题

    3. UserVoice

    4. Azure Boards 公共视图扩展

答案

  1. A, B, C, D

  2. A, B, D

  3. A

  4. D – A – C – B – E

  5. B

  6. B

  7. B, C

  8. D

  9. C

  10. D

  11. A

  12. A

  13. A, C

  14. B

  15. A, D

  16. A

  17. B

  18. B, D

  19. A

  20. A, B

  21. B, C

  22. A – (iii), B – (ii), C – (i)

  23. A, C

  24. C

  25. B

  26. A

  27. B, C

  28. B

  29. A, B

  30. D

  31. B

  32. C

  33. C, D

  34. B

  35. A, B, C

  36. A

  37. A

  38. A

  39. B, C, F, A

  40. A

  41. B, A, C

  42. A, C

  43. B

  44. C

  45. C

  46. B, D

  47. A

  48. A

  49. A

  50. A

  51. B

  52. C

  53. B, C

  54. A, B, E

  55. A

  56. B

  57. B

  58. C

  59. A

  60. B

  61. B

  62. A

  63. A

  64. D

  65. C, D

  66. B, C

  67. B, D

  68. A

  69. B

  70. A

  71. A, D

  72. B

  73. A, C

  74. B

  75. D

  76. D

  77. C

  78. B

  79. B

  80. C

  81. B, C

  82. A

  83. B

  84. A

  85. B, C

评估

第一章,DevOps 简介

  1. 正确。在传统组织中,开发通常负责对软件进行更改,而运维负责维护这些更改的目标系统的稳定性。由于更改本质上带有风险并可能扰乱稳定性,因此运维通常对更改持抵制态度。

  2. 错误。虽然理论上可以孤立地应用不同的 DevOps 实践,但真正的价值来自于将它们结合起来。例如,没有连续集成和测试自动化的持续部署不仅毫无意义,而且实际上在没有连续集成和测试自动化提供的质量保证的情况下进行持续部署是危险的。

  3. 错误答案是 D。DevOps 不是一个职称,而是一种文化运动。实际上,在开发和运维之间创建一个新的 DevOps 团队往往与 DevOps 的理念相悖。与其说有两个各自目标的团队或部门,不如说现在有三个。

  4. 快速通道是一种加快非计划、高优先级工作进度超过计划工作的方法,同时保持整个团队使用单一迭代看板。

  5. DevOps 有很多定义。常见的主要元素包括业务价值、最终用户、持续部署、自动化和协作。

第二章,站点可靠性工程基础

  1. 正确。SRE 团队的主要责任是维护应用程序的可靠性。企业或产品的声誉和成功取决于生产环境中云解决方案的可靠性。

  2. 错误。通常,可用性以“九”表示。例如,三个九(99.95%的可用性)在一年中的平均停机时间为 4 小时 22 分钟 58 秒。

  3. 正确。SRE 采用自动化来解决常见和重复出现的问题。由于自动化,常见问题的响应时间得以缩短。

  4. 95% 的可用性意味着允许的停机时间为:

    • 每周:8 小时 24 分钟 0 秒

    • 每月:1 天 12 小时 31 分钟 27 秒

    • 每年:18 天 6 小时 17 分钟 27 秒

  5. 正确答案是 A、B 和 C。DevOps 管理和缺陷跟踪不会影响或给维护可靠性带来挑战。

  6. 正确。服务可靠性的级别需要由关键利益相关者定义,SRE 团队将通过使用 SLOs 和 SLIs 来帮助维持这些服务可靠性水平。

  7. 劳动是与运行生产服务相关的一种工作,通常是手动的、重复性的、可自动化的、战术性的、缺乏持久价值的,并且随着服务的增长而线性扩展。

第三章,充分发挥 DevOps 工具的优势

  1. 错误。你可以使用 Microsoft 或 GitHub 账户免费注册 Azure DevOps。

  2. 正确。Azure Boards 允许多个团队在单一项目上协作工作。

  3. 正确。Application Insights 是 Azure Monitor 的一项功能,提供可扩展的应用性能管理APM)和实时 Web 应用的监控。

  4. 正确。你可以使用 Azure Pipelines 自动构建、测试、打包、发布和部署 GitHub 仓库代码。

  5. 错误。GitHub 是微软提供的企业级服务,支持公共和私有仓库。

第四章,一切从源代码管理开始

  1. 集中式和去中心化源代码管理的主要区别在于,去中心化源代码管理系统中,每个用户都有完整的源代码历史。而在集中式系统中,只有服务器拥有完整的历史。去中心化系统在断开服务器连接时表现最佳,而集中式系统通常允许更详细的访问控制。

  2. 正确。Git 是最知名的去中心化源代码管理系统。

  3. 正确答案是 B。Rebasing 不是一种分支策略,而是一种合并策略。

  4. 在使用 Git 时,拉取请求用于将一个分支的更改合并到另一个分支。拉取请求可以被审查、批准或拒绝。为了强制使用拉取请求,可以使用 Git 策略。

  5. 正确答案是 B。基于主干的开发不是合并策略,而是分支策略。

第五章,迁移到持续集成

  1. 错误。持续集成是指每天至少将每个开发人员的工作与同事的工作集成,并构建和测试集成后的源代码。仅仅运行每日构建并不构成持续集成。

  2. 正确。经典构建管道始终连接到源代码仓库。尽管构建管道中可能不会使用源代码,但连接始终存在。

  3. 错误。可以创建一个直接以阶段开始的 YAML 管道,源代码仓库的链接不再是必需的。

  4. 正确答案是 C:服务连接。服务连接是在包含需要调用外部工具的管道的组织或项目中配置的。配置好服务连接后,可以在一个或多个管道中使用它。

  5. 正确答案是 A 和 D:访问封闭网络的权限和安装额外软件的能力。自托管代理部署在你拥有的基础设施上。这意味着你可以将它们部署在你控制的网络上,从而使它们能够访问该网络。由于代理部署在你的基础设施上,你还可以决定安装哪些软件(以及哪些不安装)。任务和扩展任务会在代理执行作业之前自动下载到代理上。你可以拥有任意数量的并行管道,而无需使用自托管代理。然而,为此你需要从 Microsoft 购买额外的并行执行。

第六章,实现持续部署和发布管理

  1. 错误。也可以通过定时或手动触发新发布。

  2. 所有答案都是正确的。

  3. A 和 C 都是正确的。环形部署和金丝雀部署只将新版本的应用程序暴露给有限的用户群体。功能开关也用于渐进式曝光,但不是用于限制部署的风险,而是用于限制新特性发布的风险。

  4. 正确。部署组用于在发布管道中执行任务时,不仅仅在组中的一个代理上执行,而是在所有代理上执行。部署组旨在用于在运行代理的机器上部署软件。

  5. 一个可能的优势是,所有步骤的端到端可追溯性都保留在 Azure DevOps 中。如果你也在 Azure DevOps 中管理工作项和源代码,你将保持从工作项到发布的端到端可追溯性,而这一切都可以在实际部署中使用 App Center。

第七章,依赖管理

  1. 错误。一个包的版本可以在多个视图中可见。

  2. 错误。管道工件只能在 Azure DevOps 中的其他管道内消费。

  3. 正确。Azure Artifact feeds 可以用于将通用包共享给其他产品。这使你能够在 Azure DevOps 中编译应用程序,将二进制文件作为通用包上传,然后在另一个产品中再次下载它。这在使用其他部署工具(例如 Octopus Deploy)时非常有用。

  4. 正确。依赖关系管理的三个主要方面是标准化、包格式与来源,以及版本控制。

  5. 正确答案是 B 和 D。A 选项不正确,因为包引用(无论是在 .csproj 文件中还是在 nuget.config 文件中)应仅通过名称和版本引用包。C 选项不正确,因为 consumer 不是 Azure Artifact feeds 中有效的访问级别。正确的访问级别是 reader(或更高级别),因此 B 选项正确。D 选项也是正确的,你需要将包位置添加到 NuGet 配置中。

  6. 一个动因可能是解决方案的规模。如果编译和测试解决方案的时间太长,以至于开发人员不得不等待与其工作相关的反馈,分割解决方案为更小的部分可能更好。这将缩短开发人员的反馈周期,从而提高速度。另一个动因可能是多个团队正在开发一个应用程序,并且他们希望增加团队之间的隔离程度。

第八章,实施基础设施和配置作为代码

  1. 正确。ARM 模板允许你为 Azure 资源组中的所有资源指定最终状态。应用 ARM 模板将始终导致创建缺失的资源并更新现有资源。如果指定了部署模式 complete,即使是模板中没有的资源也会被删除。

  2. 正确答案是 B。模块、Run As 帐户和变量都是在 第八章 中讨论的构造,实施基础设施和配置作为代码

  3. 错误。ARM 模板参数允许引用 Azure Key Vault 中的值,以防止用户在源代码控制中输入机密或其他敏感信息。在部署时,这些机密将被检索并在 Azure 中使用,前提是启动操作的身份具有访问该密钥库的权限。

  4. 正确。你可以在 Azure Automation 帐户中定义一个或多个计划,并将它们与 Runbook 关联。

  5. 在实践基础设施即代码时可以预期许多好处。两个常见的例子是防止配置漂移和按需创建新环境。配置漂移通过按计划重新应用相同的基础设施规范到环境中来防止。按需环境可以用于快速创建新的测试环境,进行测试后再移除该环境。这允许更可重复的测试结果,并可能节省测试基础设施方面的费用。

第九章,在 DevOps 场景中处理数据库

  1. 正确。Entity Framework 和 Entity Framework Core 都内建支持在架构定义变更后生成迁移。

  2. 错误。大多数基于迁移的方法使用一个额外的表格来跟踪哪些迁移已经应用到数据库中。

  3. 正确。基于最终状态的方法通过比较当前的架构和目标架构来工作。这样会生成一个一次性的 SQL 脚本,运行该脚本以更新数据库中的架构。运行之间没有存储任何状态。

  4. 正确答案是 A 和 B。并行运行,如果操作正确,能大幅减少变更风险。如果出现问题,你可以随时移除所有新增代码以及数据库副本,然后从一个正常的工作状态重新开始。让两个情境都正常运行还可以非常精确地测量生产工作负载的性能。然而,其中一个缺点是,周期时间可能会增加。你必须一个一个地将多个小的变更移到生产环境中,这会增加总的时间消耗。

  5. 错误。你的架构(无论是隐式的还是在数据对象中捕获的)仍然会发生变化。然而,只有在从数据库中读取之前使用旧版本对象持久化的对象时,这一变化才会显现。从本质上来说,你只是推迟了处理架构变更的问题。

  6. 你可以选择不使用数据库级的编码技术,如存储过程和触发器。你将逻辑尽可能地放在数据库之外,可以减少需要做的数据库变更次数。

第十章,集成持续测试

  1. 正确。在单元测试中,测试的是单个组件,且是孤立测试。在面向对象语言中,这通常是单一的类。

  2. 错误。在集成测试中,验证的是一组组件的正确工作,而不是整个组装好的系统。如果是测试整个组装和部署的系统,这被称为系统测试。

  3. 答案 B 是正确的。测试金字塔建议进行大量的单元测试,以验证尽可能多的需求。集成测试只添加用于覆盖无法通过单元测试覆盖的风险,因此集成测试的数量较少。系统测试的数量更少,仅用于覆盖单元测试和集成测试都未覆盖的风险。

  4. 答案 C 是正确的。所有其他类型的测试都在本章中讨论。

  5. 这里可以提到的两种技术是代码审查和管道门控。代码审查允许开发人员审查同事的工作,以帮助彼此保持高质量。管道门控可以在不满足某些条件时,阻止应用程序的构建或版本进一步传播。示例条件包括某些质量度量或测试覆盖率或测试结果的最低标准。

第十一章,管理安全性和合规性

  1. 错误。为了安全地创建和交付软件,整个过程,特别是管道,需要被保护。仅仅在最后加入安全措施是行不通的,因为安全性必须贯穿交付过程的各个步骤。

  2. OWASP Zed 攻击代理ZAP)可以用于这种类型的测试。

  3. 正确。在现代应用程序中,最多 80%的代码可能来自开源库或框架。

  4. 正确的答案是 A、B、D 和 F。没有所谓的 Azure DevOps 安全变量或 Azure DevOps 密钥库。

  5. Azure 策略可以用于禁止或列出不希望的 Azure 配置,通常与基础设施配置或配置相关。Azure 安全中心(现为 Microsoft Defender for Cloud)可用于识别和修复运行时的安全风险。

第十二章,应用程序监控

  1. 错误。Azure 发出的平台度量是由每个独立服务定义的,无法更改。

  2. 93 天。这个数字保证了至少有三个月的历史记录。

  3. 正确。可以在您自己的应用程序代码中计算自定义度量并通过 SDK 或 REST API 发送到 Application Insights。

  4. 警报疲劳。

  5. 正确。Azure 允许创建包含 Web 钩子的操作组,以便在触发警报时响应。

第十三章,收集用户反馈

  1. 错误。一个可能的缺点是失去市场竞争优势。如果竞争对手知道你将要开发什么,他们可能会抢先一步。

  2. 可能的担忧是某些用户或用户群体比其他用户更为激进,这可能导致大众意见与听到的意见之间的差异。而且,关于公共路线图的反馈最可能来自现有用户。虽然保留这些用户很重要,但潜在客户可能不会就他们缺失的功能在你的路线图上发表评论。

  3. 本章讨论的两个例子是社交媒体渠道上的情感分析和支持请求的数量及严重性。

  4. 答案 C 是正确的。假设陈述了某个功能是必要的信念。在假设中,第二部分是一个可测量的用户反馈,在确认信念之前需要观察到。这被称为确认阈值。假设还没有得出结论。

  5. 用户访谈或焦点小组的潜在好处是,它们通常在较小的规模上进行,不仅可以衡量反馈,还可以理解反馈背后的原因。另一个好处是,参与者可以被精心挑选,以代表所有用户或某一特定细分群体。

第十六章,容器

  1. 容器对 DevOps 的好处包括一致性、关注点分离和平台可移植性。

  2. 正确。根据宿主操作系统的不同,容器托管在哪里并不重要。

  3. 是的,这是可能的。通过添加 Docker 支持和项目级别可以实现。

  4. RUN 命令用于在构建容器镜像的过程中安装组件或执行操作。

  5. 节点和容器可以在 Azure Kubernetes 服务中进行调度。这些组件都可以手动或自动扩展。

第十七章,规划您的 Azure DevOps 组织

  1. 错误。有些信息可以传输到其他区域或全球可用。例如,当选定区域的容量不足时,代理有时会在其他区域运行。

  2. 工作项 | 项目 | 组织 | 区域。Azure DevOps 组织是用户可以创建的最高级别构建。每个组织都严格位于一个区域,该区域由 Microsoft 维护。在一个组织内,可以创建一个或多个项目。反过来,一个项目可以包含许多工作项,如用户故事、功能或史诗。

  3. 错误。一般的推荐是只创建足够的项目:越少越好。隔离性和非常严格的授权边界可能是选择使用多个项目的原因。

  4. 授权和许可。可以为每个用户或用户组设置可访问的权限限制。分配给用户的许可证还可能禁止使用某些功能。例如,具有利益相关者许可证的用户不能使用源代码控制。

  5. 端到端可追溯性。当从单一工具执行工作管理、源代码控制、构建、工件和部署时,可以追踪部署过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值