VPC 内にある Elasticsearch クラスタ に対し、VPC 外部から Kibana にアクセスする場合、
- SSH トンネルを使用する
- プロキシを使用する
- VPN を使う
などの方法が挙げられます。
ただどの方法も構築、管理、運用のコストが大きいです。
そこでこの記事では、Kibana Helm Chart を利用し、EKS クラスタ内の Pod から Elasticsearch のデータにアクセスする方法を紹介します。なお、Helm Chart の管理には Argo CD を利用しているため、その前提の手順となっています。
環境
- Kubernetes version 1.21
- Platform version eks.7
- Elasticsearch 7.10
- Argo CD v2.3.3
OpenSearch Service で Elasticsearch を利用しています。
OpenSearch へ移行していてもほぼ同様の手順で導入可能かと思いますが未検証です。
構成
手順
はじめに EKS クラスタ内の Pod から Domain endpoint へのリーチャビリティがあることを確認します。
❯ curl https://vpc-xxx.ap-northeast-1.es.amazonaws.com
{
"name" : "xxx",
"cluster_name" : "xxx",
"cluster_uuid" : "xxx",
"version" : {
"number" : "7.10.2",
"build_flavor" : "oss",
"build_type" : "tar",
"build_hash" : "unknown",
"build_date" : "2021-09-29T11:42:59.634166Z",
"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"
}
クラスタ名やバージョンを含む情報が返ってくれば問題ありません。
なお Domain endpoint はコンソールや AWS CLI から確認できます。
❯ aws opensearch describe-domain --domain-name xxx
{
"DomainStatus": {
...
"Endpoints": {
"vpc": "vpc-xxx.ap-northeast-1.es.amazonaws.com" # これ
},
...
}
}
Helm Chart をインストールします。
OpenSearch へ移行している場合はこちらもあります。
Argo CD の Application として Chart を追加します。
Helm コマンドを使う場合はこちらをご確認ください。
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kibana-test
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://helm.elastic.co
chart: kibana
targetRevision: 7.10.2
helm:
values: |
image: "docker.elastic.co/kibana/kibana-oss"
imageTag: "7.10.2"
imagePullPolicy: "IfNotPresent"
elasticsearchHosts: "https://vpc-xxx.ap-northeast-1.es.amazonaws.com"
destination:
server: 'https://kubernetes.default.svc'
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
Kibana の Image に関する補足
デフォルトの Image だと下記エラーで Pod が起動しなかったため、OSS 版の Image を指定しています。
Failed to parse mapping [_doc]: No handler for type [flattened] declared on field [config]
理由ですが、恐らく次の通りかと思います。詳しい方がいたらコメントで教えて下さい。
https://github.com/elastic/kibana/issues/52324#issuecomment-592063291
この Issue で指摘されている通り、デフォルトの kibana では x-pack という有償オプションが有効になっているが、OpenSearch Service では無効であるため、この不整合によってエラーが起きた。OSS 版の Kibana であれば有償オプションが最初から付属していない1ため起動できる。
Application を登録すると Pod や Service が作成されます。
ポートフォワードで Kibana の Web UI にアクセスします。
❯ k port-forward kibana-test-kibana-d4fc8cb48-xs7xl 8081:5601 -n default
Forwarding from 127.0.0.1:8081 -> 5601
Forwarding from [::1]:8081 -> 5601
Kibana Helm Chart には Ingress の有効化オプションがあります。annotation を付与することで AWS Load Balancer Controller2 と組み合わせたり、Cognito で認証を挟むことができます。こうすることで VPC 外部からも安全にアクセスできます。
これらの詳細に入ると各 Operator の話になってしまうため、最終的なマニフェストを載せてこの記事は終わりにします。
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kibana-test
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://helm.elastic.co
chart: kibana
targetRevision: 7.10.2
helm:
values: |
elasticsearchHosts: "https://vpc-xxx.ap-northeast-1.es.amazonaws.com"
image: "docker.elastic.co/kibana/kibana-oss"
imageTag: "7.10.2"
imagePullPolicy: "IfNotPresent"
ingress:
enabled: "true"
className: ""
hosts:
- host: "kibana-xxx.xxx.jp"
paths:
- path: "/*"
pathtype: "ImplementationSpecific"
annotations:
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: "internet-facing"
alb.ingress.kubernetes.io/target-type: "ip"
alb.ingress.kubernetes.io/backend-protocol: "HTTP"
alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP"
alb.ingress.kubernetes.io/healthcheck-port: "5601"
alb.ingress.kubernetes.io/healthcheck-path: "/api/status"
alb.ingress.kubernetes.io/auth-type: "cognito"
alb.ingress.kubernetes.io/auth-scope: "openid"
alb.ingress.kubernetes.io/auth-session-timeout: "3600"
alb.ingress.kubernetes.io/auth-session-cookie: "AWSELBAuthSessionCookie"
alb.ingress.kubernetes.io/auth-on-unauthenticated-request: "authenticate"
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-northeast-1:xxx:certificate/xxx"
alb.ingress.kubernetes.io/auth-idp-cognito: "{\"UserPoolArn\":\"arn:aws:cognito-idp:ap-northeast-1:xxx:userpool/ap-northeast-1_xxx\",\"UserPoolClientId\":\"xxx\",\"UserPoolDomain\":\"xxx\"}"
external-dns.alpha.kubernetes.io/hostname: "kibana-xxx.xxx.jp"
destination:
server: 'https://kubernetes.default.svc'
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
記事を書くためにマニフェストを書き換えたので、もし動かなかったらコメントで教えて下さい。