使用Terraform快速搭建在AWS ECS上的Elasticsearch/Kibana
首先
你好!我是在Wano株式会社担任工程师的nari。
我有幸被指派为Wano集团的圣诞节日历第一天的负责人,现在我来写文章了。
这次,在之前一直在进行的共同搜索基础设施(WIP)建设时,我参考了这篇文章,在AWS ECS上构建了Elasticsearch/Kibana。
-
- ECSはGUIでの操作がやっぱりしんどい(設定部分が散らばりすぎている)ので、TerraformでIaCした話
- ElasticSearch/Kibana 5,6系を対象とした記事だったので、7系で構築する場合のトラブルシューティング
我打算把它们整理在一起。
简而言之
ECSでお手軽にELK(Logstashは今回なし。Elasticsearchとkibanaのみ)を動かせるサンプルを作ったのでその構築方法と概要をまとめた
GitHub – fukubaka0825/terraform-elasticsearch-and-kibana-on-ecs: terraform-elasticsearch-and-kibana-on-ecsのReadme.mdを読んでもらってもまとまってる
その際に5、6系 -> 7系の差異で少し詰まったので、その際の解決法をまとめた
Elasticserachをシングルノードで設定したいなら、discovery.type: single-node
kibanaはELASTICSEARCH_URLでElasticsearchのURLを設定する
整个系统的结构
-
- とりあえず、HA(高可用性)な構成を取らずにシングルノードでやっていく形を取っています
- 弊グループサービス(Tuncore)のアーティスト/リリース/曲名の全文検索機能のデータソースとして想定
设定环境
-
- kibana:7.4.0
-
- elasticsearch:7.4.0
- terraform:0.12.6
为什么选择在AWS ECS上使用Elasticsearch/Kibana?
今回の要件では、逐次登録されていくアーティスト/曲名をユーザー定義辞書として管理し、検索精度を担保してあげる必要がある.
(ex: 「きゃ」 と検索して、「きゃりーぱみゅぱみゅ」がヒットして欲しくない。)
Amazon Elasticsearch Serviceがユーザー定義辞書の設定ができない
これ、だいぶ前からユーザー待望のアップデートだと思うので、re:inventで発表されたりしないかな
Elastic Cloud(ELASTICSEARCH SERVICE)のユーザー定義辞書の更新も、GUIを通してしかできない
問い合わせたが、APIやプログラマブルなハックができる仕組みは存在しないという回答があった
上記によって、フルマネージのサービスを使用できなさそうなので、自前でクラスター管理をする必要が出てきたが、直近のプロジェクトでECSを使っていたのもあって、ECSで構築することにした
Terraform的配置文件详细内容/构建方法/常见问题及解决方法
Terraform配置文件的完整内容
因为重量非常重,所以把它放在了 GitHub – fukubaka0825/terraform-elasticsearch-and-kibana-on-ecs 上。请参考该链接了解更详细的信息。
-> % tree -L 2
.
├── README.md
├── elasticsearch
│ ├── Dockerfile
│ ├── dummy.pub
│ ├── elasticsearch.yml
│ ├── es_task_container_definitions.json
│ ├── kibana_task_container_definitions.json
│ ├── main.tf
│ ├── outputs.tf
│ ├── userData.sh
│ └── variables.tf
└── modules
├── ecr
├── ecs
├── iam_role
└── sg
如何构建和使用
1. 将上述样本进行克隆。
将AWS凭证设置为自己账户的凭证,并将variables.tf文件中与网络相关的变量(如vpc、subnet)更改为自己账户的值。
variable "vpc_id" {
default = "YOUR_VPC_ID"
}
variable "subnet_id" {
default = "YOUR_SUBNET_ID"
}
只部署ECR资源。
- terraform init
- terraform apply --target=module.hoge_test_es_app_ecr
构建 Dockerfile 中的 Elasticsearch 镜像,并将其推送到步骤2中部署的 ECR。
- cd ./elasticsearch
- docker build -t es-test:latest .
- docker tag es-test:latest ${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_REGION}.amazonaws.com/es-test:latest
- (aws ecr get-login --region ap-northeast-1)
- docker push ${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_REGION}.amazonaws.com/es-test:latest
将es_task_container_definitions.json中的image更改为对ecr image的引用,并部署其他资源。
[
{
"name": "ec-test",
"image": "${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_REGION}.amazonaws.com/es-test:latest",
"cpu": 0,
"memory": 60000,
"memoryReservation": 60000,
"portMappings": [
{
"containerPort": 9200,
"hostPort": 9200,
"protocol": "tcp"
},
{
"containerPort": 9300,
"hostPort": 9300,
"protocol": "tcp"
}
],
"essential": true,
"environment": [
{
"name": "ES_JAVA_OPTS ",
"value": "-Xms8g -Xmx8g "
},
{
"name": "REGION",
"value": "ap-northeast-1"
}
],
"mountPoints": [
{
"sourceVolume": "esdata",
"containerPath": "/usr/share/elasticsearch/data/"
}
],
"volumesFrom": [],
"disableNetworking": false,
"readonlyRootFilesystem": false,
"ulimits": [
{
"name": "nofile",
"softLimit": 65536,
"hardLimit": 65536
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/es-test",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
- terraform deploy
6. 访问 http://${CONTAINER_INSTANCE_PUBLIC_IP}:5601
我迷上的事情以及解決方法。
1. Elasticsearch 从7系开始的必要设置项的变更
因为我参考的关于在ecs上使用ELK的文章是针对版本5和6的,而我这次的设置版本是7.4.0,所以按照那篇文章中的配置进行操作会出现下面这样的错误。
the default discovery settings are unsuitable for production use;
at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
因此,这次我想在单个节点上完成,所以我在elasticsearch.yml中添加了以下的discovery.type设置。
cluster.name: "es-test"
bootstrap.memory_lock: false
network.host: 0.0.0.0
//以下を追加
discovery.type: single-node
xpack.security.enabled: false
2. 从Kibana 7系开始,必需参数已发生变化。
在6.7版本之前,我们使用环境变量中的ELASTICSEARCH_URL来配置kibana与elasticsearch之间的url。但是从7版本开始,我们将使用ELASTICSEARCH_HOSTS来进行配置。
[
{
"name": "kibana-test",
"image": "docker.elastic.co/kibana/kibana:7.4.0",
"cpu": 0,
"memoryReservation": 1024,
"portMappings": [
{
"containerPort": 5601,
"hostPort": 5601,
"protocol": "tcp"
}
],
"essential": true,
"environment": [
{
"name": "ELASTICSEARCH_HOSTS",
"value": "http://localhost:9200/"
}
],
"mountPoints": [],
"volumesFrom": []
}
]
结束
现在,随着大型海外项目的优先级提高,这边的任务还处于待定状态,但是一旦有一点空闲,我们希望能够重新开始。(涉及ES和主数据同步、词典更新和索引重建的自动化,以及搜素精度和速度的改善等等,有很多我们想要做的话题)
明天的主题是 @fujitayy 的「组装自制键盘的经历」!我也想尝试自己做一个自制键盘,所以很期待阅读!
由于本次的冒险日历能够得到众多人的文章撰写合作,所以它将成为一个多种多样且有魅力的日历,我现在就非常期待读它了。
再者,參加本公司的這次聖誕節日曆活動的人將在聚餐時享用燒肉??
我們要在惠比壽進行燒肉研究吧。可能是穩定的「托拉爾基」吧??
讓我們一起安全完賽後,享受美味的肉類吧!!
文献引用
-
- Deploying the ELK stack on AWS ECS, Part 1: Introduction & First Steps
-
- Elasticsearchのkuromojiの検索で重要な辞書(dictionary)と類義語(synonym)の設定 – デベロッパー・コラボ
-
- Elasticsearch 7.0.0 がリリースされるもアップグレードでハマる – papalagi.org
-
- Running Kibana on Docker | Kibana Guide [7.4] | Elastic
- elasticsearch.hosts or elasticsearch.url are not picked up at all in version 6.7.0 · Issue #140 · elastic/kibana-docker · GitHub