[AWS][EKS] AWS EKS のノードインスタンスに Amazon Linux 2023 を使いたい
こんにちは🐶
株式会社 Tsuzucle SPRING 開発事業部にフリーランスインフラエンジニアとして参画している はらしゅん です。
今回は、AWS EKS(Elastic Kubernetes Service)にて、ノードインスタンスに Amazon Linux 2023(※ EKS 最適化 AMI の Amazon Linux 2023 です)を使おうとしたところ、ハマった話を書こうと思います🐙
問題意識
Amazon Linux 2 は EOL が近いため、EKS にて新たに起動するノードインスタンスには、Amazon Linux 2 ではなく、Amazon Linux 2023 を使うべきだと考えました。
発生した問題
GUI からポチポチと Amazon Linux 2023 をノードインスタンスとしたノードグループを作成したところ・・
大体の Pod 達は問題なく動いてくれましたが、
AWS Load Balancer Controller
の pod がエラーに・・😿
下記の方が、同様の事象に遭遇し、原因も解説してくださっております。🙏
一次対応
まず一旦は AWS CLI で ノードインスタンスたちの hop limit
を上げて、
AWS Load Balancer Controller
の pod たちがエラーにならないようにしました。
▼ 現在のインスタンスの hop limit 値を取得する
$ aws ec2 describe-instances \
--instance-ids {インスタンス ID} \
--query 'Reservations[].Instances[].MetadataOptions.HttpPutResponseHopLimit'
▼ インスタンスの hop limit 値を変える
$ aws ec2 modify-instance-metadata-options \
--instance-id {インスタンス ID} \
--http-put-response-hop-limit 2
そして恒久対応として、常に hop limit が 2 以上の Amazon Linux 2023 ノードインスタンスが起動するノードグループを作成しようと思いました。
目指したこと
- なるべく IaC(AWS CLI, ekscli, YAML, JSON)化する
- Terraform でのやり方は、danimal141さんが既に紹介してくださっているし、今回のメンバー全員が Terraform に精通しているわけではないため、今回は Terraform は使わない
hop limit を 2 以上とした Amazon Linux 2023 をノードインスタンスとする方法
Launch Template(JSON)を作成
launch-template.json
{
"InstanceType": "t3.medium",
"NetworkInterfaces": [
{
"DeviceIndex": 0,
"Groups": ["sg-1234abcd"],
"DeleteOnTermination": true
}
],
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"VolumeSize": 20,
"VolumeType": "gp3",
"DeleteOnTermination": true
}
}
],
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "node-instance-name"
}
]
}
],
"MetadataOptions": {
"HttpEndpoint": "enabled",
"HttpPutResponseHopLimit": 2,
"HttpTokens": "required"
}
}
AWS CLI で Launch Template をデプロイ
新規作成時
$ aws ec2 create-launch-template --cli-input-json file://launch-template.json
更新時(Version 2 を作成する)
$ aws ec2 create-launch-template-version --launch-template-id {Launch Template ID} --version-description "version 2" --launch-template-data file://launch-template.json
Launch Templete のデフォルトバージョン(1 -> 2)を変更したい場合
$ aws ec2 modify-launch-template --launch-template-name {Launch Template 名} --default-version 2
ノードグループ YAML を作成
config.yml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: {EKS クラスター名}
region: ap-northeast-1
iam:
withOIDC: true
managedNodeGroups:
- name: managed-ng
amiFamily: AmazonLinux2023
privateNetworking: true
launchTemplate:
id: lt-1234abcd # ここを実際の起動テンプレートIDに置き換えてください
version: "1"
subnets:
- subnet-xxx
- subnet-yyy
- subnet-zzz
maxSize: 4
minSize: 2
desiredCapacity: 3
iam:
instanceRoleARN: arn:aws:iam::{アカウント ID}:role/{NodeGroupRole}
vpc:
id: vpc-1234abcd
subnets:
private:
ap-northeast-1a: { id: subnet-xxx }
ap-northeast-1c: { id: subnet-yyy }
ap-northeast-1d: { id: subnet-zzz }
securityGroup: sg-1234abcd
eksctl でデプロイ
$ eksctl create nodegroup -f config.yml
難しかった点、ハマった点
ハマりポイント1️⃣
eksctl create nodegroup
がなかなか通らなかった ...(CloudFormation が Fail してしまう)
「◯◯ のパラメータが、Launch Template 側にあるとダメ」
「□□ のパラメータが、YAML 側にあるとダメ」
「(削りすぎると)△△ のパラメータは、ここになきゃダメ」
という感じだった。
ハマりポイント2️⃣
UserData で
/etc/eks/bootstrap.sh {クラスター名}
を実行しないといけないと思い込んでいた。
しかし、EKS 最適化 AMI の Amazon Linux 2023 では、ノード初期化プロセス nodeadm が導入されている。
Launch テンプレートに AMI を指定した場合、UseData に初期化処理のパラメーターを指定する必要があるが、マネージドノードグループの場合、AMI タイプに Amazon Linux 2023 を指定することで AMI は自動的に最新の EKS 最適化 AMI を設定し、初期化時のパラメーターは自動的に設定されるため UserData を指定する必要がない。
要は、(EKS 最適化 AMI に何か特殊なカスタマイズをしない場合は)UserData で何かする必要はない、ということ。
AWS サポートさん、大変ありがとうございました・・🙏🙇
参考資料
Amazon Linux 2023 (AL2023) では、YAML 設定スキーマを使用する新しいノード初期化プロセス nodeadm が導入されています。セルフマネージド型ノードグループまたは起動テンプレートを持つ AMI を使用している場合は、新しいノードグループの作成時に追加のクラスターメタデータを明示的に指定する必要があります。
AMI を指定する際、Amazon EKS ではユーザーデータをマージしません。
マネージド型ノードグループの更新を開始すると、Amazon EKS はノードを自動的に更新し、「ノードの更新の各フェーズを理解する」でリストされた手順を完了します。
Discussion