缺少集群证书导致 Add-AzServiceFabricClusterCertificate 失败:Object 引用未设置为 object 的实例

Missing cluster cert causes Add-AzServiceFabricClusterCertificate to fail: Object reference not set to an instance of an object

我是 Service Fabric 的新手,所以我不确定这是 cmdlet 的问题还是我的失误。我正在使用 Az.ServiceFabric 模块版本 2.0.2 和 Az 模块版本 3.8.0.

我正在尝试使用 Add-AzServiceFabricClusterCertificate cmdlet 将我已经在 Azure KeyVault 中创建的辅助证书添加到我的集群。当我 运行 该 cmdlet 时,它失败并出现此错误(运行 调试给了我更多堆栈详细信息):

DEBUG: AzureQoSEvent: CommandName - Add-AzServiceFabricClusterCertificate; IsSuccess - False; Duration -
00:00:07.3059582;; Exception - System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Azure.Commands.ServiceFabric.Commands.ServiceFabricClusterCmdlet.GetClusterType(Cluster
clusterResource)
   at Microsoft.Azure.Commands.ServiceFabric.Commands.AddAzureRmServiceFabricClusterCertificate.ExecuteCmdlet()
   at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord();

查看此 cmdlet 的代码,我注意到它可能失败了,因为传递到 GetClusterType 的集群资源没有其 Certificate 成员,因此当它尝试检查 Certificate.Thumbprint 和Certificate.Thumbprint中学:

        internal ClusterType GetClusterType(Cluster clusterResource)
        {
            if (string.IsNullOrWhiteSpace(clusterResource.Certificate.Thumbprint) &&
                string.IsNullOrWhiteSpace(clusterResource.Certificate.ThumbprintSecondary))
            {
                return ClusterType.Unsecure;
            }
            else
            {
                return ClusterType.Secure;
            }
        }

以与 Get-AzServiceFabricCluster cmdlet 相同的方式检索传递到 GetClusterType 的集群,因此当我 运行 我尝试添加证书的集群的 cmdlet 时到,我注意到我的证书字段在响应中是空的。我猜这就是导致 NullRef 异常的原因。这是相关的片段:

          AzureActiveDirectory :
              TenantId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
              ClusterApplication : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
              ClientApplication : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
          Certificate :
          CertificateCommonNames : Microsoft.Azure.Management.ServiceFabric.Models.ServerCertificateCommonNames
          ClientCertificateCommonNames :
          ClientCertificateThumbprints :

我想知道当我使用 Get-AzServiceFabricCluster cmdlet 时证书字段是否应该为空,这是否确实是我的 Add-AzServiceFabricClusterCertificate cmdlet 失败的原因。当我在 Azure 门户中查看集群的安全性 blade 时,我确实看到了我最初创建集群时使用的主集群证书,这是我在部署和执行其他集群操作时使用的证书。但是,我注意到从门户查看证书时证书指纹字段为空。我希望在使用 Get-AzServiceFabricCluster 时看到此证书,但它是空的。我的 Get-AzServiceFabricCluster cmdlet 中缺少此证书是否可以通过门户或其他 cmdlet 修复?

您的集群似乎配置为按通用名称而不是指纹查找证书。除了您发布的代码段之外,我猜这是基于您的门户网站没有显示针对证书的指纹这一事实。

如果是这种情况,当旧证书过期时,无需使用新证书更新集群配置 - 相反,您只需将证书安装到您的 VMSS 库中.将新证书添加到 VMSS 后,Service Fabric 将自动使用稍后到期的证书

您必须始终确保您的 VMSS 上至少安装了一个有效证书,并使用您的集群中配置的公用名称。

PS 上传证书 KV 并安装到 VMSS:

$subscriptionId  = "sub-id"
$vmssResourceGroupName     = "vmss-rg-name"
$vmssName                  = "vmss-name"
$vaultName                 = "kv-name"
$primaryCertName           = "kv-cert-name"
$certFilePath              = "...\.pfx"
$certPassword              = ConvertTo-SecureString -String "password" -AsPlainText -Force

# Sign in to your Azure account and select your subscription
Login-AzAccount -SubscriptionId $subscriptionId

# Update primary certificate within the Key Vault
$primary = Import-AzKeyVaultCertificate `
    -VaultName $vaultName `
    -Name $primaryCertName `
    -FilePath $certFilePath `
    -Password $certPassword

$certConfig = New-AzVmssVaultCertificateConfig -CertificateUrl $primary.SecretId -CertificateStore "My"

# Get VM scale set 
$vmss = Get-AzVmss -ResourceGroupName $vmssResourceGroupName -VMScaleSetName $vmssName

# Add new certificate version
$vmss.VirtualMachineProfile.OsProfile.Secrets[0].VaultCertificates.Add($certConfig)

# Update the VM scale set 
Update-AzVmss -ResourceGroupName $vmssResourceGroupName -Verbose `
    -Name $vmssName -VirtualMachineScaleSet $vmss

有关详细信息,我写了一个 blog post 关于从指纹切换到通用名称的文章。

official docs也是很好的参考。