あんまりAWSやDockerを触ってこなかったので、自身の勉強も兼ねてやってみました。
楽勝かと思いましたが意外とハマったので、備忘録的にまとめてます。
※AWSの設定やDocker環境構築から説明しているので、「もう知ってる! or やってるよ!」という人は、docker-compose.ymlの作成とコンテナの起動から読んでいただくと良いと思います。
AWS構築
AWSの初期構築を整理します。
インスタンススタック
EC2インスタンスの構築はコンソール画面からの操作で簡易に可能かつ公式リファレンスが充実しているので省略します。
構築したインスタンスは下記の通りです。
- マシンイメージ
- Amazon Linux 2 AMI (HVM), SSD Volume Type
- インスタンスタイプ
- t2.medium(t2.microではスペック不足でコンテナが立ち上がりませんでした
(詳細はインスタンスメモリ不足による起動失敗を参照))
- t2.medium(t2.microではスペック不足でコンテナが立ち上がりませんでした
- ディスクサイズ
- SSD 30GB(まずはお試し構築ならこの容量でも十分です)
- セキュリティ(外部向け開放ポート)
- 22(SSHアクセス用)
- 5601(Kibanaにブラウザからアクセスする用)
AWSインスタンス初期設定
インスタンスを立ち上げたので、CUIによるインスタンスへのアクセスから必要と思われる操作を記載します。
(もし過不足があれば指摘してもらえれば幸いです)
状況は秘密鍵をダウンロードした状態からの操作イメージです。
-
秘密鍵の配置(~/.ssh配下に格納)
mv /Users/ユーザ名/Downloads/秘密鍵名.pem ~/.ssh
-
秘密鍵の権限設定
(インスタンスへSSHアクセスするためには秘密鍵が公開されていないことが必須なため)
chmod 400 ~/.ssh/秘密鍵名.pem
-
AWSのEC2インスタンスにSSH接続
ssh -i ~/.ssh/秘密鍵名.pem ユーザ名@パブリックDNS
(デフォルトのユーザ名はec2-user) -
パッケージの更新
sudo yum update -y
-
パッケージの自動更新設定
# yum-cronのインストール
sudo yum install yum-cron -y
# yum-cron有効化確認
sudo chkconfig --list yum-cron
# 有効化
sudo chkconfig yum-cron on
# 自動更新設定
sudo sed -i "s/^apply_updates.*$/apply_updates = yes/g" /etc/yum/yum-cron.conf
# 起動
sudo service yum-cron start
・起動確認
sudo service yum-cron status
6.タイムゾーンの変更
(インスタンスのローカルタイムとハードウェアクロックを変更します)
# 現在の設定確認
date
# ローカルタイムを【Japan】に変更
sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime
# ハードウェアクロックを【Japan】に変更
sudo sed -i "s/\"UTC\"/\"Japan\"/g" /etc/sysconfig/clock
# システム再起動
sudo reboot
# 現在の設定確認
date
7.文字コードを日本語対応に変更
sudo sed -i "s/en_US\.UTF-8/ja_JP\.UTF-8/g" /etc/sysconfig/i18n
Docker環境初期構築
初期ではDockerがインストールされていなかったので、初期構築を実施。
1.gitのインストール
sudo yum install git -y
2.dockerをインストール
sudo yum install docker -y docker -v
3.dockerを起動
sudo service docker start
(起動状態を確認する場合は、sudo service docker status
)
(補足)4.dockerコマンド実行時にsudoをやらないように設定
(利用者のセキュリティ観点で要否は判断してください)
dockerグループの確認(ない場合は追加)
$ sudo groupadd docker
任意のユーザーをdockerグループに入れる
$ sudo usermod -a -G docker $USER
5.docker-composeのインストール
curlコマンドを使って、GitHub上にある最新版資材を取得します。
(2018/8/18現在の最新版は1.22.0)
公式サイト手順
sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
資材を取得したら、バイナリファイルに権限を付与します。
sudo chmod +x /usr/local/bin/docker-compose
正常にインストールされたかを確認します。
docker-compose --version
以下のような結果が出力されればOK。
docker-compose version 1.22.0, build f46880fe
docker-compose.ymlの作成とコンテナの起動
初期設定が完了したらdocker-composeを使って、コンテナを作成/起動していきます。
※今回はdockerfileは作りません。
ちなみにDocker-composeとは公式サイトによると以下のことです。
Compose とは、複数のコンテナを使う Docker アプリケーションを、定義・実行するツールです。Compose はアプリケーションのサービスの設定に、Compose ファイルを使います。そして、コマンドを1つ実行するだけで、設定した全てのサービスを作成・起動します。
実行後のざっくりイメージは以下になります。
それではやっていきましょう。
docker-compose.ymlファイルの作成
任意のディレクトリを作成し、その中にdocker-compose.yml
というファイル名で新規ファイルを作成します。
Composeファイル作成には、公式リファレンスにお世話になりました。
作成したYAMLファイルは以下になります。
# elasticsearch
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
container_name: elasticsearch
ports:
- "9200:9200"
- "9300:9300"
ulimits:
nofile:
soft: 65536
hard: 65536
# kibana
kibana:
image: docker.elastic.co/kibana/kibana:6.3.2
container_name: kibana
ports:
- "5601:5601"
links:
- elasticsearch
# logstash
logstash:
image: docker.elastic.co/logstash/logstash:6.3.2
container_name: logstash
links:
- elasticsearch
YAMLファイルの解説コメント
YAMLファイルの記載内容を説明します。
コメントは「コード上部に##で記載します」
# elasticsearch
## elasticsearchの定義を開始
elasticsearch:
## 公式サイトからdockerイメージの最新版を取得
image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
## コンテナ名を明示的に付与
container_name: elasticsearch
## ポートフォワードで必要なポートを開放
## 9200:REST通信用
## 9300:ノード間コミュニケーション用
ports:
- "9200:9200"
- "9300:9300"
## file descriptorの設定値エラーを防ぐため
## 詳細はfile descriptorの設定変更漏れによる起動エラー項目を参照
ulimits:
nofile:
soft: 65536
hard: 65536
# kibana
## kibanaの定義を開始
kibana:
## 公式サイトからdockerイメージの最新版を取得
image: docker.elastic.co/kibana/kibana:6.3.2
## コンテナ名を明示的に付与
container_name: kibana
## ポートフォワードで必要なポートを開放
## 5601:ブラウザからkibanaのGUIにアクセスするためのポート
ports:
- "5601:5601"
## コンテナ間連携の設定
## elasticserchと情報を授受するため必須
links:
- elasticsearch
# logstash
## logstashの定義を開始
logstash:
## 公式サイトからdockerイメージの最新版を取得
image: docker.elastic.co/logstash/logstash:6.3.2
## コンテナ名を明示的に付与
container_name: logstash
## コンテナ間連携の設定
## elasticserchと情報を授受するため必須
links:
- elasticsearch
docker-composeによる起動
docker-compose.ymlファイルを作成したら、以下のコマンドを「YAMLファイルのあるディレクトリ」で実行。
docker-compose up -d
※初期実行時は、外部からDockerイメージの取得⇒コンテナの起動を行うため、少し時間がかかります。
docker-compose up
実行時にエラーが発生した場合は、docker-compose up -d
の実行時にエラーが発生の対処を実施してみてください。
構築が終わったら以下のコマンドで正常に起動しているかを確認します。
docker ps
コマンド実行後は以下のようなイメージとなります。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<ハッシュ値> docker.elastic.co/logstash/logstash:6.3.2 "/usr/local/bin/dock…" 3 days ago Up 3 days 5044/tcp, 9600/tcp logstash
<ハッシュ値> docker.elastic.co/kibana/kibana:6.3.2 "/usr/local/bin/kiba…" 3 days ago Up 3 days 0.0.0.0:5601->5601/tcp kibana
<ハッシュ値> docker.elastic.co/elasticsearch/elasticsearch:6.3.2 "/usr/local/bin/dock…" 3 days ago Up 3 days 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch
- 確認ポイント
- NAMESに指定した3つのコンテナが並んでいること
- 指定した3つのコンテナが起動していること(STATUSがUpになっていること)
です。
-
docker ps
コマンド自体が正常に起動しているコンテナのみしか一覧表示しないので、この中にコンテナが入ってなければ起動失敗と認識してOKです。
コンテナが正常に起動していない場合は、以下の項目を参照してみてください。
コンテナが起動しない時の基本動作
vm.max_map_countの設定値不足による起動エラー
動作確認
コンテナが正常に起動していたら、以下の操作で動作確認します。
- Kibanaへのブラウザアクセス
- http://<パブリックIP>:5601
- アクセス後にKibanaのTop画面が表示されればOK
- elasticsearchにサーバ内でcurlコマンドを実行
curl localhost:9200
- コマンド実行後に以下のような結果が出ればOK
{
"name" : "_2cmTM_",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "L-ftBXNTQJW_iiVW4PTujg",
"version" : {
"number" : "6.3.2",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "053779d",
"build_date" : "2018-07-20T05:20:23.451332Z",
"build_snapshot" : false,
"lucene_version" : "7.3.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
以上が構築から正常起動確認までの流れになります。
構築時発生エラーとその対処
個人的に構築している際にエラーが発生して詰まったポイントとどう対処したかを解説します。
docker-compose up -d
の実行時にエラーが発生
- エラー内容
$ docker-compose up
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
- エラー原因
- docker-compose コマンドを実行したユーザがアクセスできる権限を持っていないため
- エラー対処
- 以下のコマンドを順に実行し、
docker
というグループにユーザを所属させます。 - dockerグループの作成:
sudo groupadd docker
- 現行ユーザをdockerグループに所属:
sudo gpasswd -a $USER docker
- dockerデーモンを再起動する:
sudo service docker restart
- 設定反映のためexitして再ログイン:
exit
- 以下のコマンドを順に実行し、
コンテナが起動しない時の基本動作
私がエラー解析などで使った手順です。
(もっと良い手順もあるはずですが、今回はこれで解決したのでメモです)
-
- 起動原因の切り分け
-
docker ps
コマンドを実行して、コンテナが起動していなければ、docker ps -a
コマンドで、全てのコンテナを一覧表示し、「特定のコンテナのSTATUSがEXIT()」になっているかを確認 - docker-compose.ymlに異常があってそもそもイメージ取得などでこけているのか、起動で失敗しているのかを切り分け
-
- 起動失敗コンテナの起動ログを確認
- 起動失敗している場合は、失敗しているコンテナに対して
docker logs <CONTAINER ID>
を実行することで、コンテナ起動時のログと失敗理由を参照できます。
インスタンスメモリ不足による起動失敗
- エラー内容
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /tmp/hs_err_pid1.log
- エラー原因
- インスタンスメモリ不足(t2.microでケチった結果です。。。)
- エラー対処
- インスタンスタイプを変更し、メモリを増設(t2.micro⇒t2.medium)
file descriptorの設定変更漏れによる起動エラー
- エラー内容
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
- エラー原因
- BootstrapCheck(設定が推奨値に達していなかったり、変な設定が入っているとエラーになって終了する)により、file descriptorの設定値が既定よりも不足していたため
- エラー対処
- docker-compose.ymlファイルに
ulimits:
の設定を追加し、再度docker-compose up -d
を実行。
公式リファレンス - ulimits設定は、ホストを変更してもコンテナに設定反映されないため、YAMLファイルに直接設定を書き込む必要がある。
- docker-compose.ymlファイルに
vm.max_map_countの設定値不足による起動エラー
- エラー内容
[2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
- エラー原因
- BootstrapCheck(設定が推奨値に達していなかったり、変な設定が入っているとエラーになって終了する)により、vm.max_map_countの設定値が既定よりも不足していたため
- エラー対処
-
sudo sysctl -w vm.max_map_count=262144
コマンドを実行し、設定ファイルを書き換え - vm.max_map_count設定は、ホストの変更がコンテナにも影響するため、ホストを書き換えればOK
-