Google Compute Engine で実行されている Kubernetes ポッドがメタデータ サービスにアクセスできない

Google Compute Engine で実行されている Kubernetes ポッドがメタデータ サービスにアクセスできない

Google コンピューティング エンジンで実行されている k8 ポッド内から Google Cloud Python SDK を実行しようとしています。VM にはサービス アカウントが接続されており、シークレット マネージャーへのアクセスを許可しています。ホストからシークレット マネージャーにアクセスできますが、k8 ポッドから Python SDK を実行すると、メタデータ サービスにアクセスできないというエラーが表示されます。

>>> secret_id = 'unskript_test'
>>> name = client.secret_path(project_id, secret_id)
>>> response = client.get_secret(request={"name": name})
Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 67, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/opt/conda/lib/python3.7/site-packages/grpc/_channel.py", line 946, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/opt/conda/lib/python3.7/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "Getting metadata from plugin failed with error: Failed to retrieve http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true from the Google Compute Enginemetadata service. Compute Engine Metadata server unavailable"
    debug_error_string = "{"created":"@1630634901.103779641","description":"Getting metadata from plugin failed with error: Failed to retrieve http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true from the Google Compute Enginemetadata service. Compute Engine Metadata server unavailable","file":"src/core/lib/security/credentials/plugin/plugin_credentials.cc","file_line":90,"grpc_status":14}"
>

metadata.google.internal は k8 pod から解決されません

jovyan@jovyan-25ca6c8c-157d-49e5-9366-f9d57fcb7a9f:~$ wget http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
--2021-09-03 02:11:19--  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
Resolving metadata.google.internal (metadata.google.internal)... failed: Name or service not known.
wget: unable to resolve host address ‘metadata.google.internal’

しかし、ホストはそれを解決することができます

ubuntu@gcp-test-proxy:~$ wget http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
--2021-09-03 02:11:27--  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
Resolving metadata.google.internal (metadata.google.internal)... 169.254.169.254
Connecting to metadata.google.internal (metadata.google.internal)|169.254.169.254|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2021-09-03 02:11:27 ERROR 403: Forbidden.

ポッドに metadata.google.internal を解決させるにはどうすればよいですか?

答え1

これは、Kubernetes ポッドが DNS 名を適切な IP に解決できないために発生します。ホスト マシンには、そのドメインを IP: 169.254.169.254 にハードコードするmetadata.google.internalエントリがある可能性があります。/etc/hosts

ファイルを変更することで、それを Pod 内で複製できるはずです/etc/hosts

ただし、これは GCP 上で実行されている VM でのみ機能することを覚えておいてください。外部では、IP アドレス 169.254.169.254 は特別な意味を持たない単なる IP アドレスです。

編集: GCP VM の 1 つで /etc/hosts をチェックしたところ、次のことがわかりました。

$ cat /etc/hosts
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
169.254.169.254 metadata.google.internal metadata

したがって、最後の行をポッドにコピーしてみてください/etc/hosts

答え2

問題は、microk8sがホストなどのホストエントリをポッドにコピーしないことでした。k3に移行すると解決しました。

関連情報