kops で t3 インスタンスの T2/T3 Unlimited を無効にする

kopskubernetesクラスタを構築する時には master と node となるインスタンスが1台以上必要になる。
kops は Instance Groups という概念で これらを表現していて AWS だと AutoScalingGroup にあたる。

今までは t2 インスタンスで master と node を運用していたけど t3 がでて 1年以上?たつしそろそろインスタンスを乗り換えることにした。
t2 から t3 にインスタンスタイプを変更するにあたって気にすることとして t3 インスタンスunlimited mode がデフォルトで有効になってしまう。
もりもりCPUを使っていく感じでもないし何より追加の料金を払いたくないなぁと思ったのでこれを無効にしたのが今回の記事です。

AutoScaling Group で 無効にする場合は 起動テンプレート を使って設定をするようです。
ただ kops は YAML 経由で設定をするのでこの起動テンプレートに対応してないと使えません。

そして現状 (v0.15.0) だと対応していなさそう。。。
github.com

別の案として ユーザーデータ でオフにできないかを考える。

次のようなスクリプトインスタンス内で実行すると awscli を通して今いるインスタンスの unlimited mode を無効にできる。

#!/bin/bash
INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id`
SPECIFICATIONS_JSON="[{\"InstanceId\": \"${INSTANCE_ID}\",\"CpuCredits\": \"standard\"}]"
echo "INSTANCE_ID: ${INSTANCE_ID}"
echo "SPECIFICATIONS_JSON: ${SPECIFICATIONS_JSON}"
aws --region ap-northeast-1 ec2 describe-instance-credit-specifications --instance-id ${INSTANCE_ID}
aws --region ap-northeast-1 ec2 modify-instance-credit-specification --instance-credit-specification "${SPECIFICATIONS_JSON}"
aws --region ap-northeast-1 ec2 describe-instance-credit-specifications --instance-id ${INSTANCE_ID}

ユーザーデータとして追加するため kops の InstanceGroup へ次のように記載する。

apiVersion: kops/v1alpha2
kind: InstanceGroup
~~~
spec:
  ~~~
  additionalUserData:
    - name: credit-specification-standard.sh
      type: text/x-shellscript
      content: |
        #!/bin/bash
        INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id`
        SPECIFICATIONS_JSON="[{\"InstanceId\": \"${INSTANCE_ID}\",\"CpuCredits\": \"standard\"}]"
        echo "INSTANCE_ID: ${INSTANCE_ID}"
        echo "SPECIFICATIONS_JSON: ${SPECIFICATIONS_JSON}"
        aws --region ap-northeast-1 ec2 describe-instance-credit-specifications --instance-id ${INSTANCE_ID}
        aws --region ap-northeast-1 ec2 modify-instance-credit-specification --instance-credit-specification "${SPECIFICATIONS_JSON}"
        aws --region ap-northeast-1 ec2 describe-instance-credit-specifications --instance-id ${INSTANCE_ID}

あとは コマンドを実行するための権限として ec2:DescribeInstanceCreditSpecificationsec2:ModifyInstanceCreditSpecification が必要になります。
これは EC2 へ割り当てている IAM ロールに対してこの権限をアタッチすれば良さそうです。

kops は kind: Cluster で EC2 に対して割り当てられるポリシーの追加が行えるので次のように設定します。

apiVersion: kops/v1alpha2
kind: Cluster
~~~
spec:
  ~~~
  additionalPolicies:
    node: |
      [
        {
          "Action": [
            "ec2:ModifyInstanceCreditSpecification",
            "ec2:DescribeInstanceCreditSpecifications"
          ],
          "Effect": "Allow",
          "Resource": "*"
        }
      ]
    master: |
      [
        {
          "Action": [
            "ec2:ModifyInstanceCreditSpecification",
            "ec2:DescribeInstanceCreditSpecifications"
          ],
          "Effect": "Allow",
          "Resource": "*"
        }
      ]

これを実行すれば起動時にユーザーデータでスクリプトが実行されて unlimited mode が無効になる。