コンテナ用LinuxベースOSのBottlerocketでEKSクラスタの構築。
今回は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コマンドのインストールが必要です。
さっそく
さっそくクラスタの作成をしましょう。
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 Container
とAdmin Container
の2種類がありControl Containerの機能の中にSession Managerを使用してControl Containerへの接続ができるのでこれを使用しましょう。
$ aws ssm start-session --target i-<your instance_id>
これで接続に成功するとコンソールに入ることができるのでこの中でapiを叩いて操作ができるようになったりできるので必要に応じて使用しましょう。
Admin Containerへのログイン
Admin Containerへのログインはsshを使用してのログインになりますがこれはセキュリティ的に問題になったりするので普段は使用しなかったり許可しないまたはトラブルシュートのときのみに使用するなどの用途で使用することに運用上で注意することが必要です。
ログインする際には以下のコマンドで接続します。
$ ssh -i ~/.ssh/<your-keypair>.pem ec2-user@<worker node global ip address>
Cluster Autoscaler
基本的にはこの手順に沿って実行することで実現できます。
ただ一点だけハマりポイントが有ります。
実際に使用するcluster-autoscaler-autodiscover.yaml
にca-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の切り替えで躓いたりするポイントが出てくると思いますが機会があればそういった点も紹介したいなと思います。
簡単にはなりますがこれで終わりたいと思いますありがとうございました。
追記
実際にBottlerocketを使用した際にハマった点などを別で追記していきます。
解決しているもののあるかと思いますのでご容赦ください。
efsのマウントに失敗する
kubernetes上でefsを使用する際にaws-efs-csi-driverを使用していたのですがefsが正常にPodにアタッチできていない事象がおきました。
問題としてはefs-utilの内部でpython2のサブプロセス呼び出しが失敗しているようでpython3で明示的に指定して再ビルドすることで上手く動かすことができるようになりました。(AWSさん早く直してくれ。。。)