☰
90DaysOfDevOps 第 34 天实战:Microsoft Azure 虚拟网络、流量管理、存储与 Web 应用端到端演练
2026/10/5 9:52:58 网站建设 项目流程
  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

本文基于 2022/ja/Days/day34.md(90DaysOfDevOps 第 34 天)整理:在前 6 天打下的 Azure 与公有云理论基础上,作者以微软官方 AZ-104 管理员认证实验为蓝本,挑选与前期学习进度匹配的动手场景,依次完成虚拟网络、网络流量管理、Azure 存储、无服务器 Web 应用四大模块的端到端演练。读完本文,你将掌握如何用 Azure CLI 登录、用 PowerShell + ARM 模板批量部署 VM 与网络资源、验证虚拟网络对等互连的传递性、配置负载均衡器与应用网关,以及通过部署槽(Staging Slot)实现 Web 应用的无中断发布与自动缩放。

为什么专注一个云提供商开始动手

在第 34 天之前,系列文章已经用 6 天时间集中学习了 Microsoft Azure 以及公有云的通识基础。作者的观点很明确:先专注一家云厂商,把它的地基打牢,再迁移到其他云时才能举一反三。如果你一开始就在 AWS、Azure、GCP 之间来回切换,反而容易迷失;而当你吃透了一家的虚拟网络、身份权限、存储与计算模型之后,这些概念在其他云上几乎可以平滑平移,学习速度会显著加快。

因此本天的实验素材没有另起炉灶,而是直接采用微软官方为AZ-104(Microsoft Azure Administrator)认证准备的实验指南中的模块 04、06、07、09a,并将其中的资源命名改为90Days*前缀以适配本系列。其中模块 01、02、03 已在前几天的文章中完成,这里从模块 04 开始继续推进。由于此时尚未系统讲解容器与 Kubernetes,实验中有涉及的部分(如容器组)被有意跳过。

动手前的准备:az login 与最小权限用户

作者没有使用浏览器里的 Cloud Shell,而是在本地 Windows 机器上安装 Azure CLI,并用前几天创建的新用户(michael.cade@90DaysOfDevOps.com)登录,该用户通过 RBAC 被限定在90DaysOfDevOps资源组内。这一设计让后续所有实验都真实暴露了"最小权限"下的操作边界,是本篇最值得复刻的经验。

# 打开浏览器完成 OAuth 交互式登录 az login

登录后,作者为每个模块都准备了一个 PowerShell 脚本 + 一对 ARM 模板(模板与参数分离),全部存放在仓库的 2022/Days/Cloud 目录下。运行脚本前务必把其中的-TemplateFile/-TemplateParameterFile指向你本地的实际路径(原文提示:"Please make sure you change the file location in the script to suit your environment")。

模块一:虚拟网络(Virtual Networking)

参照 AZ-104 模块 04"实现虚拟网络"实验,作者将命名改成90Days*前缀后,通过 Module4_90DaysOfDevOps.ps1 一键触发资源组部署:

$rgName = '90DaysOfDevOps' New-AzResourceGroupDeployment ` -ResourceGroupName $rgName ` -TemplateFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\01VirtualNetworking\Mod04_90DaysOfDevOps-vms-loop-template.json ` -TemplateParameterFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\01VirtualNetworking\Mod04_90DaysOfDevOps-vms-loop-parameters.json

New-AzResourceGroupDeployment是 Az PowerShell 模块中"以 ARM 模板在指定资源组内创建/更新资源"的核心 cmdlet,模板与参数文件分离,便于把敏感值(管理员密码)放在参数文件中单独管理。实验开始前,环境中没有任何 VNet 与 VM,仅在资源组里存在一个 Cloud Shell 存储位置。运行脚本后依次完成 5 个任务。

任务 1:创建并配置虚拟网络

ARM 模板 Mod04_90DaysOfDevOps-vms-loop-template.json 用声明式方式定义了网络与计算资源,几个关键设计点:

  • 参数化:vmSize默认Standard_D2s_v3、vmName前缀默认90day-vm、vmCount默认2、virtualNetworkName默认90daysofdevops;adminPassword用securestring类型,部署时不会以明文回显。
  • 地址规划:VNet 地址空间为10.40.0.0/22,下分两个子网subnet0(10.40.0.0/24)与subnet1(10.40.1.0/24),为后续任务里"多子网 + 不同网段 VM"提供基础。
  • copy 循环:通过"copy": {"count": "[parameters('vmCount')]"}一次声明多台 VM 与其 NIC,资源名用concat(parameters('vmName'),copyIndex())生成90day-vm0、90day-vm1等,避免手写重复资源块。
"properties": { "addressSpace": { "addressPrefixes": [ "10.40.0.0/22" ] }, "subnets": [ { "name": "subnet0", "properties": { "addressPrefix": "10.40.0.0/24" } }, { "name": "subnet1", "properties": { "addressPrefix": "10.40.1.0/24" } } ] }

任务 2:将虚拟机部署进虚拟网络

模板中的 VM 采用 Windows Server 2019 Datacenter 镜像(publisher: MicrosoftWindowsServer、sku: 2019-Datacenter),VM 通过dependsOn声明依赖对应的 NIC,NIC 又依赖 VNet 创建,从而保证资源按正确的先后顺序落地:

"imageReference": { "publisher": "MicrosoftWindowsServer", "offer": "WindowsServer", "sku": "2019-Datacenter", "version": "latest" }, "networkProfile": { "networkInterfaces": [ { "properties": { "primary": true }, "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nic'),copyIndex()))]" } ] }

任务 3:配置 Azure VM 的私有与公共 IP

部署完成后进入门户/CLI 检查 VM 的 NIC 配置。本实验模板中privateIPAllocationMethod为Dynamic(动态分配),因此 VM 重启后私有 IP 可能变化;生产环境的固定地址应改用Static并通过publicIPAddress资源绑定公网 IP。

任务 4:配置网络安全组(NSG)

通过 NSG 为子网/网卡层下发入站与出站规则,控制虚拟机暴露面。任务要点包括:创建 NSG、将其关联到子网或 NIC、允许/拒绝指定的源-目标端口组合,并用实际流量验证规则生效。

任务 5:配置 Azure DNS 实现内部名称解析

Azure 默认对同一 VNet 内的 VM 提供内部 DNS 解析(<vm-name>.<region>.internal.cloudapp.net)。实验验证了 VM 之间可通过主机名互访,也演示了如何在 VNet 上启用自定义 DNS 服务器,为混合云场景中的名称解析做准备。

模块二:网络流量管理(Network Traffic Management)

完成模块 04 后,作者删除了上一个实验的全部资源与资源组(由于该用户只拥有该资源组的权限,直接删除90DaysOfDevOps组即可清空所有内容),每个实验都从"干净环境"开始。此模块对应 AZ-104 模块 06"实现网络流量管理",同样配套脚本 Mod06_90DaysOfDevOps.ps1 与一对模板文件。

$rgName = '90DaysOfDevOps' New-AzResourceGroupDeployment ` -ResourceGroupName $rgName ` -TemplateFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\02TrafficManagement\Mod06_90DaysOfDevOps-vms-loop-template.json ` -TemplateParameterFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\02TrafficManagement\Mod06_90DaysOfDevOps-vms-loop-parameters.json

部署完成后脚本还会对资源组内每台 VM 循环安装Network Watcher Agent(Windows)扩展,为后续连接性诊断做准备:

$location = (Get-AzResourceGroup -ResourceGroupName $rgName).location $vmNames = (Get-AzVM -ResourceGroupName $rgName).Name foreach ($vmName in $vmNames) { Set-AzVMExtension ` -ResourceGroupName $rgName ` -Location $location ` -VMName $vmName ` -Name 'networkWatcherAgent' ` -Publisher 'Microsoft.Azure.NetworkWatcher' ` -Type 'NetworkWatcherAgentWindows' ` -TypeHandlerVersion '1.4' }

任务 1:准备实验环境

Mod06_90DaysOfDevOps-vms-loop-template.json 与模块 04 的差异值得对比学习:

  • vmCount提升到4,用于搭建 hub-spoke 拓扑(hub 1 台 + spoke 3 台)。
  • 通过createArray定义 4 台 VM 分属 3 个不同 VNet:90day-vm-vnet01(两台)、90day-vm-vnet2、90day-vm-vnet3,地址前缀分别为10.60.x、10.62.x、10.63.x;subnetRefs: [0,1,0,0]用于把不同 VM 挂到不同子网。
  • 每个 VNet 配套独立 NSG(90day-vm-nsg01/2/3)。
  • 通过CustomScriptExtension在每台 VM 上一键安装 IIS 并写入标识页面,方便后续连通性验证:
"commandToExecute": "powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item 'C:\\inetpub\\wwwroot\\iisstart.htm' && powershell.exe Add-Content -Path 'C:\\inetpub\\wwwroot\\iisstart.htm' -Value $('Hello World from ' + $env:computername)"

任务 2:配置 Hub 与 Spoke 网络拓扑

将90day-vm-vnet01视为 Hub,vnet2、vnet3作为 Spoke,通过**虚拟网络对等互连(VNet Peering)**把 Hub 与两个 Spoke 分别打通。

任务 3:验证虚拟网络对等互连的传递性

这是本实验的"考点"所在。作者测试 Spoke1 到 Spoke2 的连通性时失败了——这是符合预期的,因为虚拟网络对等互连不具备传递性:Spoke1 与 Hub 对等、Hub 与 Spoke2 对等,并不等于 Spoke1 与 Spoke2 直接可达,除非显式建立两条 Spoke 之间的对等。

在此过程中作者遇到了一个真实的 RBAC 问题:90DaysOfDevOps组的用户无法访问 Network Watcher。原因在于 Network Watcher 是区域级资源,不绑定某个资源组,而该用户的 RBAC 授权只覆盖90DaysOfDevOps资源组。作者随后为组授予了East US Network Watcher Contributor角色才得以继续。

任务 4:配置 Hub 与 Spoke 拓扑中的路由

通过**路由表(Route Table)/ 自定义路由(UDR)**在 Hub 上配置转发规则,使流量经 Hub 转发。作者在此又遇到第二个权限问题:使用90DaysOfDevOps组内的用户身份无法在 VM 内执行命令(尽管该组是资源组的 Owner),于是临时切回主管理员账户完成,再切回 michael.cade@90DaysOfDevOps.com 继续。修复路由后重跑相同测试,结果变为reachable:

任务 5:实现 Azure Load Balancer

创建负载均衡器并配置后端池、健康探测(Health Probe)与负载均衡规则,把多台 VM 的流量按规则分发,验证故障转移与健康检查行为。

任务 6:实现 Azure Application Gateway

与 L4 的 Load Balancer 不同,Application Gateway 工作在 L7,支持基于 URL 路径 / 主机名的路由、SSL 终止与 Web 应用防火墙能力。实验完成 HTTP 监听器、后端池与路由规则的配置,并验证通过网关访问后端应用。

模块三:Azure 存储(Azure Storage)

对应 AZ-104 模块 07"管理 Azure 存储"。配套脚本为 Mod07_90DaysOfDevOps.ps1,模板是单 VM 版本 Mod07_90DaysOfDevOps-vm-template.json:

$rgName = '90DaysOfDevOps' New-AzResourceGroupDeployment ` -ResourceGroupName $rgName ` -TemplateFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\03Storage\Mod07_90DaysOfDevOps-vm-template.json ` -TemplateParameterFile C:\Users\micha\demo\90DaysOfDevOps\Days\Cloud\03Storage\Mod07_90DaysOfDevOps-vm-parameters.json ` -AsJob

注意这里追加了-AsJob参数——存储实验的模板部署耗时较长,-AsJob让 PowerShell 把部署放到后台作业执行,不阻塞当前会话,方便边部署边观察进度。模板中 VM 名称为90Days-vm0,VNet90Days-vnet0地址空间10.70.0.0/22、子网10.70.0.0/24,同样基于 Windows Server 2019 镜像。

任务 1:准备实验环境

运行上述脚本部署实验 VM,供后续存储任务使用。

任务 2:创建并配置 Azure 存储账户

创建存储账户时需要关注的关键项:账户名(全局唯一、仅小写字母与数字)、冗余策略(LRS/GRS/RA-GRS 等)、访问层级(热/冷)、以及用于 Blob、文件、队列、表的服务端点。

任务 3:管理 Blob 存储

创建容器并上传/下载 Blob,练习设置容器访问级别(私有/容器/Blob 匿名读),理解 SAS(共享访问签名)与存储访问密钥在授权上的差别。

任务 4:管理 Azure 存储的身份验证与授权

实验覆盖两种授权路径:**共享密钥(存储账户密钥)**与Azure AD 身份。作者在等 AD 授权逐步生效时遇到短暂等待("I was a little impatient waiting for this to be allowed but it did work eventually"),这也是权限传播存在延迟的常见现象。验证在 VM 内部通过门户/CLI 以受限用户身份访问存储时,能否正确触发 RBAC 授权。

任务 5:创建并配置 Azure 文件共享

创建 Azure Files 共享并映射到 VM 的驱动器。作者在此再次遇到权限边界:使用 michael.cade@90DaysOfDevOps.com 身份执行run command不成功,切换至提升权限的管理员账户后完成共享的挂载与访问验证。

任务 6:管理 Azure 存储的网络访问

通过存储账户的防火墙与虚拟网络设置限定允许的来源:选择"所选网络"后,只放行指定的 VNet/子网或 IP 范围,其他来源一律拒绝,从而把存储账户收敛到内网访问面。

模块四:无服务器与 Web 应用(Implement Web Apps)

最后一个实验对应 AZ-104 模块 09a"实现 Web 应用",用于演示 Azure App Service 的完整发布与缩放流程。虽然本模块在原文中没有独立脚本,但仓库中提供了配套的压测脚本 Mod09a_90DaysOfDevOps.ps1:

$rgName = '90DaysOfDevOps' $webapp = Get-AzWebApp -ResourceGroupName $rgName # 以下循环将持续向 Web 应用发送 HTTP 请求,用于触发自动缩放 while ($true) { Invoke-WebRequest -Uri $webapp.DefaultHostName }

该脚本先通过Get-AzWebApp拿到刚创建的 Web 应用默认主机名,再用while ($true)无限循环发起 HTTP 请求——这正是为任务 6"配置并测试 Web 应用自动缩放"制造真实负载的工具,让缩放规则可以在可观测的请求量下被触发验证。

任务 1:创建 Azure Web 应用

在 App Service 中创建 Web 应用(选择运行时栈与区域)。注意原文在任务标题处引用的截图位于其Images/Day34_Cloud31.png等文件中,仓库对应的完整截图序列见 2022/Days/Images(Day34_Cloud1 ~ Day34_Cloud36)。

任务 2:创建过渡部署槽(Staging Deployment Slot)

为 Web 应用创建staging部署槽,使生产与预发布共享同一 App Service 但各自拥有独立的 URL 与应用设置,这是"先验证、再切换"发布流程的前提。

任务 3:配置 Web 应用部署设置

在部署槽上配置应用设置、连接字符串与部署方式(如从本地 Git / ZIP 包部署),确保 staging 槽使用的配置与生产隔离、可控。

任务 4:将代码部署到过渡部署槽

把应用代码发布到 staging 槽,先在预发布地址上完成冒烟测试,不影响线上版本。

任务 5:交换过渡槽(Swap)

通过"交换(Swap)"将 staging 与 production 槽互换,实现零停机发布:老版本进入 staging 回滚位,新版本接管生产流量;若出现问题可一键再次交换回滚。

任务 6:配置并测试 Web 应用的自动缩放

在 App Service 的"缩放"面板配置基于 CPU 百分比等指标的自动缩放规则,随后运行上文 Mod09a_90DaysOfDevOps.ps1 持续打流量,观察实例数随负载增加而自动扩展的过程。

实验复盘:本天暴露的三个真实工程问题

把第 34 天的"踩坑"单独提炼出来,它们比顺利跑通的流程更有参考价值:

  1. Network Watcher 与资源组解耦:Network Watcher 是区域级资源而非资源组内资源,导致"只拥有资源组权限"的用户无法使用连接诊断。修复方式是额外授予区域级Network Watcher Contributor角色。这提醒我们在做 RBAC 规划时,不能只盯着资源组,还要考虑区域级/订阅级服务。
  2. VNet 对等互连不传递:Hub-Spoke 架构下,Spoke 之间默认不可达,必须显式对等或借助 Hub 路由转发,这是网络拓扑设计中最容易被忽略的假设。
  3. 最小权限账户在 VM 内执行的限制:即使对资源组拥有 Owner 权限,部分 VM 内操作(run command、脚本执行)仍可能受限于其他层面(如 Azure 角色对 VM 扩展的授权、凭据提升),必要时需临时使用提升权限的管理员账户完成,随后切回受限账户继续验证。

资源与下一步

本天内容为 Azure 与公有云部分画上句号。相关素材均在仓库内可直接复现:

  • 脚本与模板:2022/Days/Cloud(01VirtualNetworking / 02TrafficManagement / 03Storage / 04Serverless 四个子目录,含.ps1、-template.json、-parameters.json与 LICENSE)
  • 实验截图: 2022/Days/Images/Day34_Cloud1.png 至 Day34_Cloud36.png
  • 配套延伸视频资源:混合云与多云、Microsoft Azure 基础、Google Cloud 数字领导者认证课程、AWS 入门全课程等(均可在公开平台检索)

下一阶段将正式进入版本控制系统(Git)与代码仓库概览,并选择 GitHub 作为实践平台,见 第 35 天。

  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询