EKSのノードをSpot Fleetで構築する

EKSをterraformで作っている.そうするとEKSのノード群をAutoscalingGroupで構築する例は出てくるのだが,これをSpotFleetを使って構築しようと思う.

terraformでEKSを構築する

techblog.ap-com.co.jp

だいたいこれと同じことをする.

実際に作ったもののソースはこちら.

github.com

ノードに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のノードとしてクラスタに参加することができる.