Elastic Cloud on Kubernetes (ECK)とは
Elastic Cloud on Kubernetes(ECK)は、ElasticsearchとKibanaのデプロイと管理をKubernetes上で効率化するオープンソースソフトウェアです。Kubernetesのネイティブな能力を活用して、Elastic Stackのスケーラビリティ、復元力、そしてフレキシビリティを最大化します。自動化された運用管理により、Elastic Stackの運用コストと複雑さを大幅に削減することができます。
今回はLinode Kubernetes Engine (LKE) を利用してECKを構築する方法を紹介します。
構成は以下になります。
Linode Kubernetes Engine (LKE)の作成
Linode Cloud ManagerからLKEを作成し、kubeconfigをダウンロードします。
今回は Linode 8GB x 3台の構成としています。
尚、Linode 8GB 以下のスペックの場合リソース不足になり起動できませんのでご注意ください。
kubectlを実行する端末でconfigをexportします。
export KUBECONFIG=./elasticcloud-kubeconfig.yaml
node一覧が表示されることを確認します。
kubectl get nodes
NAME STATUS ROLES AGE VERSION
lke116066-172974-649c6380580d Ready <none> 42h v1.26.3
lke116066-172974-649c6380c34c Ready <none> 94m v1.26.3
lke116066-172974-649c63812a91 Ready <none> 42h v1.26.3
cert-managerを構築する
Kibana、Elasticsearchで利用する証明書を発行します。
今回はDNS認証を利用します。またDNSにはAkamai Edge DNSを利用します。
手順に関しては以下を参考にします。
apiVersion: v1
kind: Secret
metadata:
name: akamai-secret
type: Opaque
stringData:
clientSecret: <Clinet Secret>
accessToken: <Access Token>
clientToken: <Clinet Token>
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-akamai-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: example@mail.com
privateKeySecretRef:
name: letsencrypt-akamai-issuer-account-key
solvers:
- dns01:
akamai:
serviceConsumerDomain: <Hostname>
clientTokenSecretRef:
name: akamai-secret
key: clientToken
clientSecretSecretRef:
name: akamai-secret
key: clientSecret
accessTokenSecretRef:
name: akamai-secret
key: accessToken
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: eck-zone
spec:
secretName: akamai-crt-secret
dnsNames:
- 'elasticsearch.example.com'
- 'kibana.example.com'
issuerRef:
name: letsencrypt-akamai-dns
kind: Issuer
cert-managerをインストールします。
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
podのStatusがRunningであることを確認します。
kubectl get pods --namespace cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-579d48dff8-84nw9 1/1 Running 3 1m
cert-manager-cainjector-789955d9b7-jfskr 1/1 Running 3 1m
cert-manager-webhook-64869c4997-hnx6n 1/1 Running 0 1m
リソースを作成します。
kubectl apply -f cert.yaml
作成中のCertificateの進捗状況を確認します。
DNSのレコード作成と認証に数分時間がかかります。
kubectl describe certificate eck-zone
Name: eck-zone
Namespace: default
Labels: <none>
Annotations: <none>
API Version: cert-manager.io/v1
Kind: Certificate
Metadata:
Creation Timestamp: 2023-06-26T17:20:56Z
Generation: 1
Managed Fields:
API Version: cert-manager.io/v1
Fields Type: FieldsV1
~~~~~~~
認証が完了しない場合には、ログを確認して問題を特定します。
kubectl logs --namespace cert-manager cert-manager-74654c4948-qhzng
作成された証明書を確認します。
kubectl get certificate --all-namespaces
NAMESPACE NAME READY SECRET AGE
default eck-zone True akamai-crt-secret 34h
以上で証明書の準備完了です。
Elastic Cloud on Kubernetes (ECK)のインストール
以下の手順を参考に、ECKの構築を行います。
ECKをインストールします。
kubectl create -f https://download.elastic.co/downloads/eck/2.8.0/crds.yaml
オペレーターをデプロイします。
kubectl apply -f https://download.elastic.co/downloads/eck/2.8.0/operator.yaml
Elasticsearch clusterの構築
Elasticsearchを構築します。
今回は、Pod数を3として、ディスクを300GB付与、証明書の設定を行っています。
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 8.8.1
nodeSets:
- name: master-nodes
count: 3
config:
node.roles: ["master"]
node.store.allow_mmap: false
- name: data-nodes
count: 3
config:
node.roles: ["data", "ingest", "ml", "transform"]
node.store.allow_mmap: false
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 300Gi
http:
tls:
certificate:
secretName: akamai-crt-secret
作成したファイルを適用します。
kubectl apply -f elasticsearch.yaml
Podが起動できているか確認をします。
kubectl get pods --selector='elasticsearch.k8s.elastic.co/cluster-name=quickstart'
NAME READY STATUS RESTARTS AGE
quickstart-es-data-nodes-0 1/1 Running 0 34m
quickstart-es-data-nodes-1 1/1 Running 0 34m
quickstart-es-data-nodes-2 1/1 Running 0 34m
quickstart-es-master-nodes-0 1/1 Running 0 34m
quickstart-es-master-nodes-1 1/1 Running 0 34m
quickstart-es-master-nodes-2 1/1 Running 0 34m
Linode NodeBalancerを付与して、外部からアクセスできるようにします。
apiVersion: v1
kind: Service
metadata:
name: elasticsearch-loadbalancer
spec:
selector:
common.k8s.elastic.co/type: elasticsearch
elasticsearch.k8s.elastic.co/cluster-name: quickstart
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 9200
targetPort: 9200
作成した設定を展開します。
kubectl apply -f elasticsearch-service.yaml
ロードバランサーが作成されていることを確認します。
kubectl get svc elasticsearch-loadbalancer
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-loadbalancer LoadBalancer 10.128.69.96 xxx.xxx.xxx.xxx 9200:32334/TCP 46h
Akamai EdgeDNSにレコードを追加して名前解決できるようにします。
dig elasticsearch.example.com +noall +ans
; <<>> DiG 9.10.6 <<>> elasticsearch.example.com +noall +ans
;; global options: +cmd
elasticsearch.example.com 1748 IN CNAME xxx-xxx-xxx-xxx.ip.linodeusercontent.com.
xxx-xxx-xxx-xxx.ip.linodeusercontent.com. 86348 IN A xxx.xxx.xxx.xxx
Kibanaの構築
以下のサイトを参考に、Kibanaを構築します。
Elasticsearchに関連付けを行い、証明書の設定も行います。
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: quickstart
spec:
version: 8.8.1
count: 3
elasticsearchRef:
name: quickstart
http:
tls:
certificate:
secretName: akamai-crt-secret
作成したyamlを展開します。
kubectl apply -f kibana.yaml
kibanaが起動していることを確認します。
kubectl get kibana
NAME HEALTH NODES VERSION AGE
quickstart green 3 8.8.1 41h
podのステータスが正常であることを確認します。
kubectl get pod --selector='kibana.k8s.elastic.co/name=quickstart'
NAME READY STATUS RESTARTS AGE
quickstart-kb-694658999d-hmwzz 1/1 Running 0 41h
quickstart-kb-694658999d-vbtwv 1/1 Running 0 41h
quickstart-kb-694658999d-z6x8h 1/1 Running 0 41h
Linode NodeBalancerを付与して、外部からアクセスできるようにします。
apiVersion: v1
kind: Service
metadata:
name: kibana-loadbalancer
spec:
selector:
common.k8s.elastic.co/type: kibana
kibana.k8s.elastic.co/name: quickstart
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 5601
targetPort: 5601
作成したファイルを展開します。
kubectl apply -f kibana-service.yaml
ロードバランサーが作成されていることを確認します。
kubectl get svc kibana-loadbalancer
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kibana-loadbalancer LoadBalancer 10.128.192.34 xxx.xxx.xxx.xxx 5601:30541/TCP 2d2h
Akamai EdgeDNSにレコードを追加して名前解決できるようにします。
dig kibana.example.com +noall +ans
; <<>> DiG 9.10.6 <<>> kibana.example.com +noall +ans
;; global options: +cmd
elasticsearch.example.com 1748 IN CNAME xxx-xxx-xxx-xxx.ip.linodeusercontent.com.
xxx-xxx-xxx-xxx.ip.linodeusercontent.com. 86348 IN A xxx.xxx.xxx.xxx
Elasticsearchの設定追加
こちらの記事を参考に設定の追加を行います。
KibanaとElasticsearchに接続する際のパスワードを変数に入れます。
export PASSWORD=`kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode; echo`
インデックスを作成します。
ElasticsearchのIndex Template、フィールドの型定義をしています。
curl -u elastic:$PASSWORD -X POST -H 'Content-Type: application/json' -d "$(curl -s https://raw.githubusercontent.com/isss802/stackscripts/main/elasticsearch-kibana/elasticsearch_index_template.json)" https://elasticsearch.example.com:9200/_index_template/logs-akamai.datastream2
パイプラインを3つ作成します。
ElasticsearchのIngest Pipelineで、送られてきたDS2のフィールドを一部加工するための定義です。
curl -u elastic:$PASSWORD -X PUT -H 'Content-Type: application/json' -d "$(curl -s https://raw.githubusercontent.com/isss802/stackscripts/main/elasticsearch-kibana/elasticsearch_ingest_pipeline.json)" https://elasticsearch.example.com:9200/_ingest/pipeline/datastream2-ingest-pipeline
curl -u elastic:$PASSWORD -X PUT -H 'Content-Type: application/json' -d "$(curl -s https://raw.githubusercontent.com/isss802/stackscripts/main/elasticsearch-kibana/elasticsearch_ingest_pipeline_breadcrumbs.json)" https://elasticsearch.example.com:9200/_ingest/pipeline/datastream2-ingest-pipeline-breadcrumbs
curl -u elastic:$PASSWORD -X PUT -H 'Content-Type: application/json' -d "$(curl -s https://raw.githubusercontent.com/isss802/stackscripts/main/elasticsearch-kibana/elasticsearch_ingest_pipeline_cmcd.json)" https://elasticsearch.example.com:9200/_ingest/pipeline/datastream2-ingest-pipeline-cmcd
以上で、elasticsearchの設定は完了です。
Kibana追加設定
Kibanaのダッシュボードの設定を行うため、Saved ObjectsのファイルをPOSTします。
curl -o kibana.ndjson https://raw.githubusercontent.com/hokamoto/stackscripts/main/elasticsearch-kibana/kibana_saved_objects.ndjson && curl -u elastic:$PASSWORD -X POST "https://elasticsearch.example.com:5601/api/saved_objects/_import" -H 'kbn-xsrf: reporting' --form file=@./kibana.ndjson
以上でKibanaの設定は完了です。
DataStream2の設定
以下の記事を参考に、DataStream2の設定を行いログを確認します。
ダッシュボードからグラフが確認できたら構築は完了です。
Elasticsearchのディスク拡張
運用していくにつれてディスク拡張が必要になる場合があります。
今回は、試しに300GBから350GBにサイズを拡張してみます。
その場合はまず、storageの値を変更する必要があります。
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 8.8.1
nodeSets:
- name: master-nodes
count: 3
config:
node.roles: ["master"]
node.store.allow_mmap: false
- name: data-nodes
count: 3
config:
node.roles: ["data", "ingest", "ml", "transform"]
node.store.allow_mmap: false
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
#容量追加
storage: 350Gi
http:
tls:
certificate:
secretName: akamai-crt-secret
設定を反映します。
kubectl apply -f elasticsearch.yaml
Capacityが増強されていることを確認します。
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
elasticsearch-data-quickstart-es-data-nodes-0 Bound pvc-d39ec344188f4155 350Gi RWO linode-block-storage-retain 41h
elasticsearch-data-quickstart-es-data-nodes-1 Bound pvc-b68538a685fe4cbf 350Gi RWO linode-block-storage-retain 41h
elasticsearch-data-quickstart-es-data-nodes-2 Bound pvc-4459f647a6d3415b 350Gi RWO linode-block-storage-retain 41h
elasticsearch-data-quickstart-es-master-nodes-0 Bound pvc-e17373e2b5044f2b 10Gi RWO linode-block-storage-retain 41h
elasticsearch-data-quickstart-es-master-nodes-1 Bound pvc-40bf519cece641df 10Gi RWO linode-block-storage-retain 41h
elasticsearch-data-quickstart-es-master-nodes-2 Bound pvc-cc30b10ff06141ea 10Gi RWO linode-block-storage-retain 41h
対象のnodeを再起動したいのでdrainします。
kubectl drain lke116066-172974-649c63812a91 --ignore-daemonsets --delete-emptydir-data
Linode Cloud Managerから対象のインスタンスを再起動します。
再起動後にサービスに戻すため、uncordonします。
kubectl uncordon lke116066-172974-649c63812a91
resize2fsを利用してディスクを拡張する必要があるため、kubectl-node-shellを利用してnodeに接続します。
kubectl get node
NAME STATUS ROLES AGE VERSION
lke116066-172974-649c6380580d Ready <none> 40h v1.26.3
lke116066-172974-649c6380c34c Ready <none> 13m v1.26.3
lke116066-172974-649c63812a91 Ready <none> 40h v1.26.3
対象のNodeに接続します。
kubectl node-shell lke116066-172974-649c6380c34c
ディスクを確認します。
df -h
リサイズします。
resize2fs /dev/disk/by-id/scsi-0Linode_Volume_pvcd39ec344188f4155
ディスクが拡張できていれば作業完了です。
df -h /dev/disk/by-id/scsi-0Linode_Volume_pvc4459f647a6d3415b
Filesystem Size Used Avail Use% Mounted on
/dev/disk/by-id/scsi-0Linode_Volume_pvc4459f647a6d3415b 344G 21M 344G 1% /var/lib/kubelet/pods/bf2e34e2-cec6-4eed-aff0-f02164737084/volumes/kubernetes.io~csi/pvc-4459f647a6d3415b/mount
root@lke116066-172974-649c6380c34c:/#
podが偏り気になる際にはDeschedulerなどの利用を検討すると良いかと思います。
まとめ
Linode Kubernetes Engine (LKE)を利用することで拡張しやすいElastic Cloud on Kubernetes (ECK)を構築することができました。
ぜひ様々なシステムでLKEを活用していただければと思います。
関連記事
アカマイ・テクノロジーズ合同会社はQiitaでAkamai's cloud computing services関連など開発者向けの記事を掲載しております。