OpenShiftソリューションアーキテクトの林です。
本記事は、OpenShiftとAWSのAuto Scaling Groupで伸縮自在なKubernetesクラスタを構築するの続きです。
前回は、OpenShiftのbootstrapを利用して、
- VMを立ち上げるだけで既存のクラスタにワーカーノードとして参加させる
- AWSのAuto Scaling Groupで構成することで、簡単にOpenShiftのワーカーノードを増減させる
を実現しました。
本記事では、さらにCluster Autoscalerをクラスタに導入してみます。
これにより、Podを立てるときに十分なリソース(メモリ量など)がない場合に、自動的にAuto Scaling GroupのVM数が増えてワーカーノードが追加されるようになります。
Cluster Autoscalerは、OpenShiftのv3.11でGAとなりサポートされています(現在はAWS上のみサポート)。
- Cluster Autoscalerのインストールについて
- Auto Scaling Groupの作成
- Cluster Autoscaler用の権限設定
- IAMの設定
- Cluster Autoscalerのデプロイ
- Cluster Autoscalerの動作確認
- まとめ
Cluster Autoscalerのインストールについて
前回までの手順で、Auto Scaling Groupでワーカーノードを追加、削除できるようになっていれば、Cluster Autoscalerの導入は比較的簡単です。
- Cluster Autoscalerの動作に必要なRBACをクラスタに設定する
- AWSのAuto Scaling Groupを操作できるIAMを作成する
- 上記IAMのAccess Key IDとSecret Access Key、およびAuto Scaling Groupの名前を指定して、Cluster Autoscalerをクラスタにインストールする
そういうわけで、さっそくCluster Autoscalerをクラスタに設定してみましょう。
Auto Scaling Groupの作成
AWSのAuto Scaling Groupは、起動設定または起動テンプレートから作成することになっており、AWSの推奨は新しい方法である起動テンプレートを使った方法です。
しかし、OpenShiftで現在サポートされているCluster Autoscalerは、現在起動設定の方しかサポートしていませんでした。。。
そういうわけで、以下に注意しながら起動設定を作成します。
- 前回の記事を参考に、同じ設定でAWSの
起動設定を作成する 起動設定からAuto Scaling Groupを作成し、以下のようにタグ付けする。また、「新しいインスタンスにタグ付けする」を有効にするk8s.io/cluster-autoscaler/node-template/label/node-role.kubernetes.io/compute:truekubernetes.io/cluster/<クラスタ名>:owned

Cluster Autoscaler用の権限設定
Cluster Autoscalerの動作に必要なService AccountおよびRBACを設定します。
以下、Cluster Roleの設定を行う場面があるので、cluster-admin権限のあるOpenShiftユーザーで実施してください。
Cluster Autoscaler用のプロジェクトを作成する
以下コマンドでプロジェクトを作成します。このプロジェクトに、Cluster AutoscalerのPodを導入します。
oc apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: cluster-autoscaler
annotations:
openshift.io/node-selector: ""
EOF
oc project cluster-autoscaler
なお、OpenShift v3.11では、デフォルトのNode Selectorがnode-role.kubernetes.io/compute=trueとなっており、普通にoc new-projectでプロジェクトを作成すると中のPodはComputeノードにデプロイされます。
ここでは、Cluster AutoscalerをInfraノードにデプロイしたいので、上記のようにプロジェクトのNode Selectorを明示的に指定しています。
Cluster Autoscaler用のService Accountを作成する
Cluster AutoscalerのPodに割り当てるService Accountを作成します。
以下yamlを作成して、 oc apply -fコマンドで適用してください。
apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-addon: cluster-autoscaler.addons.k8s.io k8s-app: cluster-autoscaler name: cluster-autoscaler namespace: cluster-autoscaler
Cluster Autoscalerに必要な権限の設定
上記で作成したService Accountに権限を設定します。
まず、クラスタのリソース監視などに必要なCluster Roleを作成します。以下yamlファイルを作成して、oc apply -fで適用してください。
apiVersion: v1 kind: ClusterRole metadata: name: cluster-autoscaler rules: - apiGroups: - "" resources: - persistentvolumeclaims - persistentvolumes - pods - replicationcontrollers - services verbs: - get - list - watch attributeRestrictions: null - apiGroups: - "" resources: - events verbs: - get - list - watch - patch - create attributeRestrictions: null - apiGroups: - "" resources: - nodes verbs: - get - list - watch - patch - update attributeRestrictions: null - apiGroups: - extensions - apps resources: - daemonsets - replicasets - statefulsets verbs: - get - list - watch attributeRestrictions: null - apiGroups: - policy resources: - poddisruptionbudgets verbs: - get - list - watch attributeRestrictions: null
Cluster Autoscalerは、スケーリングの情報をConfigMapに書き込むので、それに必要な権限も作成します。
apiVersion: v1 kind: Role metadata: name: cluster-autoscaler rules: - apiGroups: - "" resources: - configmaps resourceNames: - cluster-autoscaler - cluster-autoscaler-status verbs: - create - get - patch - update attributeRestrictions: null - apiGroups: - "" resources: - configmaps verbs: - create attributeRestrictions: null - apiGroups: - "" resources: - events verbs: - create attributeRestrictions: null
Roleの作成が終わったら、先ほど作成したService AccountにこれらのRoleとクラスタの読み込み権限を付与します。
$ oc adm policy add-cluster-role-to-user cluster-autoscaler system:serviceaccount:cluster-autoscaler:cluster-autoscaler -n cluster-autoscaler $ oc adm policy add-role-to-user cluster-autoscaler system:serviceaccount:cluster-autoscaler:cluster-autoscaler --role-namespace cluster-autoscaler -n cluster-autoscaler $ oc adm policy add-cluster-role-to-user cluster-reader system:serviceaccount:cluster-autoscaler:cluster-autoscaler -n cluster-autoscaler
IAMの設定
Cluster Autoscalerは、クラスタのリソース状況を見てAWSのAuto Scaling Groupを操作するので、それができる権限を付与する必要があります。
ここでは、AWSのIAMユーザーを新しく作成して、そこに適切なポリシーを設定することにします。
Cluster Autoscalerに必要なAWSの権限ポリシー
Cluster Autoscalerに必要なポリシーは、以下URLに記載のあるとおりAuto Scaling Groupに関するものです。
https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler/cloudprovider/aws
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup", "autoscaling:DescribeLaunchConfigurations" ], "Resource": "*" } ] }
AWSのコンソールなどから、上記のポリシーを適用しているIAMを作成します。
IAMのクレデンシャルをクラスタに設定
作成したIAMのクレデンシャルをクラスタのSecretとして設定します。
$ cat <<EOF > creds [default] aws_access_key_id = your-aws-access-key-id aws_secret_access_key = your-aws-secret-access-key EOF $ oc create secret -n cluster-autoscaler generic autoscaler-credentials --from-file=creds
Cluster Autoscalerのデプロイ
これで、Cluster Autoscalerをデプロイする準備ができました。以下yamlを使って、Cluster Autoscalerをデプロイします。
.spec.template.spec.containers[0].argsの--nodes=0:6:<asgname>引数を<最小ワーカー数>:<最大ワーカー数>:<Auto Scaling Groupの名前>という記法で設定します。
ここには、前回の記事で作成したAuto Scaling Groupを設定してください。
また、.spec.template.spec.containers[0].envのAWS_REGIONにクラスタのあるリージョンを設定します。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: cluster-autoscaler name: cluster-autoscaler namespace: cluster-autoscaler spec: replicas: 1 selector: matchLabels: app: cluster-autoscaler role: infra template: metadata: labels: app: cluster-autoscaler role: infra spec: containers: - args: - /bin/cluster-autoscaler - --alsologtostderr - --v=4 - --skip-nodes-with-local-storage=False - --leader-elect-resource-lock=configmaps - --namespace=cluster-autoscaler - --cloud-provider=aws - --nodes=0:6:<Auto Scaling Group名> env: - name: AWS_REGION value: ap-northeast-1 - name: AWS_SHARED_CREDENTIALS_FILE value: /var/run/secrets/aws-creds/creds image: registry.redhat.io/openshift3/ose-cluster-autoscaler:v3.11.43 name: autoscaler volumeMounts: - mountPath: /var/run/secrets/aws-creds name: aws-creds readOnly: true dnsPolicy: ClusterFirst nodeSelector: node-role.kubernetes.io/infra: "true" serviceAccountName: cluster-autoscaler terminationGracePeriodSeconds: 30 volumes: - name: aws-creds secret: defaultMode: 420 secretName: autoscaler-credentials
このYAMLをcluster-autoscaler.yamlなどの名前で保存し、クラスタに適用します。
$ oc apply -f cluster-autoscaler.yaml -n cluster-autoscaler $ oc get pods -n cluster-autoscaler -w NAME READY STATUS RESTARTS AGE cluster-autoscaler-9b7f787f4-sw5gx 0/1 ContainerCreating 0 3s cluster-autoscaler-9b7f787f4-sw5gx 1/1 Running 0 4s
Podが無事起動することを確認してください。
Cluster Autoscalerの動作確認
これで、Cluster Autoscalerの設定が完了しました。
クラスタの能力を超える量のPodをデプロイしようとすると、Auto Scaling GroupからVMが起動され、ワーカーノードが追加されていくはずです。
ここでは、以下のような無茶なDeploymentを作って、Podをデプロイしまくります。
apiVersion: apps/v1 kind: Deployment metadata: name: scale-up labels: app: scale-up spec: replicas: 20 selector: matchLabels: app: scale-up template: metadata: labels: app: scale-up spec: containers: - name: origin-base image: openshift/origin-base resources: requests: memory: 2Gi command: - /bin/sh - "-c" - "echo 'this should be in the logs' && sleep 86400" terminationGracePeriodSeconds: 0
このファイルをscale-up.yamlなどの名前で保存し、以下のように適用してみましょう。
$ oc new-project autoscaler-demo $ oc apply -f scale-up.yaml -n autoscaler-demo
もとのクラスタの能力によりますが、おそらく以下のように大量のPending状態なPodが発生すると思います。
$ oc get pods -n autoscaler-demo | grep Pending scale-up-79684ff956-5jdnj 0/1 Pending 0 40s scale-up-79684ff956-794d6 0/1 Pending 0 40s scale-up-79684ff956-7rlm2 0/1 Pending 0 40s scale-up-79684ff956-9m2jc 0/1 Pending 0 40s scale-up-79684ff956-9m5fn 0/1 Pending 0 40s
Cluster Autoscalerは、この状態のPodを検知すると、ノードを追加して対応しようとします。
設定がうまくいっていれば、Auto Scaling Groupの希望インスタンス数が引き上げられ、以下のようにノードが追加されていくはずです。
$ oc get nodes NAME STATUS ROLES AGE VERSION ip-xx-xx-xx-xx.ap-northeast-1.compute.internal Ready compute 5d v1.11.0+d4cacc0 ip-xx-xx-xx-xx.ap-northeast-1.compute.internal Ready compute 5d v1.11.0+d4cacc0 ip-xx-xx-xx-xx.ap-northeast-1.compute.internal Ready infra,master 5d v1.11.0+d4cacc0 ip-xx-xx-xx-xx.ap-northeast-1.compute.internal Ready compute 7s v1.11.0+d4cacc0
まとめ
前回の記事では、AWSのAuto Scaling GroupとOpenShiftワーカーノードのBootstrapプロセスを用いて、Auto Scaling GroupでVM数を増減させるだけでクラスタを伸縮できるようにしました。
この記事では、さらにCluster Autoscalerをクラスタに設定して、リソースの利用状況に基づいて自動的にクラスタが伸縮されるように設定しました。
IaaSとコンテナプラットフォームを組み合わせ、条件を適切に設定すれば、事前にクラスタのサイジングを詰めるのではなく、動的に必要な量のリソースを確保することができます。
Cluster Autoscaler Operator
とはいえ、手順が複雑すぎるのでOperatorを使って簡単にインストールしたいところですね。
と思ってGitHubを探したら何かありました。
こいつは、AWSではなく、Cluster APIをCloud Providerとして使うことで、どのIaaSを使用していても利用できることを目指しているようです。
将来的には、このCluster Autoscaler Operatorもサポートされるようになるのかもしれませんね。