AWSコンソール画面でKubernetesのリソースが表示されない件

皆さん、こんにちは。技術開発グループのn-ozawanです。
かつてベネズエラ政府は自国の食糧難に対して、国民にウサギを食料として飼育させるために、各家庭にウサギを配布しました。ただ、ベネズエラではウサギを食用とする文化がなかったので、配布された国民はそのままペットとしてウサギを可愛がったそうです。

本題です。
前回、TerraformでEKSを構築する方法を紹介しました。ただ前回までの方法ではAWSコンソール画面からKubernetesのPodなどのリソースが参照できない問題があります。今回はその問題の解消方法を紹介します。

AWSコンソールでEKSの内容が見れない問題

事象

前回紹介したコードでEKSを構築すると、EKSクラスタは構築されるのですが、いざAWSコンソール画面でKubernetesのリソースを見ようとすると、以下のメッセージが表示されてリソースなどの情報を見ることが出来ません。

原因

メッセージ通りですが、AWSコンソールにログインしているユーザに、Kubernetesのリソースを参照する権限がないのが原因です。

Kubernetesのリソースを参照するために必要な権限は以下の2つになります。

・AWS側の権限
AWSコンソール画面にログインしているユーザに対して、EKSリソースへの参照権限を持つポリシーがアタッチされているかどうか

・Kubernetes側の権限
Kubernetesにアクセスしているユーザに対して、Kubernetesのリソースへの参照権限があるかどうか

この問題は上記2つの権限がないことが原因です。2つとも必要であり、前者はAWS IAMでポリシーを見直し、後者はKubernetesの認証設定を見直す必要があります。

解消方法

この問題の解消方法ですが、実はEKSのユーザーガイド「Kubernetesリソースを表示する」にしっかりと明記されています。ざっくり解説すると以下の手順になります。

1.IAMでポリシーを設定しましょう。
2.Kubernetesのリソースを表示するための、Kubernetesのロールを作成しましょう。
3.Kubernetesへ参照可能な、IAMユーザもしくはIAMロールを追加しましょう。

上記手順の1は、AWS側の権限を設定する手順が明記されています。手順2と3は、Kubernetes側の権限を設定する手順が明記されています。

EKSユーザーガイドにはKubernetesのコマンドを利用した解消方法が記載されており、Terraformを利用した解消方法は記載されていません。では、Terraformで解消する場合はどうすればよいのでしょうか?以降はその方法の紹介となります。
※手順1はIAMでポリシーをアタッチするだけなので、今回の説明は省きます。

TerraformでKubernetesロールを作成する

手順2にあるKubernetesロールの作成にはkubernetes_cluster_rolekubernetes_cluster_role_bindingの2つのリソースを利用します。また、Kubernetesロールの内容は、AWSからYamlファイルが公開(※)されていますので、それを参考にコーディングします。

※先ほど紹介したEKSユーザーガイドのページを参照してください。
※ここの話はKubernetes側の権限(RBAC認可)の話になります。
 KubernetesのRBAC認可について詳しく知りたい方はKubernetesの公式ページを参照してください。

まずkubernetes_cluster_roleでKubernetesのロールを作成します。

resource "kubernetes_cluster_role" "eks-console-dashboard-full-access-clusterrole" {
  metadata {
    name = "eks-console-dashboard-full-access-clusterrole"
  }

  rule {
    api_groups = [""]
    resources  = ["nodes", "namespaces", "pods", "configmaps", "endpoints", "events", "limitranges", "persistentvolumeclaims", "persistentvolumes", "podtemplates", "replicationcontrollers", "resourcequotas", "secrets", "serviceaccounts", "services"]
    verbs      = ["get", "list"]
  }

  # (以下省略...)
}

metadata.nameにはロールの名前を指定します。ruleブロックにはYamlファイルに記述されているapi_groupsresourcesverbsを記載していきます。ruleは複数個ありますので、同様にすべてのruleをコーディングします。

次に、先ほどKubernetesロールの作成で定義した権限を、ユーザーまたはグループに付与します。

resource "kubernetes_cluster_role_binding" "eks-console-dashboard-full-access-binding" {
  metadata {
    name = "eks-console-dashboard-full-access-binding"
  }
  role_ref {
    kind      = "ClusterRole"
    name      = "eks-console-dashboard-full-access-clusterrole"
    api_group = "rbac.authorization.k8s.io"
  }
  subject {
    kind      = "Group"
    name      = "eks-console-dashboard-full-access-group"
    api_group = "rbac.authorization.k8s.io"
  }
}

metadata.nameはこのリソースの名前です。subjectブロックには付与したいユーザーもしくはグループを指定します。今回はグループを指定します。role_refブロックには付与するロールを指定します。先ほど作成したロールになります。

以上で、解消方法の手順2のTerraformコード化は完了です。

TerraformでConfigMapを編集する

解消方法の手順3に「Kubernetesへ参照可能な、IAMユーザもしくはIAMロールを追加」とありますが、具体的にはKubernetesクラスタのConfigMapの1つである「aws-auth」を編集します。KubernetesのConfigMapを作成もしくは編集する場合はkubernetes_config_map_v1_dataリソースを利用します。

data "aws_caller_identity" "current" {}

resource "kubernetes_config_map_v1_data" "aws-auth" {
  metadata {
    name      = "aws-auth"
    namespace = "kube-system"
  }

  data = {
    "mapRoles" = yamlencode(
      [
        {
          rolearn: "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/fargate-profile-role"
          username: "system:node:{{SessionName}}"
          groups: [ "system:bootstrappers", "system:nodes", "system:node-proxier" ]
        }
      ]
    )
    mapUsers = yamlencode(
      [
        {
          userarn: "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/n-ozawan"
          username: "n-ozawan"
          groups: [ "eks-console-dashboard-full-access-group" ]
        }
      ]
    )
  }

  force = true
}

metadataブロックにあるnameにはConfigMapの名前を指定します。今回はaws-authにする必要があります。同様にnamespaceもkube-systemにする必要があります。

dataブロックにはaws-authの内容を指定します。mapRolesにはKubernetesクラスタへのアクセス権限を許可するIAMロールを指定します。ここではFargateからアクセスを許可するため、Fargateのロールを指定しています。

mapUsersにはKubernetesクラスタへのアクセス権限を許可するIAMユーザー、つまりAWSコンソールでアクセスしたいユーザーを指定します。userarnには該当ユーザーのARNを、usernameにはユーザーの名前、groupsには手順2で作成したグループを指定します。

最後のforce = trueは、aws-authを上書きすることを示しています。aws-authはEKSを構築したタイミングで自動的に作成されています。これを指定しなかった場合、apply実行時に既存のaws-authと競合を起こしてエラーとなりますので、上書き指定する必要があります。

おわりに

いかがでしたでしょうか。権限に絡む問題は理解するのが難しく、今回はAWS側とKubernetes側の両面で理解する必要があるので、さらに問題を難しくしています。とはいえ、今回の件で、TerraformでもKubernetesに対して何かしらの操作が出来ることが分かって頂けたと思います。

ではまた。

Recommendおすすめブログ