【Elasticsearch勉強会】aws環境に合わせてelastic...

Post on 21-Jan-2018

1.685 views 0 download

Transcript of 【Elasticsearch勉強会】aws環境に合わせてelastic...

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 push docker 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 s3 output 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","principalId":"AIDAJWI3XZEUUMG6MUJNO","arn":"arn:aws:iam::930021801196:user/deploy","accountId":"930021801196","accessKeyId":"AKIAJSFVI6UIWJH3UBGQ","userName":"deploy"},"eventTime":"2017-08-22T00:21:45Z","eventSource":"ec2.amazonaws.com","eventName":"DescribeTags","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":"resource-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設定例

SG04 SG03 SG02 SG01

# 送信元 宛先ポート

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”]