25
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ZOZOテクノロジーズ #2Advent Calendar 2020

Day 17

Elastic Cloud on Kubernetes (ECK)の仕組みと各構成変更における挙動について

Last updated at Posted at 2020-12-17

本記事はZOZOテクノロジーズ アドベントカレンダー#2の17日目の記事です。

TL;DR;

  • ECK動作確認環境構築手順
  • ECKの仕組み
  • 各構成・設定変更における挙動解説

動作確認環境の構築

本記事の解説で使う環境構築方法を簡単に解説します。なお、Kubernetes環境としてはAmazon Elastic Kubernetes Service(以下、EKS)を利用してますが、EKSセットアップとk8sクラスタ操作必要なkubectl等の設定手順については省略します。また、既にk8sクラスタに接続できる状態になっていることを前提とします。

環境

  • クライアントOS: macOS
  • Kubernetes versions:
    • client: v1.19.4
    • server: v1.18.9
  • ECK: 1.3

セットアップ

既に下記のようにkubectlコマンドでk8sクラスタにアクセスできる状態になっていることを前提とします。


kubectl get nodes

NAME                                                STATUS   ROLES    AGE    VERSION
ip-192-168-27-58.ap-northeast-1.compute.internal    Ready    <none>   3d4h   v1.18.9-eks-d1db3c
ip-192-168-38-215.ap-northeast-1.compute.internal   Ready    <none>   3d4h   v1.18.9-eks-d1db3c
ip-192-168-85-80.ap-northeast-1.compute.internal    Ready    <none>   3d4h   v1.18.9-eks-d1db3c

ECKインストール

ECK 1.3.0(Elastic Operatorと関連リソース)のマニフェストを次のようにk8sクラスタにapplyします。

VERSION=1.3.0
kubectl apply -f https://download.elastic.co/downloads/eck/${VERSION}/all-in-one.yaml

ECKのコアリソースはelastic-system名前空間にデプロイされます。次のコマンドでElastic Operator podがrunningになっていることを確認します。

kubectl get all -n elastic-system

NAME                     READY   STATUS    RESTARTS   AGE
pod/elastic-operator-0   1/1     Running   0          14m

NAME                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/elastic-webhook-server   ClusterIP   10.100.111.185   <none>        443/TCP   14m

NAME                                READY   AGE
statefulset.apps/elastic-operator   1/1     14m

Elastic Operatorのログは次のように確認できます。

kubectl -n elastic-system logs -f statefulset.apps/elastic-operator

Elasticsearchクラスタのデプロイ

上記の手順でElastic Operatorのインストールが完了したら、続いてElasticsearchクラスタをk8sにデプロイします。既にインストールされているElastic OperatorがElasticsearchクラスタをk8sに自動的にデプロイして宣言した通りの状態が維持されるようにk8sリソースを管理します。

まずは、本記事の動作確認で利用する名前空間testeckを作成します。

kubectl create namespace testeck

作成した名前空間testeckに、次のようにmasterノード x 3、dataノード x 1な構成のElasticsearchクラスタecksandboxをデプロイします。

cat <<EOF | kubectl apply -n testeck -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: ecksandbox
spec:
  version: 7.10.0
  nodeSets:
  - name: master-nodes
    count: 3
    config:
      node.store.allow_mmap: false
      node.roles: ["master"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: gp2
  - name: data-nodes
    count: 1
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 2Gi
        storageClassName: gp2
EOF

NOTE: volumeClaimTemplatesで、masterノードにそれぞれ1GBのEBS volume(gp2)を、dataノードに2GBのEBS volume(gp2)を割り当てる宣言をしています。

次のようにデプロイしたElasticsearchリソースの状態を取得します。問題なければHEALTH状態がgreen、NODESが4、PHASEがreadyになっているはずです。

kubectl get elasticsearch -n testeck

NAME         HEALTH   NODES   VERSION   PHASE   AGE
ecksandbox   green    4      7.10.0    Ready   64s

Elasticsearchクラスタにアクセス

デプロイしたElasticsearchクラスタにアクセスします。まずはsecretsに自動的に保存されているelasticユーザー用パスワードを次のように取得します。

export NAMESPACE=testeck
export PASSWORD=$(kubectl get secret ecksandbox-es-elastic-user -n ${NAMESPACE} -o go-template='{{.data.elastic | base64decode}}')

echo $PASSWORD
2LIh4PY5XUAejd85d9c3q461

次に、Elasticsearchクラスタ用に作成されたserviceを取得します。ecksandbox-es-httpが接続対象のserviceになります。

kubectl get svc -n testeck

NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
ecksandbox-es-data-nodes     ClusterIP   None             <none>        9200/TCP   2m50s
ecksandbox-es-http           ClusterIP   10.100.237.243   <none>        9200/TCP   2m52s
ecksandbox-es-master-nodes   ClusterIP   None             <none>        9200/TCP   2m50s
ecksandbox-es-transport      ClusterIP   None             <none>        9300/TCP   2m52s

kubectl port-forwardを使ってローカルマシンからElasticsearchのecksandbox-es-httpにポート9200にアクセスできるようにポートフォワードします。

kubectl port-forward service/ecksandbox-es-http 9200 -n testeck

Forwarding from 127.0.0.1:9200 -> 9200
Forwarding from [::1]:9200 -> 9200

最後に、さきほど取得したelasticユーザー用パスワードを指定してElasticsearchクラスタにリクエストを送信すると、次のような結果が得られます。


curl -u "elastic:$PASSWORD" -k "https://localhost:9200"

{
  "name" : "ecksandbox-es-master-nodes-0",
  "cluster_name" : "ecksandbox",
  "cluster_uuid" : "Jdcikd2dSPqlPGR9uj2hqA",
  "version" : {
    "number" : "7.10.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96",
    "build_date" : "2020-11-09T21:30:33.964949Z",
    "build_snapshot" : false,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

テストデータをIngestして検索してみる

Elastic社の公式クイックスタートガイドを参考に上記で作成したElasticsearchクラスタに次のようにテストデータをIngestします。

さきほどと同じようにローカルマシンからElasticsearchのecksandbox-es-httpにアクセスできるようにポートフォワードします。既にポートフォワードされている場合はこちらのステップは省略ください。

kubectl port-forward service/ecksandbox-es-http 9200 -n testeck

次に、テストデータを取得して、bulk APIを使ってElasticsearchクラスタにデータをBulkでインジェストします。ここではターゲットindexをbankとしています。

# テストデータ取得
curl -o accounts.json https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json

# Bulkインジェスト
curl -u "elastic:$PASSWORD" -k -H "Content-Type: application/json" -XPOST "https://localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@accounts.json"

cat indices APIでインデックスを確認するとプライマリとレプリカが1つずつの構成で、1000件のドキュメントがbankインデックスに格納されていることがわかります。

curl -u "elastic:$PASSWORD" -k "https://localhost:9200/_cat/indices?v"

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   bank  TyjMvOOCQDiNZNqwNHSNQA   1   1       1000            0      394kb          394kb

ECKの仕組み

Elastic Operator

ECKは、Elastic Operatorを使ってKubernetes上でのElasticsearchやKinanaの設定・管理を自動化します。Elastic Operatorが行う処理に、クラスタのデプロイメント、クラスタ設定変更やアップグレード、ノード数のスケールアウトやスケールイン、バックアップなどがあります。機能について詳しくはこちらを参照ください。

次のイメージは、Elastic OperatorによるElasticsearchや、Kibanaリソースのデプロイまでの流れを表しています。利用ユーザーがElasticsearchや、Kibanaリソースを定義するCRD(Custom Resource Definition)のYAMLを作成してk8sにapplyすると、Elastic Operatorがそれに基づいて、Elasticsearchや、Kibanaリソースをデプロイ、もしくは変更します。さきほど行ったElasticsearchクラスタecksandboxのデプロイメントも、まさにこの流れで実施されます。

eck-elastic-operator.png

NodeSetsとStatefulSetについて

Elastic Operatorは、クラスタ内の同一Elasticsearch構成のノードグループを表すNodeSetsをつかってElasticsearchクラスターのトポロジー設定を行います。このNodeSetsの実体はStatefulSetです。通常、Elasticsearchのmasterノードやdataノードは個別のNodeSetsを設定しますが、この場合は別々のStatefulSetでそれぞれのPodが管理されることになります。以下、NodeSetsの定義と、定義ごとに別々のStatefulSetが作られるイメージになります。NodeSetsについて詳しくは公式ページのNode orchestrationを参照ください。

eck-nodesets.png

上述の通り、NodeSetsはStatefulSetリソースとしてデプロイされるので、ECKによる各構成変更の挙動を理解するにはStatefulSetを理解しておく必要があります。 以下、構成や設定変更時の挙動理解のために抑えておくべきポイントを簡単に解説します。

ポイント1: StatefulSetにおける各Podへの個別のPVC、PVの割当て

StatefulSetはvolumeClaimTemplateの定義にもとづき、各Podに個別のPVC(PersistentVolumeClaim)、PV(Persistent Volume)を割り当てます。
例えば、さきほど行ったecksandboxクラスタのdata-nodesノードでは、次のようにvolumeClaimTemplatesで各Podが2GBのEBS volume(gp2)を割り当てる設定をしています。

  nodeSets:
  - name: data-nodes
    count: 1
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 2Gi
        storageClassName: gp2

これで、各Podには個別のPVC、PVが割り当てられます。一方、k8sにはReplicaSetがありますが、ReplicaSetの場合は、同一ReplicaSetのすべてのPodには同じPVC、PVが割り当てられます。以下、ReplicaSetとStatefulSetのPVC、PV割り当ての比較イメージになります。

eck-replicaset-vs-statefulset.png

参考までに、さきほど行ったElasticsearchクラスタecksandboxのデプロイメントではmaster-nodes(3ノード)とdata-nodes(1ノード)の2種類のNodeSets、つまり2つのStatefulSetをデプロイしてます。それぞれのPodとPVC、PVの割当状況は次のとおりとなります。

kubectl get po,sts,pv,pvc -n testeck

NAME                               READY   STATUS    RESTARTS   AGE
pod/ecksandbox-es-data-nodes-0     1/1     Running   0          7h10m
pod/ecksandbox-es-master-nodes-0   1/1     Running   0          7h10m
pod/ecksandbox-es-master-nodes-1   1/1     Running   0          7h10m
pod/ecksandbox-es-master-nodes-2   1/1     Running   0          7h10m

NAME                                          READY   AGE
statefulset.apps/ecksandbox-es-data-nodes     1/1     7h10m
statefulset.apps/ecksandbox-es-master-nodes   3/3     7h10m

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
persistentvolume/pvc-265d9044-5111-4e54-9667-a741c7537043   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-2   gp2                     7h10m
persistentvolume/pvc-299aff52-cfff-4b5b-a847-5f4bdf528f8f   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-0   gp2                     7h10m
persistentvolume/pvc-d7ff409d-f731-4f02-b26e-c67fd3662941   2Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-data-nodes-0     gp2                     7h10m
persistentvolume/pvc-e40bcf99-0e57-48e7-acc8-d19224b67665   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-1   gp2                     7h10m

NAME                                                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-data-nodes-0     Bound    pvc-d7ff409d-f731-4f02-b26e-c67fd3662941   2Gi        RWO            gp2            7h10m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-0   Bound    pvc-299aff52-cfff-4b5b-a847-5f4bdf528f8f   1Gi        RWO            gp2            7h10m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-1   Bound    pvc-e40bcf99-0e57-48e7-acc8-d19224b67665   1Gi        RWO            gp2            7h10m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-2   Bound    pvc-265d9044-5111-4e54-9667-a741c7537043   1Gi        RWO            gp2            7h10m

ポイント2: Pod実行順序(作成は番号が低いものから、更新・削除は高いものから)

StatefulSetにおいて各Pod名には0からはじまりN-1まで(Nはレプリカ数)の整数値が順番に割り当てられます。
例えば、先ほどデプロしたElasticsearchクラスタecksandboxのmasterノード用のStatefulSetはレプリカ数3で、つまり3Podで構成されますが、次のように各Pod名には0〜2 (3-1)の整数値が割りあてられています。

kubectl get pods -n testeck

NAME                           READY   STATUS    RESTARTS   AGE
ecksandbox-es-master-nodes-0   1/1     Running   0          6h25m
ecksandbox-es-master-nodes-1   1/1     Running   0          6h25m
ecksandbox-es-master-nodes-2   1/1     Running   0          6h25m
...

同一StatefulSetにおいてPodの作成は番号が低いものから順番に1つずつ行われます。一方、更新・削除はPodの番号が高いもの順に1つずつ行われます。

例えば、3レプリカのStatefulSetが0にスケールインするときは、Podの更新・削除にあたるのでPodの番号が高いものから順(2->1->0)に削除されます。一方、PodがスケールアウトするときはPodが番号の低いもの順(0->1->2)で作成されます。

もう一点、スケールインしてからスケールアウトするようなケースで、抑えておくべき重要なポイントに、同一PVC、PVは切り離されたあともそのままで、再びスケールアウト時に同じ番号のPodに割り当てられることです。以下のイメージは、3レプリカのStatefulSetが1Podにスケールインしてから再び3Podにスケールアウトする処理の流れを表します。スケールイン時に1と2のPodはPVC、PVCが切り離されますが、それらはそのままで、再びスケールアウトの際に同じ番号のPodに割り当てられます。

eck-scale-in-out.png

これらの挙動は、データを失うことなくPodの変更、すなわち構成変更を可能にするための基本動作になります。

各構成変更とその挙動

ノードのスケールアウト・スケールイン

ノードのスケールアウト・スケールインは基本的に、NodeSetsのcountを変更して行います。これは上述の通りStatefulSetのスケールアウト・スケールインになります。よって、クラスタは無停止で1つずつレプリカが更新されます。ただし、以下の条件においてはクラスタ可用性が保証されないのでご注意ください。

  • シングルノードのElasticsearchクラスタ
  • Elasticsearchクラスタのインデックスにレプリカがない

それでは以下のYAMLをapplyして、先ほどデプロしたElasticsearchクラスタecksandboxdata-nodesノードを3レプリカにスケールアウトさせてみます。


cat <<EOF | kubectl apply -n testeck -f -

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: ecksandbox
spec:
  version: 7.10.0
  nodeSets:
  - name: master-nodes
    count: 3
    config:
      node.store.allow_mmap: false
      node.roles: ["master"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: gp2
  - name: data-nodes
    count: 3
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 2Gi
        storageClassName: gp2
EOF

上記を実行すると、次のようにdata-nodesのStatefulSetが3レプリカに拡張し、また順番に各PodにPVC、PVが割り当てられることがわかります。

kubectl get elasticsearch,po,sts,pv,pvc -n testeck

NAME                                                    HEALTH   NODES   VERSION   PHASE   AGE
elasticsearch.elasticsearch.k8s.elastic.co/ecksandbox   yellow   4       7.10.0    Ready   7h38m

NAME                               READY   STATUS    RESTARTS   AGE
pod/ecksandbox-es-data-nodes-0     1/1     Running   0          7h38m
pod/ecksandbox-es-data-nodes-1     0/1     Running   0          29s
pod/ecksandbox-es-data-nodes-2     0/1     Running   0          29s
pod/ecksandbox-es-master-nodes-0   1/1     Running   0          7h38m
pod/ecksandbox-es-master-nodes-1   1/1     Running   0          7h38m
pod/ecksandbox-es-master-nodes-2   1/1     Running   0          7h38m

NAME                                          READY   AGE
statefulset.apps/ecksandbox-es-data-nodes     1/3     7h38m
statefulset.apps/ecksandbox-es-master-nodes   3/3     7h38m

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
persistentvolume/pvc-1acf4843-0563-4d2d-95d3-0332515c985d   2Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-data-nodes-2     gp2                     23s
persistentvolume/pvc-265d9044-5111-4e54-9667-a741c7537043   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-2   gp2                     7h38m
persistentvolume/pvc-299aff52-cfff-4b5b-a847-5f4bdf528f8f   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-0   gp2                     7h38m
persistentvolume/pvc-31440203-06d5-4d00-947d-3f431b84a381   2Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-data-nodes-1     gp2                     23s
persistentvolume/pvc-d7ff409d-f731-4f02-b26e-c67fd3662941   2Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-data-nodes-0     gp2                     7h38m
persistentvolume/pvc-e40bcf99-0e57-48e7-acc8-d19224b67665   1Gi        RWO            Delete           Bound    testeck/elasticsearch-data-ecksandbox-es-master-nodes-1   gp2                     7h38m

NAME                                                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-data-nodes-0     Bound    pvc-d7ff409d-f731-4f02-b26e-c67fd3662941   2Gi        RWO            gp2            7h38m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-data-nodes-1     Bound    pvc-31440203-06d5-4d00-947d-3f431b84a381   2Gi        RWO            gp2            29s
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-data-nodes-2     Bound    pvc-1acf4843-0563-4d2d-95d3-0332515c985d   2Gi        RWO            gp2            29s
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-0   Bound    pvc-299aff52-cfff-4b5b-a847-5f4bdf528f8f   1Gi        RWO            gp2            7h38m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-1   Bound    pvc-e40bcf99-0e57-48e7-acc8-d19224b67665   1Gi        RWO            gp2            7h38m
persistentvolumeclaim/elasticsearch-data-ecksandbox-es-master-nodes-2   Bound    pvc-265d9044-5111-4e54-9667-a741c7537043   1Gi        RWO            gp2            7h38m

ノードのスケール変更に合わせてレプリカ数を自動伸縮

ノードのスケール変更に合わせてレプリカ数を自動で伸縮させることができます。レプリカの自動拡張は、主にインデックスにシャードが1つの場合には純粋にノード数に合わせて線形増加させるだけでよいのでとても有効です。

次のようにインデックスにindex.auto_expand_replicasを設定することで、クラスター内のdataノードの数に基づいて、レプリカの数を自動拡張します。設定については、ダッシュで区切られた下限値-上限値(例:0-5)に設定するか、上限に全てを意味するallを使用します(例:0-all)。ここでは、先ほど作成したbankインデックスに完全にdataノード数に基づいてレプリカの数を自動拡張することを意味する0-allを設定します。


INDEX_NAME="bank"
curl -u "elastic:$PASSWORD" -k -XPUT "https://localhost:9200/${INDEX_NAME}/_settings" -H 'Content-Type: application/json' -d'
{
 "index" : {
    "auto_expand_replicas": "0-all"
  }
}'

なお、インデックス設定について詳しくはこちらのページを参照ください。

これで、ノードのスケールアウト・スケールインでやったようにdataノード数を変更すると、それに基づきレプリカ数がN-1で増減します。レプリカ数の確認は次のコマンドで確認ください(ポートフォワードすることをお忘れなく)。repのフィールドがレプリカ数になります。

curl -u "elastic:$PASSWORD" -k "https://localhost:9200/_cat/indices?v"

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   bank  TyjMvOOCQDiNZNqwNHSNQA   1   3       1000            0      394kb          394kb

NodeSetの追加

ElasticsearchクラスタへのNodeSetの新規追加はクラスタ無停止で行われます。
例えばdata-nodes2のような新しいNodeSetsをElasticsearchクラスタに追加すると、Elastic Operatorはそれに応じた新しいStatefulSetを作成します。また、TLS証明書やElasticsearch設定のためのSecretsやConfigMapを自動的に作成します。

Volumeサイズの拡張

2020年12月時点では、こちらのStatefulSet実装の制限のためStatefulSetにアタッチされているPVCのVolumeサイズをダイナミックに変更することはできないようです。つまりvolumeClaimTemplatesのストレージサイズを変更してもPVCがストレージ拡張をサポートしない、PVCストレージ拡張がサポートされていてもStatefulSetが最初のVolumeを掴むためにいづれにせよできないということのようです。

  - name: data-nodes
    count: 2
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 3Gi  <<<ここを増やす
        storageClassName: gp2

ワークアラウンドとして共有されている方法は、次のようにNodeSetの名前を変更(data-nodes2)して、ストレージサイズを変更して、そのYAMLをapplyする方法になります。Elastic Operatorは新規NodeSetdata-nodes2のためにPodを作成して、旧Podのデータを自動的に新Podに移行します。データ移行が終了すると、旧ポッドが自動的に削除されます。

  - name: data-nodes2
    count: 2
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 3Gi
        storageClassName: gp2

NodeSet.specの更新

既存のNodeSetの仕様が更新されます。 Elasticsearch設定や、podTemplateを更新するといったNodeSet.specの更新がされる場合は、Elastic Operatorは、対応するElasticsearchノードのローリングアップグレードを実行します。Elasticsearchのローリングアップグレードに従い、可能な限りElasticsearchクラスターの可用性を維持しながら、関連するPodを更新します。通常、この処理ではElasticsearchノードが1つずつ再起動されます。

NodeSet.spec更新例

  • ES Configs like JVMヒープサイズ
  • PodTemplateの更新(仮想メモリ設定、Pluginインストール設定)

なお、ノードスケール変更と同様に、以下の条件下においてはクラスタ可用性が保証されないのでご注意ください。

  • シングルノードのElasticsearchクラスタ
  • Elasticsearchクラスタのインデックスにレプリカがない

仮想メモリ設定例

次のようにpodTemplateを変更して仮想メモリを設定することができます。仮想メモリ設定について詳細はこちらを参照ください。

  nodeSets:
  - name: master-nodes
    count: 3
    podTemplate:
      spec:
        initContainers:
        - name: sysctl
          securityContext:
            privileged: true
          command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']

pluginインストール例

次のようにpodTemplateを変更してpluginをインストールすることができます。pluginインストール設定について詳細はこちらを参照ください。

  - name: data-nodes
    count: 2
    config:
      node.store.allow_mmap: false
      node.roles: ["data", "ingest"]
    podTemplate:
      spec:
        initContainers:
        - name: install-plugins
          command:
          - sh
          - -c
          - |
            bin/elasticsearch-plugin install --batch analysis-icu

Elasticsearchクラスタのアップグレード

ノードのスケールアウト・スケールインと同様に、新規Podが1つずつ作成され、無停止でアップグレードを行うことが可能です。ただし、バージョンを下げることはできません。

先ほどデプロしたElasticsearchクラスタecksandbox7.10.0でしたが、次のようにspec.versionで新しいバージョン7.10.1を指定することで自動アップグレード処理が開始されます。

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: ecksandbox
spec:
  version: 7.10.1
  nodeSets:
  - name: master-nodes
    count: 3
    config:
      node.store.allow_mmap: false
      node.roles: ["master"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: gp2

まとめ

ECKはかなりの部分がElastic Operatorで自動化されていて、運用管理が単純化されることが理解できたのではないかと思います。また、自動化されている処理についてはStatefulSetが重要な役割を担っており、この挙動の理解が必須かと思います。今回ストレージ周りの挙動については触れませんでしたが安定した運用を行うためにこちらについても十分な理解が必要かと思います。
以上長くなってしまいましたが、ECKの仕組みと各構成変更における挙動について簡単に説明させていただきました。ご一読いただきありがとうございました。

Have a happy ECK life!

25
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?