Chatwork 坂本です。
本ブログは2020年1月23日に行われた、下記のコンテナ支部での発表を補足する内容で、eksctlの設定ファイルとvariantの具体的な使い方に焦点を当てて書きたいと思います。
目次
eksctlの設定ファイル
発表資料では、主にeksctlをvariantでwrapして、運用している、という話をしましたが(さらにeksctlの設定ファイルのテンプレートからの生成もvariantで)、そもそもなんでそのような運用が必要なのか、というのを、eksctlの設定ファイルの構成から説明していきたいと思います。
下記がChatworkで運用しているeksctlの設定ファイルのサンプルです(eksctl version 0.13.0)。
eks本体の設定ファイル:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: %%CLUSTER_NAME%% region: ap-northeast-1 version: "%%EKS_VERSION%%" cloudWatch: clusterLogging: enableTypes: ["*"] # types: "api", "audit", "authenticator", "controllerManager", "scheduler" vpc: clusterEndpoints: privateAccess: true publicAccess: true publicAccessCIDRs: - "XX.XX.XX.XX/32" subnets: # must provide 'private' and/or 'public' subnets by availibility zone as shown public: ap-northeast-1b: id: "subnet-XXXXX" ap-northeast-1c: id: "subnet-XXXXX" ap-northeast-1d: id: "subnet-XXXXX"
nodegroupの設定ファイルの一部:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: %%CLUSTER_NAME%% region: ap-northeast-1 nodeGroups: - name: worker-1b-%%WORKER_VERSION%% labels: node.kubernetes.io/role: "worker" aws.amazon.com/purchaseType: "spot" instanceType: mixed minSize: 1 maxSize: 40 desiredCapacity: %%WORKER_DESIRED_CAPACITY%% volumeSize: %%WORKER_VOLUME_SIZE%% volumeType: gp2 volumeEncrypted: true instancesDistribution: instanceTypes: - m5.xlarge - c5.xlarge - c5n.xlarge - c4.xlarge onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 0 spotInstancePools: 4 tags: # EC2 tags required for cluster-autoscaler auto-discovery k8s.io/cluster-autoscaler/enabled: "true" k8s.io/cluster-autoscaler/%%CLUSTER_NAME%%: "owned" iam: instanceProfileARN: "arn:aws:iam::XXXXXXX:instance-profile/eks-nodegroup-worker" instanceRoleARN: "arn:aws:iam::XXXXXXX:role/eks-nodegroup-worker" preBootstrapCommands: - 'cat /etc/docker/daemon.json | jq -r ".\"log-opts\".\"max-size\" |= \"%%WORKER_LOG_MAX_SIZE%%\"" | jq -r ".\"log-opts\".\"max-file\" |= \"%%WORKER_LOG_MAX_FILE%%\"" > /tmp/docker.json' - 'cp -f /tmp/docker.json /etc/docker/daemon.json' - 'systemctl restart docker' securityGroups: attachIDs: - "sg-XXXXX" availabilityZones: - "ap-northeast-1b"
eksctlとしてはなかなか複雑な設定ファイルだと思いますが、このような設定ファイルにしているのは下記の理由があります。
- nodegroupは、新しい機能が入ったり、amiが新しくなったりして、作り直すことがあるので、単独で管理したい
- 見やすい
- 作り直しに対応しやすいように、nodegroupにversionを付けている(dateの結果が
%%WORKER_VERSION%%
に入る)
- managed nodegroupは使わない(使えない)
- spotに対応していない
- ChatworkではKubernetes化に伴い(かつ、最近のspotの安定性を考慮し)、本番環境もspotでの運用を目指しています
preBootstrapCommands
に対応していない
- spotに対応していない
- cluster-autoscalerを利用するため、az毎にnodegroupを作成する
- 上記は1bだけですが、1c, 1dも同じ内容で作成します
- cluster-autoscalerを利用する際、1つのazにまとめてしまうと、cluster-autoscalerとしては、どのazを広げるべきなのか判断できないため、個別に作成する必要があります
- その他、volumesizeなど、環境毎(prod,stg,test)に変えたい
これらの設定がありますが、クラスタ毎で変わるのはそれほどありません。 そのため、上記の内容をテンプレート化して、吐き出し、それをeksctlコマンドに渡して、eks、eks nodegroupを作成しています。
eksctlの設定ファイルのsampleは下記で確認できます。
まれに上記にない項目もありますが、その場合はソースを見るしかないです。 https://github.com/weaveworks/eksctl/blob/master/pkg/apis/eksctl.io/v1alpha5/types.go
preBootstrapCommandsについて
非managed node groupを利用する場合、preBootstrapCommandsが利用できます。 preBootstrapCommandsは、userdataとして実行されるもので、これによって、eksctl自体で対応できない設定も対応することが可能な場合があります。
preBootstrapCommandsをuserdataとして登録するのは、ソースコードでは↓です。
https://github.com/weaveworks/eksctl/blob/master/pkg/cfn/builder/nodegroup.go
上記の設定ファイルのpreBootstrapCommandsでは
- defaultのdockerの設定(/etc/docker/daemon.json)の一部を
jq
コマンドで置換- amazon linux2はデフォルトでjqが入っている
- dockerのrestart
を実行しています。具体的には、dockerのログローテーションの設定をしています。デフォルト(10Mが10file)でも問題ありませんが、本番環境だけ不安なので、大きめにしています(その分、nodeのvolumesizeも大きめに)。
このdockerの設定は、下記で見つけて導入しました。他にも使えるものがあるので、いろいろと設定したい場合は、exampleを漁ってみてください。 https://github.com/weaveworks/eksctl/blob/master/examples/05-advanced-nodegroups.yaml
githubのexampleにしかないものもあるし、eksctl.ioのドキュメントにしかないものがある場合があるため、両方見てみることをおすすめします。
variantの具体的な使い方
variantの詳細な機能を説明するわけではないですが、発表資料よりもう少し具体的なvariantの使い方を説明します。
上記のようなテンプレートからeksctlの設定ファイルを生成していますが、以外と値が多く、sed
でやるとしてもなかなか骨が折れる内容ではあります。
そこで、Chatworkではvariantの設定ファイルを作成し、それを環境毎に持ち、variant経由でコマンドを実行しています。
variantの設定ファイルたち
$ tree config config └── environments ├── eks-prod.yaml ├── eks-stg.yaml └── eks-test.yaml
これらのファイルの中身は下記のような内容です。
% cat config/environments/eks-prod.yaml awsProfile: "" awsDefaultRegion: "ap-northeast-1" awsAccessKeyId: "" awsSecretAccessKey: "" eksVersion: "1.14" worker: desiredCapacity: "2" volumeSize: "200" log: maxSize: "50m" maxFile: "6"
そして、これをvariantの環境として実行すれば、eks-prod用のeksctl設定ファイルが生成されます。 variantではファイル名がコマンド名になり、Chatworkではeksを管理するコマンドをachlisとしています。
# env setはvariant自身のコマンド ./achlis env set "eks-prod" # ファイルの生成 ## generateコマンドの実体は、configに設定された値でひたすらsedで置換するものです ./achlis generate files --aws-profile=XXXX # born ./achlis born
環境毎の設定をファイルに持たせることができるので、コマンド自体は変わらず、再現性が高くなり、設定をgitで管理することができます。 またvariantにはdocker runner機能(コマンドをdocker runで実行する)があるため、環境とコマンドがセットになります。
さらに、発表資料でも書きましたが、bornというコマンドの中では、実際には
- EKS cluster 作成
- nodegroup 作成
- iamserviceaccount 作成
- flux enable repo の有効化(fluxのinstall)
がステップ実行されます(variantはtask runner)。
あとはCIや人間が、achlisを実行すれば、どんどんEKSのclusterができていきます。
まとめ
- eksctl!!
- variant !!
上記のachlisはvariant1で作成しましたが、variant2に移行中です。
variant2ではtestや、並列実行、ログ周りなどいろいろと改善されております。
最後に(どうでもいいニュース)
ランナーしての活動を報告しますと、2020年2月に行われた神奈川マラソン(ハーフマラソン)で、89分46秒で完走し、無事にハーフマラソンの自己ベストを更新しました。
ハーフマラソン90分切りは1つの目標であり、今のトレーニングが順調に来ていることを確認できるいい機会でした。 3月に行われる板橋シティマラソンで、どれぐらいいけるのか、非常に楽しみではありますが、同時に怖さもあります。
以上です。