在虚拟机规模集上配置用于滚动升级的自定义指标(预览版)

注意

虚拟机规模集上用于滚动升级的自定义指标目前为预览版。 需同意补充使用条款才可使用预览版。 在正式版 (GA) 推出之前,这些功能的某些方面可能会有所更改。

通过用于滚动升级的自定义指标,可以利用应用程序运行状况扩展向虚拟机规模集发出自定义指标。 这些自定义指标可用于向规模集告知在触发滚动升级时更新虚拟机应采用的顺序。 自定义指标还可以向规模集告知特定实例应在何时跳过升级。 这样可以更好地控制排序和更新过程本身。

自定义指标可以与其他滚动升级功能结合使用,例如自动 OS 升级

要求

  • 在虚拟机规模集上使用用于滚动升级的自定义指标时,规模集还必须使用具有丰富运行状况状态的应用程序运行状况扩展来报告阶段排序或跳过升级信息。 使用具有二元状态的应用程序运行状况扩展时,不支持自定义指标升级。
  • 必须设置应用程序运行状况扩展才能使用 HTTP 或 HTTPS 来接收自定义指标信息。 不支持 TCP 与用于滚动升级的自定义指标集成。

概念

阶段排序

阶段是虚拟机的分组构造。 设置应用程序运行状况扩展通过 customMetrics 属性发出的元数据可确定每个阶段。 虚拟机规模集获取从自定义指标中检索的信息,并使用它将虚拟机置于分配的阶段。 在每个阶段中,虚拟机规模集还将分配升级批次。 每个批次都使用滚动升级策略进行配置,该策略将考虑每个虚拟机的更新域 (UD)、容错域 (FD) 和区域信息。

启动滚动升级后,虚拟机将置于指定阶段。 分阶段升级按数字顺序执行。 某个阶段内所有批次的虚拟机都完成后才能进入下一阶段。 如果未收到虚拟机的阶段排序,规模集会将它置于最后一个阶段

地区性规模集此图显示了在地区规模集上使用 n 阶段升级时所发生情况的概要示意图。

区域性规模集此图显示了在区域规模集上使用 n 阶段升级时所发生情况的概要示意图。

若要指定虚拟机应与之关联的阶段编号,请使用 phaseOrderingNumber 参数。

{
     “applicationHealthState”: “Healthy”,
      “customMetrics”: "{ \"rollingUpgrade\": { \"PhaseOrderingNumber\": 0 } }"
}

跳过升级

使用跳过升级功能可在滚动升级期间忽略单个示例的升级。 这类似于使用实例保护,但可以更无缝地集成到滚动升级工作流和实例级应用程序中。 与阶段排序类似,跳过升级信息通过应用程序运行状况扩展和自定义指标设置传递到虚拟机规模集。 触发滚动升级时,虚拟机规模集会检查应用程序运行状况扩展自定义指标的响应,如果跳过升级设置为 true,则实例不包括在滚动升级中。

此图显示了在区域规模集上使用跳过升级时所发生情况的概要示意图。

若要跳过虚拟机上的升级,请使用 SkipUpgrade 参数。 这会告知滚动升级在执行升级时跳过此虚拟机。

{
     “applicationHealthState”: “Healthy”,
      “customMetrics”: "{ \"rollingUpgrade\": { \"SkipUpgrade\": true} }"
}

跳过升级和阶段排序还可配合使用:

{
     “applicationHealthState”: “Healthy”,
      “customMetrics”: "{ \"rollingUpgrade\": { \"SkipUpgrade\": false, \"PhaseOrderingNumber\": 0 } }"
}

配置应用程序运行状况扩展

应用程序运行状况扩展要求 HTTP 或 HTTPS 请求具备关联端口或请求路径。 使用应用程序运行状况扩展时,TCP 探测受支持,但无法通过探测响应正文设置 ApplicationHealthState,并且不能与滚动升级自定义指标一起使用。

{
  "extensionProfile" : {
     "extensions" : [
      {
        "name": "HealthExtension",
        "properties": {
          "publisher": "Microsoft.ManagedServices",
          "type": "<ApplicationHealthLinux or ApplicationHealthWindows>",
          "autoUpgradeMinorVersion": true,
          "typeHandlerVersion": "1.0",
          "settings": {
            "protocol": "<protocol>",
            "port": <port>,
            "requestPath": "</requestPath>",
            "intervalInSeconds": 5,
            "numberOfProbes": 1
          }
        }
      }
    ]
  }
}
名称 值/示例 数据类型
protocol httphttps string
port 在协议为 httphttps 时为可选 int
requestPath 在使用 httphttps 时为必需 string
intervalInSeconds 可选,默认值为 5 秒。 此设置是每次运行状况探测之间的间隔。 例如,如果 intervalInSeconds == 5,则会每隔 5 秒向本地应用程序终结点发送一次探测。 int
numberOfProbes 可选,默认值为 1。 此设置是更改运行状况所需的连续探测数。 例如,如果 numberOfProbles == 3,则需要 3 个连续的“正常”信号才能将运行状况从“不正常”/“未知”更改为“正常”状态。 相同的要求适用于将运行状况更改为“不正常”或“未知”状态。 int
gracePeriod 可选,默认值 = intervalInSeconds * numberOfProbes;最大宽限期为 7200 秒 int

安装应用程序运行状况扩展

使用 az vmss 扩展集将应用程序运行状况扩展添加到规模集模型定义中。

使用所需设置创建名为 extensions.json 的 json 文件。

{
  "protocol": "<protocol>",
  "port": <port>,
  "requestPath": "</requestPath>",
  "gracePeriod": <healthExtensionGracePeriod>
}

应用应用程序运行状况扩展。

az vmss extension set \
  --name ApplicationHealthLinux \
  --publisher Microsoft.ManagedServices \
  --version 2.0 \
  --resource-group myResourceGroup \
  --vmss-name myScaleSet \
  --settings ./extension.json

升级规模集中的虚拟机。 仅当规模集使用手动升级策略时,才需要此步骤。 有关升级策略的详细信息,请参阅虚拟机规模集的升级策略

az vmss update-instances \
  --resource-group myResourceGroup \
  --name myScaleSet \
  --instance-ids "*"

配置应用程序运行状况扩展响应

可以通过多种不同的方式配置自定义指标响应。 它可以集成到现有应用程序中,动态更新,并配合各种函数使用,以基于特定情况提供输出。

示例 1:阶段排序

此示例应用程序可以安装在规模集中的虚拟机上,以发出所属阶段消息。

#!/bin/bash

# Open firewall port (replace with your firewall rules as needed)
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

# Create Python HTTP server for responding with JSON
cat <<EOF > server.py
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

# Function to generate the JSON response
def generate_response_json():
    return json.dumps({
        "ApplicationHealthState": "Healthy",
        "CustomMetrics": {
            "RollingUpgrade": {
                "PhaseOrderingNumber": 0
            }
        }
    })

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # Respond with HTTP 200 and JSON content
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        response = generate_response_json()
        self.wfile.write(response.encode('utf-8'))

# Set up the HTTP server
def run(server_class=HTTPServer, handler_class=RequestHandler):
    server_address = ('localhost', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server on port 8000...')
    httpd.serve_forever()

if __name__ == "__main__":
    run()
EOF

# Run the server
python3 server.py

示例 2:跳过升级

此示例应用程序可以安装在规模集中的虚拟机上,以发出在即将进行的滚动升级中应忽略的实例。

#!/bin/bash

# Open firewall port (replace with your firewall rules as needed)
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

# Create Python HTTP server for responding with JSON
cat <<EOF > server.py
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

# Function to generate the JSON response
def generate_response_json():
    return json.dumps({
        "ApplicationHealthState": "Healthy",
        "CustomMetrics": {
            "RollingUpgrade": {
                "SkipUpgrade": "true"
            }
        }
    })

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # Respond with HTTP 200 and JSON content
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        response = generate_response_json()
        self.wfile.write(response.encode('utf-8'))

# Set up the HTTP server
def run(server_class=HTTPServer, handler_class=RequestHandler):
    server_address = ('localhost', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server on port 8000...')
    httpd.serve_forever()

if __name__ == "__main__":
    run()
EOF

# Run the server
python3 server.py

示例 3:阶段排序和跳过升级组合

此示例应用程序将阶段排序和跳过升级参数添加到自定义指标响应中。

#!/bin/bash

# Open firewall port (replace with your firewall rules as needed)
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

# Create Python HTTP server for responding with JSON
cat <<EOF > server.py
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

# Function to generate the JSON response
def generate_response_json():
    return json.dumps({
        "ApplicationHealthState": "Healthy",
        "CustomMetrics": {
            "RollingUpgrade": {
                "PhaseOrderingNumber": 1,
                "SkipUpgrade": "false"
            }
        }
    })

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # Respond with HTTP 200 and JSON content
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        response = generate_response_json()
        self.wfile.write(response.encode('utf-8'))

# Set up the HTTP server
def run(server_class=HTTPServer, handler_class=RequestHandler):
    server_address = ('localhost', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server on port 8000...')
    httpd.serve_forever()

if __name__ == "__main__":
    run()
EOF

# Run the server
python3 server.py

有关更多响应配置示例,请参阅应用程序运行状况示例

后续步骤

了解如何在虚拟机规模集上执行手动升级