web-dev-qa-db-ja.com

GKEクラスタが同じプロジェクトのGCRレジストリから(ErrImagePull)をプルできない(GitLab Kubernetes Integration):なぜですか?

そのため、少しグーグルした後(プルシークレットで問題が発生しているユーザーによって汚染されています)、これをここに投稿します。また、GCPサポート(聞いたとおりに更新されます)に投稿します。

GitLab Kubernetes統合(ドキュメント: https://about.gitlab.com/solutions/kubernetes )から、GCRレジストリ/イメージと同じプロジェクト内にクラスターを作成しました。

Kubectl(このプロジェクトのGCRレジストリ内のプライベートイメージに依存)を使用してこのクラスターに新しいサービス/デプロイメントを追加すると、GitLabで作成されたクラスターのポッドは、ErrImagePullを使用してGCRからプルできません。

明確にするために、私はGitLabプライベートレジストリからプルしていません。GitLabから作成されたGKEクラスターと同じプロジェクト内のGCRレジストリからプルしようとしています(プルシークレットは必要ありません)。

このプロジェクト内の他のクラスター(GCP Consoleから作成)は同じイメージに適切にアクセスできるため、APIを使用して作成されたクラスター(この場合はGitLabから)とGCP Consoleから作成されたクラスターには多少の違いがあると思います。

私は過去に誰かがこれに遭遇したことを願っています-または、問題を引き起こしている可能性があるサービスアカウントなどの違いを説明できます。

サービスアカウントを作成し、プロジェクト閲覧者の役割を手動で付与して、問題が解決するかどうかを確認します。

更新:手動で構成されたサービスアカウントは問題を解決しませんでした。

注:イメージをクラスターにプルしようとしていますが、クラスターで実行されているGitLabランナーにはプルしていません。つまり。 GitLabインフラストラクチャと一緒に別のサービス/デプロイメントを実行したい

8
Necevil

TL; DR — GitLab-Ci Kubernetes Integrationによって作成されたクラスターは、ノードの権限(スコープ)を変更しないと、コンテナーイメージと同じプロジェクトのGCRレジストリからイメージをプルできません。

デフォルトでは、GitLab-CiのKubernetes統合によって作成されたクラスター自体によって作成されたクラスターノードは、Google Cloudサービスへの最小限の権限(スコープ)で作成されます。

これは、クラスターのGCP Consoleダッシュボードから視覚的に確認でき、権限セクションまで下にスクロールして、「ストレージ」を探します。

enter image description here

つまり、GitLab-Ci Kubernetes統合クラスター内で実行されているノードには、GCRレジストリからイメージをプルするために必要なデフォルトのGCRレジストリ(読み取り専用)権限がないことになります。

また、(私が知る限り)サービスアカウントにGCRレジストリへの適切なアクセス権を付与しても機能しないことも意味します。サービスアカウントを適切に設定したかどうかは完全にはわかりませんが、そうしたと思います。

すごい。

権限を修正する方法

基本的に2つのオプションがあります。最初の方法は、クラスターを作成することです(つまり、GitLab Kubernetes Integrationの外部で)。次に、ここにある手動で「既存のクラスターに接続する」の指示に従ってGitLabプロジェクトをそのクラスターに再接続します。 https://gitlab.com/help/user/project/clusters/index#adding-an-existing-kubernetes-cluster

2番目のオプションは、権限を変更することですが、それはより複雑です。

6
Necevil

TL; DR— GitLab-Ci Kubernetes Integrationによって作成されたクラスターは、コンテナーイメージと同じプロジェクトのGCRレジストリからイメージをプルできません—ノードの権限(スコープ)を変更せずに。

個々のNode machine(s)の権限を手動で変更して、アプリケーションのデフォルト認証情報を付与することができます(参照: https://developers.google.com/identity/protocols/application-default-credentials )適切なスコープをリアルタイムで—この方法でこれを行うと、ノードが将来のある時点で再作成された場合、変更されたスコープがなくなり、問題が発生します。

権限を手動で変更する代わりに、必要なGCPサービスにアクセスするための適切なスコープを持つ新しいNodeプールを作成します。

参考のために使用したいくつかのリソースを以下に示します。

  1. https://medium.com/google-cloud/updating-google-container-engine-vm-scopes-with-zero-downtime-50bff87e5f8
  2. https://adilsoncarvalho.com/changing-a-running-kubernetes-cluster-permissions-a-k-a-scopes-3e90a3b95636

適切にスコープされたNodeプールを作成する

gcloud container node-pools create [new pool name] \
 --cluster [cluster name] \
 --machine-type [your desired machine type] \
 --num-nodes [same-number-nodes] \
 --scopes [your new set of scopes]

必要なスコープの名前がわからない場合—スコープとスコープエイリアスの完全なリストは、こちらからご覧いただけます: https://cloud.google.com/sdk/gcloud/reference/container/node-pools/create

私にとっては、gke-default(他のクラスターと同じ)とsql-adminを行いました。これは、ビルドの一部でCloud SQLのSQLデータベースにアクセスできる必要があり、そのためにパブリックIPに接続する必要がないためです。

gke-defaultスコープ(参照用)

  1. https://www.googleapis.com/auth/devstorage.read_only (プルすることができます)
  2. https://www.googleapis.com/auth/logging.write
  3. https://www.googleapis.com/auth/monitoring
  4. https://www.googleapis.com/auth/service.management.readonly
  5. https://www.googleapis.com/auth/servicecontrol
  6. https://www.googleapis.com/auth/trace.append

上記を、GitLab-Ciで作成されたクラスターからのよりロックされたアクセス許可と比較してください(これらの2つのみ https://www.googleapis.com/auth/logging.writehttps:/ /www.googleapis.com/auth/monitoring ):

必要な最低限のアクセス許可のみにクラスターを構成することは、確実にここに進むためのものです。それが何であるかを理解し、適切にスコープされた新しいNode Pool ...を作成したら...

以下を使用してノードをリストします。

kubectl get nodes

先ほど作成したもの(最新)は新しい設定ですが、古いオプションはGCRからプルできるデフォルトのgitlabクラスターです。

次に:

kubectl cordon [your-node-name-here]

その後、ドレインしたい:

kubectl drain [your-node-name-here] --force

GitLab Runnerがインストールされているという事実が、ポッドを制御するために使用されたローカルデータ/デーモンセットが原因で、ポッドを正常にドレインできないという問題に遭遇しました。

そのため、私がNodeをコード化すると、ノードをKubectlから削除しただけです(これが問題の原因になるかどうかはわかりませんが、私にとっては問題ありませんでした)。ノードが削除されると、 GitLabによって作成された「default-pool」ノードプールを削除します。

ノードプールを一覧表示します。

gcloud container node-pools list --cluster [CLUSTER_NAME]

Gitlabによって作成された古いスコープを確認します。

gcloud container node-pools describe default-pool \
    --cluster [CLUSTER_NAME]

正しい新しいスコープ(追加したばかり)があるかどうかを確認します。

gcloud container node-pools describe [NEW_POOL_NAME] \
    --cluster [CLUSTER_NAME]

新しいNodeプールに適切なスコープがある場合、デプロイメントは次のコマンドでデフォルトのプールを削除できます。

gcloud container node-pools delete default-pool \
   --cluster <YOUR_CLUSTER_NAME> --zone <YOUR_ZONE>

私の個人的なケースでは、プライベートネットワークへのアクセスを許可する方法(つまり、プライベートIPを介してCloud SQLにアクセスする方法)を見つけようとしていますが、今は画像をプルできるので、途中です。

それだけだと思います。数分節約できたことを願っています。

11
Necevil