コンテナ用LinuxベースOSのBottlerocketでEKSクラスタの構築。

公開:2020/10/11
更新:2020/10/11
4 min読了の目安(約3800字TECH技術記事

今回はAWSが発表したコンテナ用のOS、Bottolerocketを使用してEKSクラスタの構築をやっていきたいと思います。

一通りのクラスタの構築と簡単なアプリのデプロイとk8sのCluster Autoscalerで少し躓いた点があったのでその点だけメモとして残しておきたいと思います。

使用ツール

$ aws version
aws-cli/2.0.46 Python/3.7.4 Darwin/19.6.0 exe/x86_64

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-16T11:56:40Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"darwin/amd64"}

$ eksctl version
0.26.0

ssmを使用してBottlerocketのノードへのログインもしてみたいのであれば是非試してみてください。
その際はこちらからaws cliで使用するssmコマンドのインストールが必要です。
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

さっそく

さっそくクラスタの作成をしましょう。
eksctlコマンドでも作成は可能ですが今回はしっかりconfigを書いて次回自分が使いやすいようにしておくことも大事なので以下のようにコードで管理することにします。

---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: test-cluster
  region: ap-northeast-1
  version: "1.17"

iam:
  withOIDC: true

nodeGroups:
  - name: ng-bottlerocket
    desiredCapacity: 3
    minSize: 1
    maxSize: 4
    instanceType: t3.small
    amiFamily: Bottlerocket
    iam:
      attachPolicyARNs:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
    ssh:
      publicKeyName: <your key-pair name>
      allow: true

このような形で管理しています。
かなり簡単で nodeGroupsのamiFamilyを Bottlerocketに指定することでBottlerocketのOSが入ったNodeが作成されます。

注意点としてBottlerocketは現状nodegroupのみの対応でManeged Node Groupに対応していないのでnodeGroupsで設定することに注意してください。(将来的な対応に期待しています)

attachPolicyARNsは今まではAmazonEKSWorkerNodePolicy,AmazonEKS_CNI_Policy,AmazonEC2ContainerRegistryReadOnlyが必須のポリシーになっていたのですが今回はssmを使用してのNodeへの接続もするので追加しています。
今回は管理対象外ですがRoleとしてTerraform側で作成してroleをアタッチするという方法もあるのでご自身の好きな方法で管理してみるといいかなと思います。

sshに関しては後述するのですが一部の操作に対して使用することができるので必要であれば設定しておきましょう。

では実際に作成していきます。

$ eksctl create cluster -f <your-file-name>.yaml

これで作成されるのでnodeが作成されるのか確認してみましょう。

$ kubectl get nodes

これでnodeが3つ表示されれば成功です。

Session Managerを使用してNodeにログインする。

今までのNodeへのログインはsshでログインするか、自分でsession managerを設定する必要があるのですがBottlerocketとEKSの組み合わせではワーカーノード管理のためのツールとしてControl ContainerAdmin Containerの2種類がありControl Containerの機能の中にSession Managerを使用してControl Containerへの接続ができるのでこれを使用しましょう。

$ aws ssm start-session --target i-<your instance_id>

これで接続に成功するとコンソールに入ることができるのでこの中でapiを叩いて操作ができるようになったりできるので必要に応じて使用しましょう。
https://github.com/bottlerocket-os/bottlerocket/blob/develop/README.md#api

Admin Containerへのログイン

Admin Containerへのログインはsshを使用してのログインになりますがこれはセキュリティ的に問題になったりするので普段は使用しなかったり許可しないまたはトラブルシュートのときのみに使用するなどの用途で使用することに運用上で注意することが必要です。

ログインする際には以下のコマンドで接続します。

$ ssh -i ~/.ssh/<your-keypair>.pem ec2-user@<worker node global ip address>

Cluster Autoscaler

基本的にはこの手順に沿って実行することで実現できます。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-cluster-autoscaler-setup/

ただ一点だけハマりポイントが有ります。
実際に使用するcluster-autoscaler-autodiscover.yamlca-bundle.crtをマウントしているのですが、デフォルトで設定されているpathだとエラーになり正常に起動しないので以下のように修正することで動くようになります。

volumeMounts:
 - name: ssl-certs
   mountPath: /x86_64-bottlerocket-linux-gnu/sysroot/usr/share/factory/etc/pki/tls/certs/ca-bundle.crt
   readOnly: true

あとはドキュメントの手順に沿って実行することでリソースに合わせて自動でスケールしてくれるようになっています。
これで実際のCluster Autoscalerの実装は完了です。

まとめ

駆け足でやってしまいアプリケーションを動かすなどの実装は紹介しなかったのですがService type LoadBalancerで実際に外部との通信にも問題はなく実行できていたのでそこまで大きな問題はなく実装できたのかなと思っています。

実際に運用されている方はNodeの切り替えで躓いたりするポイントが出てくると思いますが機会があればそういった点も紹介したいなと思います。

簡単にはなりますがこれで終わりたいと思いますありがとうございました。