Kubernetes API サーバーに対する認証

このページでは、Google Kubernetes Engine(GKE)で Kubernetes API サーバーに接続するときにサポートされている認証方法について説明します。

Google Cloud APIs に対する Kubernetes ワークロードの認証については、Workload Identity をご覧ください。

概要

Kubernetes API サーバーに対する認証方法はいくつかあります。GKE では、OAuth 認証がクラスタ認証に推奨されており、自動的に構成されます。

始める前に

作業を始める前に、次のことを確認してください。

次のいずれかの方法で gcloud のデフォルトの設定を指定します。

  • gcloud init。デフォルトの設定全般を確認する場合に使用します。
  • gcloud config。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。

gcloud init の使用

エラー One of [--zone, --region] must be supplied: Please specify location を受信した場合は、このセクションの内容を実施します。

  1. gcloud init を実行して、次の操作を行います。

    gcloud init

    リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

    gcloud init --console-only
  2. 手順に従って gcloud を承認し、Google Cloud アカウントを使用します。
  3. 新しい構成を作成するか、既存の構成を選択します。
  4. Google Cloud プロジェクトを選択します。
  5. ゾーンクラスタの場合はデフォルトの Compute Engine ゾーン、リージョン クラスタまたは Autopilot クラスタの場合はデフォルトの Compute Engine リージョンを選択します。

gcloud config の使用

  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project PROJECT_ID
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone COMPUTE_ZONE
  • Autopilot クラスタまたはリージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region COMPUTE_REGION
  • gcloud を最新バージョンに更新します。
    gcloud components update

ユーザー認証

GKE は、gcloud コマンドライン ツールを使用してエンドユーザー認証を管理します。gcloud ツールは、Google Cloud に対するユーザー認証、Kubernetes 構成の設定、クラスタの OAuth アクセス トークンの取得、アクセス トークンの更新を行います。Identity and Access Management(IAM)または Kubernetes ロールベースのアクセス制御(RBAC)を使用して、クラスタへのアクセスを制御できます。

OAuth を GKE と統合する前は、事前にプロビジョニングされた X.509 証明書または静的パスワードが唯一の利用可能な認証方法でした。現在これらの方法は推奨されておらず、GKE バージョン 1.12 以降の新しいクラスタではデフォルトで無効になっています。以前の認証方法を使用している場合は、これらの方法を移行することをおすすめします。

OAuth を使用した認証

OAuth メソッドを使用してクラスタに対する認証を行うには、次の手順に従います。

  1. 認証情報を使用して gcloud ツールにログインします。そうすることでウェブブラウザが開き、Google Cloud への認証プロセスが完了します。

    gcloud auth login
    
  2. 特定のクラスタの Kubernetes 認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    
  3. 認証されていることを確認します。

    kubectl cluster-info
    

サービスの認証

ユーザーの操作を経ることなく、サービスから GKE クラスタの API サーバーに対する認証が必要になる場合があります(CI また CD のパイプライン スクリプトなど)。これを実現する方法は サービスが実行されている環境によって異なります。

同一 GKE クラスタ内のサービス

接続する GKE クラスタ内の Pod でサービスが実行されている場合は、Kubernetes サービス アカウントを使用して認証します。

  1. Kubernetes サービス アカウントを作成し、Pod に接続します。Pod に Kubernetes サービス アカウントがすでにある場合、このステップはスキップできます。

    この例では、cicd-ns 名前空間で cicd という名前の Kubernetes サービス アカウントを使用します。

  2. Kubernetes RBAC を使用して、Kubernetes サービス アカウントに正しい権限を付与します。

    次の例では、prod 名前空間に edit 権限を付与します。

    kubectl create rolebinding cicd \
        --clusterrole=edit \
        --serviceaccount=cicd-ns:cicd \
        --namespace=prod
    
  3. 実行時に、サービスが kubectl を呼び出すと、構成した認証情報が自動的に受信されます。

Google Cloud 内のサービス

サービスが Google Cloud 内で実行されている場合(Compute Engine VM や別の GKE クラスタなど)、環境で利用可能な Google サービス アカウント認証情報を使用して API サーバーを認証します。

  1. Compute Engine 環境に Google サービス アカウントを割り当てます。サービスが Compute Engine VM 内で実行されている場合は、インスタンスにGoogle サービス アカウントを割り当てます。サービスが GKE クラスタ内で実行されている場合は、Workload Identity を使用して、Google サービス アカウントとして実行されるように Pod を構成します。

    この例では、Google サービス アカウントとして ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com を使用しています。

  2. Google サービス アカウントにクラスタへのアクセス権を付与します。

    この例では、クラスタ内で Kubernetes API オブジェクトへのアクセスを提供する roles/container.developer Cloud IAM ロールを付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    
  3. クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

    サービスは、環境に設定された Google サービス アカウントを使用して自動的に認証されます。

他の環境でのサービス

サービスが Google Cloud 以外の環境から認証されている場合、マネージド Google サービス アカウントの認証情報にはアクセスできません。クラスタの認証情報を取得するには、Google サービス アカウントの作成、そのキーのダウンロードを行い、実行時にサービスからキーを使用して、gcloud ツールでクラスタの認証情報を取得する必要があります。

  1. サービスの Google サービス アカウントを作成します。Google サービス アカウントがすでにある場合は、この手順を省略できます。

    この例では、ci-cd-pipeline という名前のサービス アカウントを作成します。

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. Google サービス アカウントにクラスタへのアクセス権を付与します。

    この例では、Google サービス アカウントとして ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com を使用し、クラスタ内の Kubernetes API オブジェクトへのアクセスを提供する roles/container.developer IAM ロールを付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    このアクセス権を Kubernetes RBAC を使用して付与し、より詳細な制御を行うこともできます。

  3. Google サービス アカウントのキーを作成してダウンロードし、実行時にサービスで使用できるようにします。

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. サービスを実行している環境で、Google サービス アカウント キーを使用して gcloud ツールの認証を行います。

    gcloud auth activate-service-account ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --key-file=gsa-key.json
    
  5. gcloud ツールを使用してクラスタの認証情報を取得します。

    gcloud config set project PROJECT_ID
    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

gcloud を使用しない環境

gcloud ツールを使用してクラスタ認証情報を取得することをおすすめします。この方法は、コントロール プレーンの IP ローテーション認証情報のローテーションなどのクラスタ イベントの影響を受けにくいためです。ただし、環境に gcloud ツールをインストールできない場合でも、静的な kubeconfig ファイルを作成してクラスタを認証できます。

  1. サービスの Google サービス アカウントを作成します。Google サービス アカウントがすでにある場合は、この手順を省略できます。

    この例では、ci-cd-pipeline という名前のサービス アカウントを作成します。

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. Google サービス アカウントにクラスタへのアクセス権を付与します。

    この例では、Google サービス アカウントとして ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com を使用し、クラスタ内の Kubernetes API オブジェクトへのアクセスを提供する roles/container.developer IAM ロールを付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    このアクセス権を Kubernetes RBAC を使用して付与し、より詳細な制御を行うこともできます。

  3. Google サービス アカウントのキーを作成してダウンロードします。

    この例では、キーファイルの名前は gsa-key.json です。

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. クラスタの endpointclusterCaCertificate の値を取得します。

    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
         --format="value(endpoint)"
    
    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --format="value(masterAuth.clusterCaCertificate)"
    
  5. 以下を含む kubeconfig.yaml ファイルを作成します。

    apiVersion: v1
    kind: Config
    clusters:
    - name: CLUSTER_NAME
      cluster:
        server: https://endpoint
        certificate-authority-data: masterAuth.clusterCaCertificate
    users:
    - name: ci-cd-pipeline-gsa
      user:
        auth-provider:
          name: gcp
    contexts:
    - context:
        cluster: CLUSTER_NAME
        user: ci-cd-pipeline-gsa
      name: CLUSTER_NAME-ci-cd
    current-context: CLUSTER_NAME-ci-cd
    

    以下を置き換えます。

    • CLUSTER_NAME: クラスタの名前。
    • endpoint: 前のステップで取得した endpoint の値。
    • masterAuth.clusterCaCertificate: 前のステップで取得した clusterCaCertificate の値(base64 でエンコードされた証明書をデコードする必要はありません)。
  6. 環境内のサービスと合わせて kubeconfig.yamlgsa-key.json をデプロイします。サービスを実行する環境で、次の環境変数を設定します。

    export KUBECONFIG=path/to/kubeconfig.yaml
    export GOOGLE_APPLICATION_CREDENTIALS=path/to/gsa-key.json
    
  7. これで、サービスが kubectl を呼び出せるようになり、Google サービス アカウントとして認証されます。

従来の認証方法

GKE と OAuth を統合する前は、事前にプロビジョニングされた X.509 証明書または静的パスワードが唯一の利用可能な認証方法でしたが、現在これらの方法は推奨されておらず、無効にする必要があります。これらの方法は、クラスタの侵害に対する攻撃の範囲が広く、GKE バージョン 1.12 以降で実行しているクラスタでは、デフォルトで無効になっています。以前の認証方法を使用している場合は、無効にすることをおすすめします。

有効にすると、container.clusters.getCredentials 権限を持つユーザーはクライアント証明書と静的パスワードを取得できます。roles/container.adminroles/ownerroles/editor の各ロールにこの権限があるため、これらのロールは慎重に使用してください。詳細については、GKE での IAM のロールをご覧ください。

静的パスワードによる認証の無効化

静的パスワードとは、API サーバーが検証するユーザー名とパスワードの組み合わせです。GKE では、この認証方法は基本認証と呼ばれます。

既存のクラスタを更新して静的パスワードを削除するには、次のコマンドを実行します。

gcloud container clusters update CLUSTER_NAME --no-enable-basic-auth

クライアント証明書による認証の無効化

証明書認証では、クライアントが提示する証明書を、指定された認証局で API サーバーが検証します。GKE では、クラスタルート認証局(CA)がクライアント証明書に署名します。

クライアント証明書による認証は、Kubernetes API サーバーに対する認可に影響します。従来の属性ベースのアクセス制御(ABAC)による認可がクラスタで有効になっている場合、クライアント証明書はデフォルトで認証され、API サーバーで任意のアクションを実行できます。一方、ロールベースのアクセス制御(RBAC)を有効にしている場合は、クライアント証明書に Kubernetes リソースに対する特定の権限を付与する必要があります。

クライアント証明書を生成せずにクラスタを作成するには、--no-issue-client-certificate フラグを使用します。

gcloud container clusters create CLUSTER_NAME \
    --no-issue-client-certificate

現在、既存のクラスタからクライアント証明書を削除する方法はありません。既存のクラスタでクライアント証明書による認証を停止するには、クラスタで RBAC が有効になっていることと、クライアント証明書がクラスタで認可されていないことを確認してください。

次のステップ