1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EKSマネージドノードグループの起動に任意の処理を追加する

Posted at

まえがき

たとえばプライベート証明書を使ったコンテナリポジトリを使っている場合、ノードにプライベート証明書をインストールする必要があります。EKS最適化AMIを使ったマネージドノードグループでこれをするには起動テンプレートをカスタマイズすればいいです。Amazon Linux 2023のEKS最適化AMIを使ったマネージドノードの場合の例を記載します。

参考

Terraformのサンプル

結論としては以下のようなコードでマネージドノードグループと起動テンプレートを作成すればいいです。Terraform内のextra_scriptsに追加処理のシェルスクリプトを記述します。例だとS3バケットに配置したプラベート証明書をインストールするシェルスクリプトを書いています。

ちなみに、以下コードはVPCをAWS VPC Terraform module、EKSをAWS EKS Terraform moduleで作成して変数を参照しています。ノードグループのIAMロールにはS3へのアクセス権も付与してあります。

sample.tf
resource "aws_eks_node_group" "extra" {
  cluster_name    = module.eks.cluster_name
  node_group_name = "extra"
  node_role_arn   = module.eks.eks_managed_node_groups.default.iam_role_arn
  subnet_ids      = module.vpc.private_subnets

  scaling_config {
    desired_size = 1
    max_size     = 1
    min_size     = 1
  }

  launch_template {
    id      = aws_launch_template.extra.id
    version = "$Latest"
  }
}

# AL2023 EKS最適化AMIの最新IDを取得
data "aws_ssm_parameter" "eks_ami_image_id" {
  name = "/aws/service/eks/optimized-ami/${module.eks.cluster_version}/amazon-linux-2023/x86_64/standard/recommended/image_id"
}

# 変数にuserdataの内容を格納
locals {
  user_data = base64encode(templatefile("./al2023_user_data.tpl", {
    apiServerEndpoint    = module.eks.cluster_endpoint
    certificateAuthority = module.eks.cluster_certificate_authority_data
    cidr                 = module.eks.cluster_service_cidr
    name                 = module.eks.cluster_name
    extra_scripts        = "aws s3 --region リージョン cp s3://バケット名/証明書 /etc/pki/ca-trust/source/anchors/ && update-ca-trust extract"
  }))
}

resource "aws_launch_template" "extra" {
  name                   = "extra"
  image_id               = nonsensitive(data.aws_ssm_parameter.eks_ami_image_id.value)
  user_data              = local.user_data
  vpc_security_group_ids = [module.eks.node_security_group_id]

  monitoring {
    enabled = true
  }

  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required"
    http_put_response_hop_limit = 2
    instance_metadata_tags      = "disabled"
  }
}
al2023_user_data.tpl
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: application/node.eks.aws

---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    apiServerEndpoint: ${apiServerEndpoint}
    certificateAuthority: ${certificateAuthority}
    cidr: ${cidr}
    name: ${name}
--//
Content-Type: text/x-shellscript

#!/bin/bash
${extra_scripts}

--//--

解説

EKSへの参加

2024/10現在、EKS最適化AMIのAmazonLinuxはAL2AL2023の2つがあり、EKSへの参加方法も異なります。AL2bootstrap.shというシェルスクリプト使っています。このスクリプトを実行してEKSへの参加を行いますが、その際AWSのDescribeClusterAPIを使用していました。これだと大規模な環境ではAPIの大量実行が発生する恐れもあったそうです。そこでAL2023ではnodeadmを使うように変更されました。今までDescribeClusterで取得していた情報をYAMLに記述することでAPIの大量実行を防ぐようになりました。nodeadmはServiceとして登録されておりOS起動時に自動実行され、起動時の設定はuserdataから読み込まれるようです。

参考

cloud-init(userdata)

Amazon Linuxのインスタンス初期設定はcloud-initを使用しており、ユーザーデータに書かれた処理が実行されます。ユーザーデータは以下のようなMIMEマルチパートドキュメントの形式で書かれています。--//で囲まれた部分が1つの塊で、Content-Typeでデータの型(type/subtype;parameter=value)を指定し、型に沿った内容(Content)を記述します。

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: type/subtype;parameter=value

Content

--//
Content-Type: type/subtype;parameter=value

Content
--//--

AL2のEKS最適化AMIの場合、bootstrap.shの実行が記述されています。AL2023の場合はnodeadmの設定が記述されています。nodeadmの設定はContent-Type:application/node.eks.awsの型を使用します。この型はnodeadm設定用であるため、任意のコマンドを実行したい時はConntent-Type:text/x-shellscriptを追加すればいいです。たとえば以下のユーザーデータならnodeadmの設定をしつつファイル「hogehoge」を作成します。

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: application/node.eks.aws

---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    apiServerEndpoint: APIサーバーのエンドポイント
    certificateAuthority: EKSクラスタの証明書
    cidr: サービスCIDR
    name: クラスタ名

--//
Content-Type: text/x-shellscript

#!/bin/bash
touch hogehoge

--//--

参考

ノードグループと起動テンプレートの設定

Terraformだとaws_eks_node_groupaws_launch_templateで似たような設定項目があります。例えばセキュリティグループは両方にパラメータが用意されています。起動テンプレートをカスタマイズする場合にどちらで設定すべきかはAWSのドキュメントに記載があります。セキュリティグループは起動テンプレートで設定します。

参考

起動テンプレートのメタデータオプション

カスタムでないデフォルトのマネージドノードグループの場合、起動テンプレートはIMDSv2が必須になっておりHttpPutResponseHopLimitも2に設定されています。カスタムした起動テンプレートを使う場合、明示的にこれらの設定をします。特にHttpPutResponseHopLimitを2にしないとPodがノードのIAMロールを継承できません。IRSAでPodにIAMを付与するかHttpPutResponseHopLimitを2に設定して回避します。サンプルのTerraformではHttpPutResponseHopLimitを2に設定しています。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?