1 ×
AWS環境に合わせて
ElasticStackをログ分析基盤として構築した話
2017/10/11(Wed)
Future Architect, Inc
Hisashi Hibino
2 ×
本日、伝えたいこと
 ElasticsearchをVPC内で構築する時のポイント
 Logstashをコンテナ化してAWS各種ログを取り込む時のコツ
 AWSにおける課題と今後の取り組みについて
※資料は終了後公開します
3 ×
自己紹介
名前:日比野 恒 (ひびの ひさし)
所属:フューチャーアーキテクト株式会社
Technology Innovation Group
セキュリティアーキテクト (CISA、登録セキスぺ)
領域:
サーバ基盤
OS
データベース
アプリケーション
ネットワーク
データセンター
セ
キ
ュ
リ
テ
ィ
4 ×
フューチャーアーキテクトの紹介
「経営とITをデザインする」アントレプレナーとテクノロジーイノベーターのコンサル集団
5 ×
世にないものは、何だかんだ自分たちで作っちゃう会社(笑)
あのOSS脆弱性スキャナ「Vuls」も当社エンジニアが自主的に開発!!
公開当初、GitHub Trendingで一位を獲得!
世間を賑わせ続けていますー^^
6 ×
×
Today is ...
7 ×
全体のアーキテクチャ
S3 Bucket
・
・
・
・
・
・
ECS Cluster
input s3
input s3
/log_a
/log_z
Log A
Elasticsearch
Cluster
Log Z
logstash container
logstash container
Elasticsearch01
Elasticsearch02
Elasticsearch03
Kibana01
Kibana02
HTTPS
@Tokyo
output elasticsearch
output elasticsearch
8 ×
全体のアーキテクチャ
S3 Bucket
・
・
・
・
・
・
ECS Cluster
input s3
input s3
/log_a
/log_z
Log A
Elasticsearch
Cluster
Log Z
logstash container
logstash container
Elasticsearch01
Elasticsearch02
Elasticsearch03
Kibana01
Kibana02
HTTPS
@Tokyo
output elasticsearch
output elasticsearch
※本日の範囲
9 ×
全体のアーキテクチャ
S3 Bucket
・
・
・
・
・
・
ECS Cluster
input s3
input s3
/log_a
/log_z
Log A
Elasticsearch
Cluster
Log Z
logstash container
logstash container
Elasticsearch01
Elasticsearch02
Elasticsearch03
Kibana01
Kibana02
HTTPS
@Tokyo
output elasticsearch
output elasticsearch
※本日の範囲
ユースケースはログ管理!!
10 ×
んん?あれ、なんか様子がおかしいぞ
AWSでElasticsearchって言ったら、みんなこれだよね?
11 ×
Elasticsearch
12 ×
EC2 Discovery Pluginでクラスタを組もう
AWSのSecurity Groupを認識して所属しているElasticsearchノードを探しに行く。
【参考】EC2 Discovery Plugin
https://www.elastic.co/guide/en/elasticsearch/plugins/5.6/discovery-ec2.html
Security Group
VPC
ES01 ES02
ES03
Elasticsearch
Cluster
# export ES_JAVA_OPTS=“-Dhttps.proxyHost=<プロキシIP> -Dhttps.proxyPort=<ポート>"
# /usr/share/elasticsearch/bin/elasticsearch-plugin install discovery-ec2
# vi /etc/elasticsearch/elasticsearch.yml
# --------------------------------- Discovery ----------------------------------
discovery.zen.hosts_provider: ec2
discovery.ec2.groups: "<SecurityGroupID>"
discovery.ec2.availability_zones: [ "ap-northeast-1a", "ap-northeast-1c" ]
cloud.aws.region: ap-northeast-1
# ---------------------------------- Cloud AWS --------------------------------
cloud:
aws:
protocol: https
proxy:
host: <プロキシサーバのIPアドレス>
port: <プロキシサーバのポート番号>
# systemctl restart elasticsearch
【導入手順】
※プロキシサーバ環境の場合に必要
Elasticsearch Cluster用
IAMロールを割り当てる
13 ×
EC2
Repository S3 Pluginでバックアップとリストアを簡単に!
シームレスにS3 Bucketに対して、IndexのSnapshotをバックアップとリストアが可能。
【参考】Snapshot And Restore
https://www.elastic.co/guide/en/elasticsearch/reference/5.6/modules-snapshots.html#_repository_plugins
Curator 5 repository-s3
S3 Bucket
(log-a)
/backup/index
# export ES_JAVA_OPTS=“-Dhttps.proxyHost=<プロキシIP> -Dhttps.proxyPort=<ポート>"
# /usr/share/elasticsearch/bin/elasticsearch-plugin install repository-s3
【導入手順】
※プロキシサーバ環境の場合に必要
Elasticsearch
Index
1
2
Snapshot
Curator用IAMロールを割り当てる
PUT /_snapshot/my_s3_repository
{
"type": "s3",
"settings": {
"bucket": "log-a",
"region": "ap-northeast-1",
"base_path": "backup/index",
"compress": "true",
"server_side_encryption": "true"
}
}
14 ×
Elasticsearchノードをテンプレート化する時の考え方
Elasticsearchを導入してAMI化するとクラスタへの追加時にノードID重複となる。
EC2
CentOS 7.x
Java 8 Python 2.x
Curator 5.x
AMI
EC2
CentOS 7.x
Java 8 Python 2.x
Curator 5.x
イメージ化 インスタンス作成
 Java8導入
 Curator5導入
 Elasticsearchは導入しない
Elasticsearch 5.5.x
Elasticsearchを設定
 Elasticsearch導入
 ingest plugin導入
 aws cloud plugin導入
 elastisearch.yml設定
 jvm.options設定
 X-Pack導入
Elasticsearch Cluster
ES01 ES02 ES03
1 2 3
15 ×
Elasticsearchのクラスタに対するAPIアクセス
KibanaとElasticsearchが別ノードの場合はロードバランサを挟む必要がある。
【参考】Load Balancing Across Multiple Elasticsearch Nodes
https://www.elastic.co/guide/en/kibana/current/production.html#load-balancing
Elasticsearch Cluster
Elasticsearch01
Elasticsearch02
Elasticsearch03
Kibana Internal-ELB
TCP9200
TCP9200
# The URL of the Elasticsearch instance to use for all your queries.
elasticsearch.url: “http://<Internal-ELBのFQDN>:9200"
【kibana.ymlの設定】
※elasticsearch.urlは、URLを1つしか指定出来ない。
16 ×
Logstash
17 ×
LogstashをECSでコンテナサービス化しよう!
コンテナ化することでLogstashをタスクとして実行することが可能になる。
EC2 (ビルドマシン)
CentOS 7.x
Docker 1.12
CentOS 7.x
Logstash 5.5.x
Dockerfile Image ECS
ECR
docker pushdocker build
ECS Cluster
EC2 (ECS最適化) EC2 (ECS最適化)
Docker 1.12
ECS Agent Logstash 5.5.x
Docker 1.12
ECS Agent Logstash 5.5.x
docker pull
ECS最適化AMI
(ami-ab5ea9cd)
【ECS化のメリット】
 障害時のエラーハンドリング
 ログの量やリアルタイム性に応じた柔軟なサイジング
【IAMロール】
AmazonEC2ContainerRegistryPowerUser
【IAMロール】
AmazonEC2ContainerServiceforEC2Role
18 ×
ログは全てS3を介して取り込むべし
ログ形式毎にフォルダを切ってS3にログを収集することで障害時のハンドリングが容易になる。
ログファイル
データベース
ネットワーク機器
イベントログ
Filebeat
Winlogbeat
Logstash
(収集)
input jdbc
input tcp/udp
(syslog/netflow)
S3 Bucket
(bucket-a)
/log
/backup
AWS各種アクセスログ
Logstash
(正規化)
S3アクセスログ
CloudFront
アクセスログ
ELB
アクセスログ
Elasticsearch
input s3output s3
output es
1 2
3 input {
s3 {
backup_to_bucket => “bucket-a"
backup_add_prefix => “backup/"
delete => "true"
bucket => "bucket-a"
region => "ap-northeast-1"
prefix => “log/log-a"
interval => "5"
sincedb_path => "/var/lib/logstash/sincedb"
}
}
log-a
Logstashで取り込まれた後
生ログは/backupで保持される
19 ×
S3で難しいものは、泣く泣くCloudWatchLogs
CloudTrailの操作ログはJSON形式だが、複数並列の[]がうまくパース出来ない問題。
S3アクセスログ
CloudFront
アクセスログ
ELB
アクセスログ
CloudTrail
操作ログ
RDS
SQL監査ログ
S3 Bucket
Cloud Watch Logs
Logstash
(正規化)
Elasticsearch
input s3
output es
input cloudwatch_logs
input {
cloudwatch_logs {
log_group => [ "CloudTrail/DefaultLogGroup" ]
region => "ap-northeast-1“
codec => json
}
}
【参考】input cloudwatch-logs plugin
https://github.com/lukewaite/logstash-input-cloudwatch-logs
20 ×
{"Records":[{"eventVersion":"1.05","userIdentity":{"type":"IAMUser","principal
Id":"AIDAJWI3XZEUUMG6MUJNO","arn":"arn:aws:iam::930021801196:user/d
eploy","accountId":"930021801196","accessKeyId":"AKIAJSFVI6UIWJH3UBGQ",
"userName":"deploy"},"eventTime":"2017-08-
22T00:21:45Z","eventSource":"ec2.amazonaws.com","eventName":"DescribeTa
gs","awsRegion":"ap-northeast-
1","sourceIPAddress":"122.208.2.42","userAgent":"aws-cli/1.3.9 Python/2.6.9
Linux/3.10.40-
50.136.amzn1.x86_64","requestParameters":{"filterSet":{"items":[{"name":"r
esource-id","valueSet":{"items":[{"value":"i-
bd2862bb"}]}}]}},"responseElements":null,"requestID":"570f599f-6d88-430f-
9b75-2f6b2e4de006","eventID":"499e235d-979d-45ed-865f-
6be44eb66eeb","eventType":"AwsApiCall","recipientAccountId":"930021801196
"}]}
CloudTrailの操作ログのサンプル
21 ×
まとめ
22 ×
Amazon Elasticsearch Service(ES)との比較
比較項目 Amazon ES Elasticsearch on EC2
監視 CloudWatch X-Pack (Monitoring)
アクセス制御 IAM Policy X-Pack (Security)
バックアップ 1日毎 (14日保持) 任意のタイミング (容量に準ずる)
スケールアップ 無停止 無停止
スケールアウト 無停止 無停止
バージョンアップ 手動移行 無停止(5.6⇒6.0)
利用バージョン AWS指定バージョンのみ 最新バージョン
サポート AWSサポート Elasticサポート
利用可能機能 OSS範囲のみ Elastic有償機能 (X-Pack)
23 ×
Amazon Elasticsearch Service(ES)との比較
比較項目 Amazon ES Elasticsearch on EC2
監視 CloudWatch X-Pack (Monitoring)
アクセス制御 IAM Policy X-Pack (Security)
バックアップ 1日毎 (14日保持) 任意のタイミング (容量に準ずる)
スケールアップ 無停止 無停止
スケールアウト 無停止 無停止
バージョンアップ 手動移行 無停止(5.6⇒6.0)
利用バージョン AWS指定バージョンのみ 最新バージョン
サポート AWSサポート Elasticサポート
利用可能機能 OSS範囲のみ Elastic有償機能 (X-Pack)
24 ×
AWS@Tokyoにおける課題
AZ-a AZ-c
@Tokyo
東京リージョンにはAZが2つしかないため、AZ障害時にクラスタのクォーラムを維持できない。
VPC
Elasticsearch01 Elasticsearch02 Elasticsearch03
25 ×
AWS@Tokyoにおける課題
東京リージョンにはAZが2つしかないため、AZ障害時にクラスタのクォーラムを維持できない。
AZ-a AZ-c
@Tokyo
VPC
Elasticsearch01 Elasticsearch02 Elasticsearch03
26 ×
Next challenge will be GCP...
27 ×ログ量は急増加、容量で課金なんてあり得ないでしょ、、、
28 ×
最後にちょっとだけ宣伝
当社ゆるふわエンジニアが、Elastic & Honeypotネタで登壇します。
当社大崎オフィスで開催しますー、ぜひお越しください!! ^^/
【第7回】 11/13(月)開催予定!!
https://s-jaws.doorkeeper.jp/
29 ×
30 ×
Appendix
31 ×
SecurityGroup設定例
SG04SG03SG02SG01
# 送信元 宛先ポート
1 Elasticsearch(SG02) TCP 9600
# 送信元 宛先ポート
1 Kibana(SG03) TCP 9200
2 Logstash(SG01) TCP 9200
3 Elasticsearch(SG02) TCP 9200
4 Elasticsearch(SG02) TCP 9300
# 送信元 宛先ポート
1 ELB(SG04) TCP 5601
# 送信元 宛先ポート
1 a.a.a.a/32 TCP 443
送信元IPアドレス
a.a.a.a
【SG01:Logstash】 【SG02:Elasticsearch】 【SG03:Kibana】 【SG04:ELB】
32 ×
Elasticsearchに必要なIAMロール
{
"Statement": [
{
"Action": [
"ec2:DescribeInstances“
],
"Effect": "Allow",
"Resource": [
"*“
]
}
],
"Version": "2012-10-17“
}
Elasticsearch Cluster用
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
“Resource”: “arn:aws:s3:::<S3 Bucket名>/backup/index/*“
}
]
}
Curator用
33 ×
Logstashに必要なIAMロール
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*“
],
"Resource": "*“
}
]
}
input S3用
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:CreateCluster",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:StartTelemetrySession",
"ecs:UpdateContainerInstancesState",
"ecs:Submit*",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents“
],
"Resource": "*“
}
]
}
ECSクラスタ用
34 ×
elasticsearch.ymlのサンプル
# ---------------------------------- Cluster -----------------------------------
cluster.name: es_cluster01
# ------------------------------------ Node ------------------------------------
node.name: node-es01
# ---------------------------------- Network -----------------------------------
network.host: 0.0.0.0
# --------------------------------- Discovery ----------------------------------
discovery.zen.hosts_provider: ec2
discovery.ec2.groups: "<SecurityGroupID>"
discovery.ec2.availability_zones: [ "ap-northeast-1a", "ap-northeast-1c" ]
cloud.aws.region: ap-northeast-1
# ---------------------------------- Cloud AWS --------------------------------
cloud:
aws:
protocol: https
proxy:
host: <プロキシサーバのIPアドレス>
port: <プロキシサーバのポート番号>
AWSとの通信にプロキシサーバを介す場合
35 ×
logstash.confのサンプル
input {
s3 {
backup_to_bucket => “bucket-a"
backup_add_prefix => “backup/"
delete => "true"
bucket => "bucket-a"
region => "ap-northeast-1"
prefix => “log/log-a"
interval => "5"
sincedb_path => "/var/lib/logstash/sincedb"
}
}
filter {
date {
timezone => "Asia/Tokyo“
}
}
output {
elasticsearch {
hosts => [ “internal-<ELB名>-<AWSアカウント>.ap-northeast-1.elb.amazonaws.com:9200" ]
index => “log-a-%{+YYYY.MM.dd}"
template_name => "log-a"
}
}
36 ×
Dockerfileのサンプル
FROM centos:7
# Ensure Logstash gets a UTF-8 locale by default.
ENV LANG='en_US.UTF-8' LC_ALL='en_US.UTF-8'
# timezone settings
RUN cp -p /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# install java1.8.0
RUN yum install -y java-1.8.0-openjdk
ENV JAVA_HOME=/usr/lib/jvm/jre-1.8.0
COPY java.sh /etc/profile.d/java.sh
RUN chmod +x /etc/profile.d/java.sh
# install logstash
COPY elastic.repo /etc/yum.repos.d/
RUN yum install -y logstash-5.5.x
COPY logstash.conf /etc/logstash/conf.d/logstash.conf
COPY logstash.yml /etc/logstash/logstash.yml
#install plugins
RUN /usr/share/logstash/bin/logstash-plugin install <plugins名>
# enable systemd
ENV container docker
# exec logstash
RUN systemctl enable logstash.service
EXPOSE 5044
CMD [“/usr/sbin/init”]

【第21回Elasticsearch勉強会】aws環境に合わせてelastic stackをログ分析基盤として構築した話