3
0

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 1 year has passed since last update.

Elastic Cloud on Kubernetes (ECK)をLinode Kubernetes Engine (LKE) で構築してAkamaiのログを可視化する

Last updated at Posted at 2023-07-21

Elastic Cloud on Kubernetes (ECK)とは

Elastic Cloud on Kubernetes(ECK)は、ElasticsearchとKibanaのデプロイと管理をKubernetes上で効率化するオープンソースソフトウェアです。Kubernetesのネイティブな能力を活用して、Elastic Stackのスケーラビリティ、復元力、そしてフレキシビリティを最大化します。自動化された運用管理により、Elastic Stackの運用コストと複雑さを大幅に削減することができます。
今回はLinode Kubernetes Engine (LKE) を利用してECKを構築する方法を紹介します。

構成は以下になります。

image.png

Linode Kubernetes Engine (LKE)の作成

Linode Cloud ManagerからLKEを作成し、kubeconfigをダウンロードします。

今回は Linode 8GB x 3台の構成としています。
尚、Linode 8GB 以下のスペックの場合リソース不足になり起動できませんのでご注意ください。

image.png

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を利用します。

手順に関しては以下を参考にします。

cert.yaml
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付与、証明書の設定を行っています。

elasticsearch.yaml
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を付与して、外部からアクセスできるようにします。

elasticsearch-service.yaml
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に関連付けを行い、証明書の設定も行います。

kibana.yaml
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を付与して、外部からアクセスできるようにします。

kibana-service.yaml
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の設定を行いログを確認します。

ダッシュボードからグラフが確認できたら構築は完了です。

image.png

Elasticsearchのディスク拡張

運用していくにつれてディスク拡張が必要になる場合があります。

今回は、試しに300GBから350GBにサイズを拡張してみます。

その場合はまず、storageの値を変更する必要があります。

elasticsearch.yaml
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関連など開発者向けの記事を掲載しております。

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?