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


このページでは、Google Kubernetes Engine(GKE)クラスタで Kubernetes API サーバーに接続するときに使用できる認証方法について説明します。

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

概要

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

始める前に

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

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

ユーザーの認証

GKE は、Google Cloud CLI を使用してエンドユーザー認証を管理します。gcloud CLI は、Google Cloud に対するユーザー認証、Kubernetes 構成の設定、クラスタの OAuth アクセス トークンの取得、アクセス トークンの更新を行います。

すべての GKE クラスタは、Google Cloud ユーザー/サービス アカウント ID を受け入れるように設定されています。受け入れる際には、kubectl から提供された認証情報を検証し、ユーザー/サービス アカウント ID に関連付けられたメールアドレスを取得します。したがって、認証に成功するには、これらのアカウントの認証情報に userinfo.email OAuth スコープが含まれている必要があります。

gcloud を使用して新しいまたは既存のクラスタ用の環境の kubeconfig をセットアップするとき、gcloud は、gcloud 自体で使用されるものと同じ認証情報を kubectl に渡します。たとえば gcloud auth login を使用する場合、userinfo.email スコープを含め、そのユーザー個人の認証情報が kubectl に渡されます。これにより、GKE クラスタは kubectl クライアントを認証できます。

または、Compute Engine インスタンス上で動作しながら、Google Cloud サービス アカウントの認証情報を使用するように kubectl を設定する方法もあります。ただし、デフォルトでは、Compute Engine インスタンスによって作成される認証情報に userinfo.email スコープが含まれません。したがって、Compute Engine インスタンスの作成時に --scopes フラグを使用するなどして、このスコープを明示的に追加する必要があります

クラスタ内でアクションを承認するには、Identity and Access Management(IAM)または Kubernetes のロールベースのアクセス制御(RBAC)を使用できます。

OAuth を使用した認証

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

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

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

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

    kubectl cluster-info
    

ユーザーまたは Google Cloud サービス アカウントが認証された後、GKE クラスタに対するアクションの実行をアカウントに許可する必要があります。認可の構成方法の詳細については、ロールベースのアクセス制御をご覧ください。

アプリケーションの認証

CI/CD パイプラインのスクリプトで認証するなど、ユーザーの操作なしで Pod 内のアプリケーションから API サーバーに対して認証することもできます。これを実現する方法は、アプリケーションが実行されている環境によって異なります。

同じクラスタ内のアプリケーション

アプリケーションが同じ GKE クラスタで実行されている場合は、Kubernetes サービス アカウントを使用して認証します。

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

  2. Kubernetes RBAC を使用して、アプリケーションに必要な権限を Kubernetes サービス アカウントに付与します。

    次の例では、名前空間がprodであるリソースに対して、サービスアカウント名がcicdで名前空間がcicd-nsへのview権限を付与します。

    kubectl create rolebinding cicd-secret-viewer \
        --namespace=prod \
        --clusterrole=view \
        --serviceaccount=cicd-ns:cicd
    
  3. 実行時に、アプリケーションが Kubernetes API リクエストを送信すると、API サーバーはサービス アカウントの認証情報を認証します。

Google Cloud 内のアプリケーション

アプリケーションが Google Cloud の内部で実行されて、かつ、ターゲット クラスタ(Compute Engine VM や別の GKE クラスタなど)の外部で実行されている場合は、その環境で利用できる IAM サービス アカウントの認証情報を使用して API サーバーに対する認証を行う必要があります。

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

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

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

    次の例では、クラスタ内の 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
    

    また、RBAC を使用して IAM サービス アカウントにクラスタへのアクセス権を付与することもできます。同じクラスタ内のアプリケーションから kubectl create rolebinding コマンドを実行し、--service-account フラグの代わりに --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com を使用します。

  3. クラスタの認証情報を取得します。

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

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

他の環境のアプリケーション

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

  1. アプリケーションの IAM サービス アカウントを作成します。IAM サービス アカウントをすでに保有している場合は、このステップをスキップします。

    次のコマンドは、ci-cd-pipeline という名前の IAM サービス アカウントを作成します。

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

    次のコマンドは、roles/container.developer IAM ロールを ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com IAM サービス アカウントに付与します。

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

    RBAC を使用して、IAM サービス アカウントにクラスタへのアクセス権を付与することもできます。同じクラスタ内のアプリケーションから kubectl create rolebinding コマンドを実行し、--service-account フラグの代わりに --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com を使用します。

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

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. アプリケーションを実行している環境で、IAM サービス アカウント キーを使用して gcloud CLI に対する認証を行います。

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

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

gcloud を使用しない環境

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

  1. アプリケーションの IAM サービス アカウントを作成します。IAM サービス アカウントをすでに保有している場合は、このステップをスキップします。

    次のコマンドは、ci-cd-pipeline という名前の IAM サービス アカウントを作成します。

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

    次のコマンドは、roles/container.developer IAM ロールを ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com IAM サービス アカウントに付与します。

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

    カスタム IAM ロールを作成して、付与する権限を詳細に制御することもできます。

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

    次の例では、鍵ファイルの名前は 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:
        exec:
          apiVersion: client.authentication.k8s.io/v1beta1
          args:
          - --use_application_default_credentials
          command: gke-gcloud-auth-plugin
          installHint: Install gke-gcloud-auth-plugin for kubectl by following
            https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin
          provideClusterInfo: true
    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. これで、アプリケーションが Kubernetes API にリクエストを送信できるようになりました。アプリケーションは IAM サービス アカウントとして認証されます。

従来の認証方法

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 が有効になっていることと、クライアント証明書がクラスタで認可されていないことを確認してください。

次のステップ