負荷分散エンドポイントとACL (と、バグ)

前回の記事「エンドポイントに ACL を!」で、Windows Azure 仮想マシンのエンドポイントに ACL を設定する方法をご紹介しました。

Windows Azure のエンドポイントには、前回紹介したシンプルなやつのほかに、「負荷分散エンドポイント」というのもあります。

これはパブリックポートへのアクセスを、複数の仮想マシンのローカルポートに順番に割り振るものです。そして、もちろんこれにも ACL が設定できるのですが、前回の記事で紹介したコマンドレット “Set-AzureEndpoint” を使うと次のようなエラーが出てしまいます。

Update-AzureVM : "An exception occurred when calling the ServiceManagement API. HTTP Status Code: 400. Service Management Error Code: BadRequest. Message: Existing endpoints in LB set '' do not contain ACL.. Operation Tracking ID:
22304468014d33bfc58ebd309ce61."
発生場所 行:1 文字:136
+ ... 80 -ACL $acl | Update-AzureVM
+ ~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Update-AzureVM]、ServiceManagementClientException
+ FullyQualifiedErrorId : Microsoft.WindowsAzure.Management.ServiceManagement.IaaS.UpdateAzureVMCommand

Set-AzureLoadBalancedEndpoint

実は、負荷分散エンドポイントにの設定変更には、専用のコマンドレット “Set-AzureLoadBalancedEndpoint” が用意されています。これを使うことで、負荷分散セット(負荷分散対象の VM 群)内のすべての VM のエンドポイントの設定を変更することができます。もちろん ACL 設定も。

例を示しましょう。クラウドサービス “sasaweb” 内に “sasaweb01”, “sasaweb02” の 2 台の VM があるとします。この場合以下のように、いずれか一台の VM を Get-AzureVM して、 Set-AzureLoadBalancedEndpoint に流し込んでやれば OK.

Get-AzureVM -ServiceName sasaweb -Name sasaweb01
| Set-AzureLoadBalancedEndpoint -LBSetName webfarm -Protocol tcp -LocalPort 80 -PublicPort 80 -ProbeProtocolTCP -ProbePort 80 -ACL $acl

しかし一つバグが

ただ、大変申し訳ないのですが、現在の負荷分散エンドポイントには一つバグがあります。

まず、下図をご覧ください。負荷分散エンドポイントには、通常のエンドポイントにある “PublicPort” と “LocalPort” のほかに “ProbePort” というものがあります。これは、負荷分散機が、割り振り対象の仮想マシン達に対して死活監視をするためのポートです。

 

image

負荷分散プロトコルとして “tcp” と “http” が指定できて (HTTPだってTCP上のプロトコルだろ、というツッコミはご容赦) 、“tcp” の場合は単純に ProbePort に対して接続を試みて ACK が返ってくれば、そのサーバーは負荷分散対象として「生きている」とみなされます。 “http” の場合は ProbePort に加えて “ProbePath” というオプションで URI も指定できて、そこを GET して 200 OK が返れば「生きている」ことになります。

で、バグなのですが、

LocalPort と ProbePort に同じ値を指定すると、 ACL が無効になってしまいます

この辺にも記述があります→ Endpoint ACL doesn't work when Local Port and Probe Port are the same

対策

とりあえずの回避策としては、「ProbePort には LocalPort と違う値を指定する」しかありません。そして、その為には ProbePort に指定するポートもちゃんと bind されて LocalPort と同じように機能しなければなりません。

IIS だと Web サイトの「バインド」の設定。

image

Apache なら httpd.conf の Listen ディレクティブでの設定ですね。

image

その上で、次のように負荷分散エンドポイント設定をお願いします。

Get-AzureVM -ServiceName sasaweb -Name sasaweb01 | Set-AzureLoadBalancedEndpoint -LBSetName webfarm -Protocol tcp -LocalPort 80 -PublicPort 80 -ProbeProtocolTCP -ProbePort 8080 -ACL $acl

※ LBSetName というのは、負荷分散対象 VM 群を識別する名前です。Get-AzureEndpoint すると出てきます。

PS C:\> Get-AzureVM -ServiceName sasaweb -Name sasaweb01 | Get-AzureEndpoint

LBSetName : webfarm
LocalPort : 80
Name : http
Port : 80
Protocol : tcp

おまけ

負荷分散エンドポイント関連の PowerShell コマンドを二つご紹介します。


クラウドサービス “sasaweb” 内の全 VM に負荷分散エンドポイントを新規作成。同時にACLも設定:

  • ”LBSetName” 前述の通り、負荷分散対象 VM 群を識別する名前です。
  • “Name” は個々の仮想マシンのエンドポイントの名前

Get-AzureVM -ServiceName sasaweb | Add-AzureEndpoint -LBSetName webfarm -Name http -Protocol tcp -LocalPort 80 -PublicPort 80 -ProbePort 8080 -ProbeProtocol tcp -ACL $acl | Update-AzureVM


エンドポイント “http” を、クラウドサービス “sasaweb” 内の全 VM から一度に削除:

Get-AzureVM -ServiceName sasaweb | Remove-AzureEndpoint -Name http | Update-AzureVM


近いうちにエンドポイント ACL の設定も管理ポータルからできるようになると思いますが、 PowerShell はとても便利なのでぜひお試しください。何が便利ってこういうブログからコピペしてすぐ実行できますしね!

__END__