このページでは、Google Kubernetes Engine(GKE)の使用時に発生する可能性のある 400、401、403、404 エラーを解決する方法について説明します。
問題: 認証と認可のエラー
GKE クラスタに接続すると、HTTP ステータス コード 401 (Unauthorized)
の認証 / 認可エラーが発生することがあります。この問題は、ローカル環境から GKE クラスタで kubectl
コマンドを実行しようとしたときに発生することがあります。
この問題の原因は、次のいずれかである可能性があります。
gke-gcloud-auth-plugin
認証プラグインが正しくインストールされていないか、構成されていません。- クラスタ API サーバーに接続し、
kubectl
コマンドを実行するための権限がありません。
原因を診断するには、次のセクションの手順を行います。
curl
を使用してクラスタに接続する
認証と認可のエラーの原因を診断するには、curl
を使用してクラスタに接続します。curl
を使用すると、kubectl
コマンドライン ツールと gke-gcloud-auth-plugin
プラグインがバイパスされます。
環境変数を設定します。
APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION --format "value(endpoint)") TOKEN=$(gcloud auth print-access-token)
アクセス トークンが有効であることを確認します。
curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
有効なアクセス トークンがある場合、このコマンドは Google の OAuth 2.0 サーバーにリクエストを送信し、サーバーはトークンに関する情報で応答します。
API サーバーのコア API エンドポイントに接続してみます。
# Get cluster CA certificate gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --format "value(masterAuth.clusterCaCertificate)" | \ base64 -d > /tmp/ca.crt # Make API call with authentication and CA certificate curl -s -X GET "${APISERVER}/api/v1/namespaces" \ --header "Authorization: Bearer $TOKEN" \ --cacert /tmp/ca.crt
curl
コマンドが成功すると、Namespace のリストが表示されます。kubeconfig でプラグインを構成するのセクションの手順に沿って、プラグインが原因かどうかを確認します。curl
コマンドが次のような出力で失敗した場合は、クラスタにアクセスするための適切な権限がありません。{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
この問題を解決するには、クラスタにアクセスするための適切な権限を管理者に確認してください。
kubeconfig でプラグインの使用を構成する
クラスタに接続するときに認証と認可のエラーが発生し、curl
を使用してクラスタに接続できた場合は、gke-gcloud-auth-plugin
プラグインを使用せずにクラスタにアクセスできることを確認します。
この問題を解決するには、クラスタの認証時に gke-gcloud-auth-plugin
バイナリを無視するようにローカル環境を構成します。バージョン 1.25 以降を実行している Kubernetes クライアントでは、gke-gcloud-auth-plugin
バイナリが必須であるため、kubectl
コマンドライン ツールにはバージョン 1.24 以前を使用する必要があります。
プラグインを使用せずにクラスタにアクセスする手順は次のとおりです。
curl
を使用して、バージョン 1.24 以前のkubectl
コマンドライン ツールをインストールします。次の例では、バージョン 1.24 のツールをインストールします。curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
テキスト エディタでシェル起動スクリプト ファイルを開きます。たとえば、Bash シェルの
.bashrc
を開きます。vi ~/.bashrc
macOS を使用している場合は、これらの手順で
.bashrc
ではなく~/.bash_profile
を使用します。起動スクリプト ファイルに次の行を追加して保存します。
export USE_GKE_GCLOUD_AUTH_PLUGIN=False
起動スクリプトを実行します。
source ~/.bashrc
クラスタの認証情報を取得します。これにより、
.kube/config
ファイルが設定されます。gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。COMPUTE_LOCATION
: Compute Engine のロケーション。
kubectl
コマンドを実行します。次に例を示します。kubectl cluster-info
これらのコマンドを実行した後に 401 エラーまたは同様の認証エラーが発生した場合は、適切な権限があることを確認し、エラーを返した手順を再実行します。
エラー 400: ノードプールの再作成が必要
コントロール プレーンとノードを再作成するアクションを実行しようとすると、次のエラーが発生することがあります。
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.
たとえば、進行中の認証情報のローテーションが完了したときに、このエラーが発生することがあります。
バックエンドでは、ノードプールが再作成対象としてマークされていますが、実際の再作成オペレーションの開始には時間がかかることがあります。このため、GKE がクラスタ内の 1 つ以上のノードプールをまだ再作成していないため、オペレーションが失敗します。
この問題を解決するには、次のいずれかの解決策を選択します。
- 再作成が完了するまで待ちます。既存のメンテナンスの時間枠や除外などの要因に応じて、完了までに数時間、数日、あるいは数週間かかることがあります。
コントロール プレーンと同じバージョンへのアップグレードを開始して、影響を受けるノードプールの再作成を手動で開始します。
再作成を開始するには、次のコマンドを実行します。
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME
アップグレードが完了したら、操作をやり直してください。
エラー 401: Unauthorized
GKE は、ノードに接続されている IAM サービス アカウントを使用して、ロギングやモニタリングなどのシステムタスクを実行します。少なくとも、これらのノード サービス アカウントには、プロジェクトに対する Kubernetes Engine デフォルト ノード サービス アカウント(roles/container.defaultNodeServiceAccount
)ロールが必要です。デフォルトでは、GKE はプロジェクトで自動的に作成される Compute Engine のデフォルトのサービス アカウントをノード サービス アカウントとして使用します。
組織で iam.automaticIamGrantsForDefaultServiceAccounts
組織のポリシー制約が適用されている場合、プロジェクトのデフォルトの Compute Engine サービス アカウントに GKE に必要な権限が自動的に付与されないことがあります。
-
ノードが使用するサービス アカウントの名前を確認します。
console
- [Kubernetes クラスタ] ページに移動します。
- クラスタリストで、検査するクラスタの名前をクリックします。
- クラスタの運用モードに応じて、次のいずれかを行います。
- Autopilot モードのクラスタの場合は、[セキュリティ] セクションで [サービス アカウント] フィールドを見つけます。
- Standard モード クラスタの場合は、次の操作を行います。
- [ノード] タブをクリックします。
- [ノードプール] テーブルで、ノードプールの名前をクリックします。[ノードプールの詳細] ページが開きます。
- [セキュリティ] セクションで、[サービス アカウント] フィールドを見つけます。
[サービス アカウント] フィールドの値が
default
の場合、ノードは Compute Engine のデフォルトのサービス アカウントを使用します。このフィールドの値がdefault
でない場合、ノードはカスタム サービス アカウントを使用します。カスタム サービス アカウントに必要なロールを付与するには、最小権限の IAM サービス アカウントを使用するをご覧ください。gcloud
Autopilot モードのクラスタの場合は、次のコマンドを実行します。
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccountStandard モードのクラスタの場合は、次のコマンドを実行します。
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --format="table(nodePools.name,nodePools.config.serviceAccount)"出力が
default
の場合、ノードは Compute Engine のデフォルトのサービス アカウントを使用します。出力がdefault
でない場合、ノードはカスタム サービス アカウントを使用しています。必要なロールをカスタム サービス アカウントに付与するには、最小権限の IAM サービス アカウントを使用するをご覧ください。 -
Compute Engine のデフォルト サービス アカウントに
roles/container.defaultNodeServiceAccount
ロールを付与する手順は次のとおりです。console
- [ようこそ] ページに移動します。
- [プロジェクト番号] フィールドで、 [クリップボードにコピー] をクリックします。
- [IAM] ページに移動します。
- [ アクセスを許可] をクリックします。
- [新しいプリンシパル] フィールドに次の値を指定します。
PROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_NUMBER
は、コピーしたプロジェクト番号に置き換えます。 - [ロールを選択] メニューで、[Kubernetes Engine のデフォルト ノード サービス アカウント] ロールを選択します。
- [保存] をクリックします。
gcloud
- Google Cloud プロジェクト番号を確認します。
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
PROJECT_ID
を実際のプロジェクト ID に置き換えます。出力は次のようになります。
12345678901
- Compute Engine のデフォルト サービス アカウントに
roles/container.defaultNodeServiceAccount
ロールを付与します。gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/container.defaultNodeServiceAccount"
PROJECT_NUMBER
は、前の手順で取得したプロジェクト番号に置き換えます。
エラー 403: 十分な権限がない
gcloud container clusters get-credentials
を使用して GKE クラスタに接続しようとしたときに、アカウントに Kubernetes API サーバーにアクセスする権限がないと、次のエラーが発生します。
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".
この問題を解決するには、次の操作を行います。
アクセスの問題が発生しているアカウントを特定します。
gcloud auth list
Kubernetes API サーバーの認証の手順に沿って、アカウントに必要なアクセス権を付与します。
エラー 403: 再試行の予算が不足しています
GKE クラスタを作成しようとすると、次のエラーが発生することがあります。
Error: googleapi: Error 403: Retry budget exhausted: Google Compute Engine:
Required permission 'PERMISSION_NAME' for 'RESOURCE_NAME'.
このエラー メッセージでは、次の変数が適用されます。
PERMISSION_NAME
: 権限の名前(compute.regions.get
など)。RESOURCE_NAME
: アクセスしようとした Google Cloud リソースのパス(Compute Engine リージョンなど)。
このエラーは、クラスタに接続されている IAM サービス アカウントに、クラスタの作成に必要な最小限の権限がない場合に発生します。
この問題を解決するには、次の操作を行います。
- GKE クラスタを実行するために必要なすべての権限を持つ IAM サービス アカウントを作成または変更します。手順については、最小権限の IAM サービス アカウントを使用するをご覧ください。
--service-account
フラグを使用して、クラスタ作成コマンドで更新された IAM サービス アカウントを指定します。手順については、Autopilot クラスタを作成するをご覧ください。
または、--service-account
フラグを省略して、GKE がプロジェクト内の Compute Engine のデフォルトのサービス アカウントを使用するようにします。このアカウントには、デフォルトで必要な権限が付与されています。
エラー 404: リソースが見つかりません
gcloud container
コマンドを呼び出したときにエラー 404(リソースが見つかりません)が発生した場合は、Google Cloud CLI で再認証して問題を解決します。
gcloud auth login
エラー 400/403: アカウントに編集権限がありません
アカウントに対する編集権限がないエラー(エラー 400 または 403)は、次のいずれかが手動で削除または編集されたことを示します。
Compute Engine または Kubernetes Engine API を有効にすると、Google Cloud は次のサービス アカウントとエージェントを作成します。
- プロジェクトの Compute Engine のデフォルトのサービス アカウント。GKE は、ロギングやモニタリングなどのシステムタスク用に、デフォルトでこのサービス アカウントをノードに接続します。
- Google 管理のプロジェクト内の Google API サービス エージェント。プロジェクトに対する編集権限が必要です。
- Google マネージド プロジェクト内の Google Kubernetes Engine サービス エージェント。プロジェクトに対する Kubernetes Engine サービス エージェントのロールが必要です。
いずれかの時点で、これらの権限の編集、プロジェクトのロール バインディングの削除、サービス アカウントの完全削除、API の無効化が行われると、クラスタの作成とすべての管理が失敗します。
GKE サービス エージェントの権限を確認する
Google Kubernetes Engine サービス アカウントにプロジェクトに対する Kubernetes Engine サービス エージェントのロールが割り当てられているかどうかを確認するには、次の操作を行います。
Google Kubernetes Engine サービス アカウントの名前を確認します。すべてのサービス アカウントの形式は次のとおりです。
service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
PROJECT_NUMBER
は、使用するプロジェクト番号に置き換えます。Google Kubernetes Engine サービス アカウントにプロジェクトに対する Kubernetes Engine サービス エージェントのロールが割り当てられていないことを確認します。
gcloud projects get-iam-policy PROJECT_ID
PROJECT_ID
を実際のプロジェクト ID に置き換えます。
この問題を解決するには、Google Kubernetes Engine サービス アカウントから Kubernetes Engine サービス エージェントのロールを削除している場合、もう一度追加します。ロールを削除していない場合は、次の手順に沿って Kubernetes Engine API を再度有効にします。これにより、サービス アカウントと権限が復元されます。
Console
Google Cloud コンソールの [API とサービス] ページに移動します。
プロジェクトを選択します。
[API とサービスを有効化] をクリックします。
Kubernetes を検索して、検索結果から API を選択します。
[有効にする] をクリックします。API をすでに有効にしている場合は、まずそれを無効にしてから再度有効にする必要があります。API と関連サービスが有効になるには、数分かかることがあります。
gcloud
gcloud CLI で次のコマンドを実行します。
PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID"
--format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
次のステップ
さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。