5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Docker-composeでECS上にコンテナを起動してログ収集・分析基盤(ELK)を構築する

Last updated at Posted at 2019-05-21

Docker-composeでECS上にコンテナを起動してログ収集・分析基盤(ELK)を構築する

はじめに

公開しているWebアプリケーションのアクセスログを収集したく、ログの収集・分析基盤としてELK環境を構築しました。自前でサーバを立てるのも面倒だったので、AWSとDockerのお勉強がてら、Docker-composeファイルを用意して、ECS上でコンテナを起動し、システムを構築しました。なお、構築時のエラー・トラブルについては別記事でまとめたいと思います。

この記事の対象者

  • Elasticsearch, Logstash, Kibana環境をDockerで構築するのが初めて
  • ECSを使ったことがなく、docker-compose.ymlからECS上でコンテナを建てたい人

この記事を見てできること

  • ECS上でdocker-composeを使って、コンテナを起動できる
  • EC2上にELK環境を構築できる(厳密には、ElasticsearchとLogstashのコンテナをEC2上で動かせる)
  • アプリケーションからPOSTされたJSONデータをKibanaで可視化できる

システム情報

  • Elasticsearch 7.0.0
  • Logstash 7.0.0
  • Kibana 7.0.0
  • docker-compose v2
  • EC2 t2.small メモリ2GB (無料枠対象外なのでご注意を)

システム構成

色々試行錯誤した結果、以下のようなシステム構成となりました。
Kibanaをlocalhost上で建てているのは、EC2インスタンスのスペックが低すぎて(2GB)、EC2上でKibanaが起動しなかったためです。自分だけKibanaを見れればよかったので、Kibanaを確認したい時だけ、localhost上にKibanaをデプロイしています。
system.001.jpeg

docker-compose.ymlを使って、ECS上でコンテナを起動

以下の色掛け部分の構築をします。
system.002.jpeg

以下の記事が参考になりました。
公式
ローカルで使用したdocker-compose.ymlを使ってECS上でコンテナを起動する
ECS CLIでAmazon ECSを操作してみた
AWS CLIを使用するための初期設定

ECS-CLIをインストール

brew install amazon-ecs-cli
バージョン確認
aws --version
aws-cli/1.16.156 Python/3.7.0 Darwin/18.2.0 botocore/1.12.146

ECS-CLIで使用するAWSの情報を設定

aws configure
AWS Access Key ID [None]: hogehoge
AWS Secret Access Key [None]: hogehoge
Default region name [None]: [リージョン名]
Default output format [None]: json

リージョン名はここから検索

ここのIDとAccess Keyに何を設定すればいいかが分からない方は、おそらくIAMユーザを作成する必要があります。一旦、以下の公式ページに一通り目を通しましょう。
IAMユーザ作成→IAMユーザーのアクセスキーIDおよびシークレットアクセスキーの取得という手順をふむ必要があります。
※既に作成済みならば読み飛ばしてください。

公式:AWS CLI の設定

docker-compose.yml(Logstash, Elasticsearch用)を準備

docker-compose.yml
version: "2"
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.0.0
    mem_limit: 1g
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    networks:
      - elastic-stack

  logstash:
    image: gogogonkun/logstash_pub
    mem_limit: 768m
    ports:
      - "5044:5044"
    environment:
      - "LS_JAVA_OPTS=-Xms512m -Xmx512m"
    networks:
      - elastic-stack

networks:
  elastic-stack:
  • Dockerイメージについて
    logstashのDockerイメージは、事前に設定ファイルに変更を加えたり、confファイルを仕掛けたかったため、公式のDockerイメージを一部変更したものを使用しています。経緯や詳細はこちらの記事で紹介します。

  • メモリサイズについて
    t2.smallインスタンスのメモリが2GBしかないため、mem_limitをそれぞれ1g, 768mと設定して、自重しています。ちなみに2GBを超えてしまうと、コンテナが起動してくれません。 経緯や詳細は上記と同様にこちらの記事で紹介します。

とりあえずローカルで起動

docker-compose up -d

動作確認

$: curl localhost:9200
{
  "name" : "77e042e7f49d",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "Ocgt84ZaReWsBhgjzMQUSA",
  "version" : {
    "number" : "7.0.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "b7e28a7",
    "build_date" : "2019-04-05T22:55:32.697037Z",
    "build_snapshot" : false,
    "lucene_version" : "8.0.0",
    "minimum_wire_compatibility_version" : "6.7.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

止める

docker-compose stop

ECSクラスタを起動(t2.smallインスタンスは有料です)

ecs-cli up --keypair KEY_NAME --capability-iam --size 1 --instance-type t2.small

docker-compose.ymlからECS上でコンテナを起動

ecs-cli compose -f docker-compose.yml up

確認

$: ecs-cli ps   
Name                                                State    Ports                                                         TaskDefinition  Health
6d644480-39a0-4367-b3ed-ac82b0d630d9/logstash       RUNNING xx.xxx.xxx.xxx:5044->5044/tcp                                 ELK:80          UNKNOWN
6d644480-39a0-4367-b3ed-ac82b0d630d9/elasticsearch  RUNNING  xx.xxx.xxx.xxx:9300->9300/tcp, xx.xxx.xxx.xxx:9200->9200/tcp  ELK:80          UNKNOWN

ここまでで、ECS上にコンテナを起動することが出来ました。

少し寄り道... 固定のIPアドレスの取得

アプリケーションからLogstashへログをPOSTする際の送り先、KibanaでElasticsearchからログを取得する際の取得先のIPアドレスが、EC2インスタンスが再起動する度に変わってしまうと、その度にコンテナの設定変更が必要となります。
system.003.jpeg

でもそんなのは面倒なので、EC2インスタンスのIPアドレスを固定します。Elastic IPsでは固定のIPアドレスを取得して、EC2インスタンスに紐づけることができます。
以下の記事を参考に、EC2インスタンスにIPアドレスを紐づけます。
公式
AWS EC2インスタンスにElastic IP(固定グローバルIPアドレス)を割り当てる

docker-compose.yml(Kibana用)を使って、localhost上でコンテナを起動

先ほどまでとは異なり、以下の色掛け部分の環境を構築します。
system.004.jpeg

docker-compose.yml(Kibana用)を準備

docker-compose.yml
version: "2"
services:
  kibana:
    image: gogogonkun/kibana
    mem_limit: 3g
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_URL=http://XX.XXX.XXX.XXX:9200
      - ELASTICSEARCH_USER=NAME=kibana
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
  • Dockerイメージについて
    EC2インスタンス上に建てたコンテナと同様に、Dockerイメージを一部書き換えております。

  • 環境変数について

docker-compose.ymlからlocalhost上でコンテナを起動

 $: docker-compose up -d

確認

$: docker-compose ps   
     Name                   Command              State           Ports         
-------------------------------------------------------------------------------
kibana_kibana_1   /usr/local/bin/kibana-docker   Up      0.0.0.0:5601->5601/tcp

これで、EC2インスタンス上にElasticsearch、Logstashを、Localhost上にKibanaをそれぞれ建てることが出来ました。これで環境構築が完成したかのように思えますが、EC2インスタンスのセキュリティグループを設定していないため、アプリケーションやローカルの端末からEC2で建てているコンテナに接続することが出来ません。

EC2インスタンスのSecurity Groups設定

特定のIPアドレスから、EC2で建てたコンテナの指定したポートに対する接続を許可します。
下の図のようなイメージです。

system.005.jpeg

この記事を参考にします。
【AWS】セキュリティグループを設定してみた(そして関連する用語を調べてみた)

以下のような設定になるかと思います。
3番は動作確認のために、自分のIPアドレスから全てのポートにアクセスできるようにしています。

Protocol Port Range Source
1 TCP 5044 App IP
2 TCP 9200 My IP
3 TCP 0 - 65535 My IP

上手くいかなかったら、とりあえず動作確認のために、全てのIPアドレスから全てのポートに対する接続を許可してみてから、接続を許可する範囲を狭めていくといいと思います。
※セキュリティホールになるので、最終的にはガバガバ設定にしないでください・・・

動作確認

  • Elasticsearch
    [EC2コンテナのIPアドレス]:9200 に接続します。
    JSONが返却されれば問題ないかと思います。
{
  "name" : "77e042e7f49d",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "Ocgt84ZaReWsBhgjzMQUSA",
  "version" : {
    "number" : "7.0.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "b7e28a7",
    "build_date" : "2019-04-05T22:55:32.697037Z",
    "build_snapshot" : false,
    "lucene_version" : "8.0.0",
    "minimum_wire_compatibility_version" : "6.7.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
  • Kibana
    localhost:5601 に接続します。
    画面が表示されるかと思います。
スクリーンショット 2019-05-21 20.01.15.png
  • Logstash
    [EC2コンテナのIPアドレス]:5044 に接続します。
ok

※Logstash用のconfファイルが置かれていなければ、何も返却されません。
ちなみに今回は、Logstashがインストールされているコンテナの/usr/share/logstash/pipeline 配下に、以下のようなconfファイルを仕込んでいます。POSTされたJSONデータをそのままElasticsearchにぶち込むconfファイルです。

movhis.conf
input {
    http {
        port => 5044
        response_headers => {
            "Access-Control-Allow-Origin" => "*"
            "Content-Type" => "text/plain"
            "Access-Control-Allow-Headers" => "Origin, X-Requested-With, Content-Type, Accept"
        }
    }    
}

output {
    elasticsearch {
        hosts => "http://[EC2インスタンスのIPアドレス]:9200"
        index => "movhis-%{+YYYY.MM}"
    }   
}

Logstashのコンテナを建てる度に、confファイルをちまちま設定するのが面倒な人は、以下の手順で、自分用のDockerイメージを使用しましょう。

  1. 公式のDockerイメージを書き換える
  2. Dockerイメージのコミット
  3. DockerHubへプッシュ
  4. docker-compose.ymlでプッシュしたDockerイメージを指定する
    ※DockerHubへのプッシュまでについてはこちらの記事を確認ください。

logstashにhttpリクエストを投げて、Kibanaから確認してみる

※上記confファイルが設定されている前提の話です。

先ほどの動作確認と同様に、ブラウザ上で[EC2コンテナのIPアドレス]:5044 に接続
次にKibanaからデータが登録されているか確認

1.インデックス選択
スクリーンショット 2019-05-21 20.23.32.png

スクリーンショット 2019-05-21 20.23.48.png

2.データ確認
スクリーンショット 2019-05-21 20.24.40.png

データが登録されていることが確認出来ました。

おわりに

ECSを利用してDocker-composeファイルからELKの環境を構築してきました。また、Logstashを通してElasticsearchに登録されたログデータを、Kibanaから確認することも出来ました。
今回はPOSTされたJSONデータをそのまま可視化するだけでしたが、システムのメトリクス・業務のログ等、いろんなログデータを登録して可視化することができます。自分が使いやすいように好きにカスタマイズして遊んでください。

後半は説明が適当になってしまったので、後で見直して、整理したいと思います。特に、ログを可視化できるようになるまで、割とハマったポイントがあったので、別途まとめて紹介したいと思います。

説明が長くなってしまいましたが、改善点やご意見お待ちしております。
ここまで見ていただき、ありがとうございました。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?