EKSのノードをSpot Fleetで構築する
EKSをterraformで作っている.そうするとEKSのノード群をAutoscalingGroupで構築する例は出てくるのだが,これをSpotFleetを使って構築しようと思う.
terraformでEKSを構築する
だいたいこれと同じことをする.
実際に作ったもののソースはこちら.
ノードにSpotFleetを使う
EKSのノードとして立ち上がるのに大事なのは,
- amazon-eks-nodeのAMIを使う
- EC2インスタンスのタグに
kubernetes.io/cluster-name=ownedが設定されていること - Init scriptのuser dataで
/etc/eks/bootstrap.shを叩く
の3つである.
このうち,AMIと,user dataに関してはASGであってもSpotFleetであっても同じ設定が可能である.
ただし,タグに関しては, 変数がKEYにくるようなタグをterraformでSpotFleetに付与することはできない. なのでこれに関しては何かしらの手を打つ必要がある.
ちなみに,
resource "aws_spot_fleet_request" "eks_node" {
launch_specification {
instance_type = "t3.medium"
ami = "${var.ami}"
# ...
tags {
"${kubernetes.io/cluster-name}" = "owned"
}
}
}
みたいな書き方をすると, ${kubernetes.io/cluster-name} というKEYのタグができるだけで,全然変数展開はしてくれない.
User dataに埋める
というわけでどうするかというと,インスタンス起動時にawscliを使って自分自身のインスタンスにタグを付与させる.
というのuser dataに書いておく.
#!/bin/bash
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py
export PATH=$PATH:/usr/local/bin
pip install awscli
REGION=ap-northeast-1
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws --region $REGION ec2 create-tags --resources "$INSTANCE_ID" --tags Key=kubernetes.io/cluster-name,Value=owned
set -o xtrace
/etc/eks/bootstrap.sh --apiserver-endpoint "${master_endpoint}" --b64-cluster-ca "${certificate_authority}" "${name}"
これで無事SpotFleetでも起動と同時にEKSのノードとしてクラスタに参加することができる.