AKSやVMで複数マネージドIDに紐付けるとIdentity not foundとなり認証できなくなる件

結論

複数のマネージドIDを紐付けている時には、認証時にどのマネージドIDを利用するか指定する必要があります。

こう書くと当たり前の話ですが・・ハマりました。

以下の例ではAKSで話しますが、VMでも複数の「ユーザー割り当て済み」のIDを設定していると同じ状態になります。

事象

最初は、マネージドID(Managed identities for Azure resources 旧MSI)による認証を有効化しているAKSクラスタにて、Container Insight機能(monitoringアドオン)を有効化したときに問題が発生しました。

Addon有効化後も暫くは問題無く動いているのですが、数時間~24時間程度経過するとPodが全て失敗する事態に遭遇しました。そしてAddonを無効化すると直る。

事象の深掘り

調べてみるとマネージドIDによる認証が上手くいってないようでした。

具体的には、Identity not found というエラーからIMDS(メタデータサービス)からOAuth2のTokenが返ってこない状態でした。

$ curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' -H Metadata:true -s
{"error":"invalid_request","error_description":"Identity not found"}

Pytnonのモジュールや、Azure CLIも以下のように認証部分書いていたのですが、軒並み同じエラーです。

credential = ManagedIdentityCredential()
$ az login -i 

原因を調査

調査したところ、AKSでAddonを有効化すると、その分のマネージドIDが降り出されます。結果、複数のマネージドIDがマシンに紐付いた状態になっていることになります。

その上での上記の認証の呼び出し方が原因のようでした。少し補足説明します。

Addon設定前

マネージドIDが一つだけ設定されているため、マネージドIDを明示的に指定しなくても、マネージドIDが一意に特定できるため、よしなにトークン返してくれます。

f:id:yomon8:20200507220146p:plain

例えば、こんな感じでも暗黙で一意のマネージドIDが勝手に紐付いて認証できます。

credential = ManagedIdentityCredential()

Addon設定後

マネージドIDが複数作成されるため、マネージドIDを明示的に指定しないと、どのマネージドIDの認証を利用するかわかりません。

f:id:yomon8:20200507221203p:plain

実際にMC始まりのリソースグループをポータルで見ても複数のマネージドIDが存在していることが確認できます。

f:id:yomon8:20200507220558p:plain

つまり、以下のように明示的にマネージドIDを指定して認証をする必要があります。

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx はマネージドIDのGUIDになります。

  • curl
$ curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -H Metadata:true -s
  • Python
credential = ManagedIdentityCredential(client_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
  • Azure CLI
$ az login -i -u xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

今回はContainer Insightを有効化して事象が発生しましたが、他のAddonでもマネージドIDが作成されるものの場合は同じことが発生すると思います。(全部は検証してないですが・・)

最後に

もう一つだけ謎が残っています。最初に事象で書いた以下の部分です。

暫くは問題無く動いているのですが、数時間~24時間程度経過するとPodが全て失敗する自体に遭遇しました。そして無効化すると直る。

暫くは動いているという部分ですが、以下の図で言うと、⑤から⑥に依頼した際に発行されるTokenはIMDS上にキャッシュされているように見えます。実際に見てみるとAccess Tokenの期限は1日で設定されているようなので、有効化前のトークンが生きている間は問題無く動いていて、そのAccess Tokenが切れた時に問題が顕在化しているように見えます。

この部分に関しては、見えない部分があるので参考までに。

f:id:yomon8:20200508124419p:plain 引用元: Managed identities for Azure resources | Microsoft Docs

参考URL

azure-sdk-for-python/managed_identity.py at azure-identity_1.3.1 · Azure/azure-sdk-for-python · GitHub