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月に行われる板橋シティマラソンで、どれぐらいいけるのか、非常に楽しみではありますが、同時に怖さもあります。
以上です。