はじめに
ECKというElasticsearchをKubernetes上にデプロイできるECK Operatorを使って、Elasticsearchクラスターを構築しKibanaを外部公開するまでを試してみた。
また、Kubernetesがクラウド間の差分を吸収してくれるというのを耳にしたことがあったので、GKE(GCP)とEKS(AWS)上で同じKubernetesマニフェストで実際にECKが動くのか試してみた。
目的としては、Kubernetesを触ったことがなかったので、学習目的で触ってみたかったのと、近々Elasticsearchを使う機会がありそうなため。
要約
- Kubernetesクラスター作成含め、コマンド計4回でElasticsearchクラスターが構築できた。
- GKE、EKSで同じマニフェストでElasticsearchクラスタを作成して外部接続できた。
- Type: LoadBalanecerを指定すると、若干性質が異なるLBが作成される。(GKEはネットワークロードバランサーが、EKSはCLBが作成される)
- Kubernetesの学習目的であれば、1クラスターが無料で使えるGKEを選んだほうがよさそう。
構成図
- Node2台構成で、Elasticsearch用Podを2台、Kibana用Podを1台配置
- LoadBalancerでは、SSLオフロードせず各Podの同一ポートにバランシングする
- 各PodでSSL終端する(ECK側で持っている自己証明書を使用)
構築手順
事前準備(共通)
ECK on GKE
事前準備
- CLIでGCPリソースを操作できるように、CloudSDKをインストールする
GKE Cluster作成
-
以下のコマンドを実行する
- eck-learnというクラスター名でデータノードとしてEC2(n1-standard-1)を2台が作成される
- 作成に3分程度かかる
gcloud container clusters create eck-learn \ --zone=asia-northeast1-a \ --cluster-version=latest \ --enable-ip-alias \ --num-nodes=2
-
kubectlにてnode状態を確認する。(status: ReadyになっていればOK)
$ kubectl get nodes NAME STATUS ROLES AGE VERSION gke-eck-learn-default-pool-feb7e9ae-23k1 Ready <none> 47h v1.16.11-gke.5 gke-eck-learn-default-pool-feb7e9ae-x7zl Ready <none> 47h v1.16.11-gke.5
ECK作成
※ こちらを参考に実施
ECK operatorをインストール
-
ECK operatorをapplyする
$ kubectl apply -f https://download.elastic.co/downloads/eck/1.1.2/all-in-one.yaml
-
kubectl get svc にて状態を確認する(elastic-webhook-serverが表示されればOK)
$ kubectl get svc -n elastic-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elastic-webhook-server ClusterIP 10.0.0.38 <none> 443/TCP 110s
ElasticsearchをDeploy
- manifestを作成する
- 接続元を制限したい場合は「loadBalancerSourceRanges」に許可IPを入力する
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 7.8.0
nodeSets:
- name: default
count: 2
config:
node.master: true
node.data: true
node.ingest: true
node.store.allow_mmap: false
http:
service:
spec:
type: LoadBalancer
# Ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-services.html
# https://kubernetes.io/docs/concepts/services-networking/service
loadBalancerSourceRanges:
- "xxx.xxx.xxx.xxx/32"
-
kubectl applyを実行
$ kubectl apply -f eck-elascticsearch.yaml
-
kubectl get pod にてpod状態を確認する(RunningになればOK)
$ kubectl get pod NAME READY STATUS RESTARTS AGE quickstart-es-default-0 1/1 Running 0 63s
-
kubectl get svc にてservice状態を確認する
-
quickstart-es-http
にEXTERNAL-IPが振られていればOK - GKEの場合は、EXTERNAL-IPがLBに振られたグローバルIPになる
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 14m quickstart-es-default ClusterIP None <none> <none> 2m40s quickstart-es-http LoadBalancer 10.0.12.244 xxx.xxx.xxx.xxx 9200:30834/TCP 2m41s quickstart-es-transport ClusterIP None <none> 9300/TCP 2m41s
-
-
Elasticsearchに接続するためのパスワードを取得する
$ PASSWORD=$(kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode)
-
Elasticsearchに接続する(以下のような出力が返ればOK)
※ xxx.xxx.xxx.xxxはkubectl get svc
で出力されるquickstart-es-http
のEXTERNAL-IP
を入力する$ curl -u "elastic:$PASSWORD" -k https://xxx.xxx.xxx.xxx:9200 { "name" : "quickstart-es-default-0", "cluster_name" : "quickstart", "cluster_uuid" : "p_wTfmIdQZ2Wt6Maq3wEDg", "version" : { "number" : "7.8.0", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "757314695644ea9a1dc2fecd26d1a43856725e65", "build_date" : "2020-06-14T19:35:50.234439Z", "build_snapshot" : false, "lucene_version" : "8.5.1", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
KibanaをDeploy
- manifestを作成する
- 接続元を制限したい場合は「loadBalancerSourceRanges」に許可IPを入力する
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: quickstart
spec:
version: 7.8.0
count: 1
elasticsearchRef:
name: quickstart
http:
service:
spec:
type: LoadBalancer
# Ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-services.html
# https://kubernetes.io/docs/concepts/services-networking/service
loadBalancerSourceRanges:
- "xxx.xxx.xxx.xxx/32"
-
kubectl applyを実行
$ kubectl apply -f eck-kibana.yaml
-
kubectl get pod にてpod状態を確認する(RunningになればOK)
$ kubectl get pod NAME READY STATUS RESTARTS AGE quickstart-es-default-0 1/1 Running 0 46h quickstart-kb-c69c8645d-2hwx4 1/1 Running 0 118s
-
kubectl get svc にてservice状態を確認する
-
quickstart-kb-http
にEXTERNAL-IPが振られていればOK - GKEの場合は、EXTERNAL-IPがLBに振られたグローバルIPになる
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 47h quickstart-es-default ClusterIP None <none> <none> 46h quickstart-es-http LoadBalancer 10.0.12.244 xxx.xxx.xxx.xxx 9200:30834/TCP 46h quickstart-es-transport ClusterIP None <none> 9300/TCP 46h quickstart-kb-http LoadBalancer 10.0.13.197 xxx.xxx.xxx.xxx 5601:30579/TCP 88s
-
-
Kibanaに接続する
-
xxx.xxx.xxx.xxxは
kubectl get svc
で出力されるquickstart-kb-http
のEXTERNAL-IP
を入力する -
自己証明書のため、ブラウザで警告が出るが「アクセスする」を選ぶ
-
以下のログイン画面がでれば接続成功
※ UsernameとPasswordは、Elasticserach接続時に使用したもの(Username: elastic, Password: xxxxxxxxxxxxxxx)と同じ
ECK on EKS
事前準備
- CLIでAWSリソースを操作できるように、AWS CLI Version2をインストールする。※eksctlを使うためにはversion2が必要
- EKSをCLI操作するために、eksctlをインストールする。
EKS Cluster作成
-
以下のコマンドを実行する
- eck-learnというクラスター名でデータノードとしてEC2(t3.small)を2台が作成される
- EC2以外にもVPCやサブネットやルートテーブルといったネットワーク関連リソースが
eksctl~
というtag付きで作成される - 作成に15分程度かかる
- EKS on EC2で作成する。(EKS on Fargate だとECK作成時に失敗する)
$ eksctl create cluster \ --vpc-cidr 10.0.0.0/16 \ --vpc-nat-mode HighlyAvailable \ --name eck-learn \ --nodegroup-name eck-learn-ng \ --node-type t3.small \ --nodes 2
-
kubectlにてnode状態を確認する。(status: ReadyになっていればOK)
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-155-85.ap-northeast-1.compute.internal Ready <none> 18m v1.16.8-eks-e16311 ip-192-168-177-141.ap-northeast-1.compute.internal Ready <none> 17m v1.16.8-eks-e16311
ECK作成
以降は、ECK on GKEと同じ手順で作成できる
ざっくり比較(GKE vs EKS)
-
起動時間
- GKE:2~3分
- EKS:15分
-
Kubernetes version
- GKE: かなり細かく指定が可能
gcloud container get-server-config --zone asia-northeast1-a
で東京リージョンで使えるversionが表示可能 - EKS: 各マイナーバージョンごとに一つを選ぶ
参考:利用可能な Amazon EKS Kubernetes バージョン
- GKE: かなり細かく指定が可能
-
料金
-
Type: LoadBalanecer指定した場合に作成されるリソース
- EKSの場合
- CLBが作成される(リバースプロキシ)
- 外からの接続先はCLBのエンドポイントになる(固定化されたIPは払い出されない)
- loadBalancerSourceRanges に設定した内容はSecurityGroupとしてCLBにアタッチされる
- GKEの場合
- ネットワークロードバランサーが作成される(パススルーのロードバランサー)
- 外からの接続先としてグローバルIPが払い出される
- loadBalancerSourceRanges に設定した内容は各ワーカーノードのFW設定として入る(つまり許可外のIPもLBは通過する)
- EKSの場合
まとめ
- Kibana接続まで実質コマンド4,5回でできるので、普通にElascticクラスターを構築する場合と比較するとかなり楽
- Kubernetesクラスター作成以降(ECKの作成)は、両クラウドともに同じ手順でできたため、「Kubernetesがクラウド間の差分を吸収してくれる」というのは実感できた。
- ただ、同じマニフェストでも作成されるリソースはクラウドによって違う(当然といえば当然)ので、クラウド側のサービス仕様の理解は必要。(今回の場合はType: LoadBalanecerの部分)
- Kubernetesの学習目的であれば、1クラスターが無料で使えるGKEを選んだほうがよさそう。