技術(tech)

DockerImageをカスタマイズしてDockerHubに登録する

DockerImageをカスタマイズしDockerHubに登録する

はじめに

この記事は、公式で公開されているDockerImageに一部アプリケーションの設定に変更を加えたDockerImageを作成し、DockerHubに登録する手順を記したものです。
私自身Dockerはあまり詳しくなく、デフォルトのDockerImageに少しだけ変更を加えてコンテナを建てる場合にはどうすればいいのかが分からずに、色々調べたり試したりしてみて最終的に実践した方法をまとめています。

この記事の対象者

  • DockerImageを少しだけ変えて保存したんだけれども、どうするんだ?って人

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

  • DockerImageに変更を加えたものを新たにDockerImageとして登録できる
  • 上記のDockerImageをDockerHubに登録できる

なぜDockerImageをカスタマイズしたくなったのか

具体的には、以下の作業を実施している時に、困りごとが2つありました。
Docker-composeでECS上にコンテナを起動してログ収集・分析基盤(ELK)を構築する

公式で公開されているDockerImageだとメモリの関係でコンテナが起動しない

最初は、EC2のt2.smallインスタンス(メモリ2GB)の中でElasticsearchとLogstashを起動しようと試みていました。しかし、公式で公開されているDockerImageの初期設定では、これらのアプリケーションで占有するメモリがそれぞれ1GBでした。
つまり、そのままのDockerImageではElasticsearchとLogstashが両方起動出来ずに、コンテナが落ちてしまいます(ぴったり2GBだし起動出来るじゃん!!となる訳もありませんでした…)。そこで、コンテナ起動前にアプリケーションで占有するメモリの設定を変更する必要がありました。
system.006.jpeg

コンテナを起動する度に、特定のファイルを都度配置する必要があった(面倒)

Logstashではconfファイルの設定に基づいて、アプリケーションが動作します。公式で公開されているDockerImageからコンテナを起動した時点では、このconfファイルが配置されておりません。そのため、コンテナ起動後に手動でconfファイルを配置するという、イケていない運用をしていました。

対応策として、Dockerのボリューム(Data Volume)を使用してマウントすることで、データを永続化すればいいじゃんという話もあるかと思います。しかし、ECインスタンス上でコンテナを起動しており、単純にローカルのディレクトリとコンテナ間でボリュームをマウントすることが出来ませんでした(ただ単に知識不足というのもあります。またEBSボリュームも使いたくなかった)。

そんなことがあり、「このDockerImageをベースとして、メモリの設定ファイルだけ書き換えたいな・・・、このconfファイルをコンテナ起動時に配置したいな・・・」と思うことが度々ありました。

方法:設定ファイルの書き換え & confファイルの配置

  1. docker-composeで環境変数を設定する
    元々docker-composeを使って、ECSでコンテナを起動していたため、docker-compose.ymlの環境変数の設定を追記しました。アプリケーションのメモリの設定については、こちらで対応できました。
  2. DockerImageをカスタマイズしてDockerHubに登録する
    既にconfファイルが配置された状態のDockerImageを作成して、docker-composeで読み込むイメージにしてしまおうという発想に至りました。confファイルの配置については、こちらで対応できました。

手順

  1. docker-composeで環境変数を設定する
    単純に環境変数(environment)に設定するだけでした。
    環境変数って、どこまで設定できて・設定できないものは何なのかイマイチ分かっていません。公式ページやググった結果、環境変数を設定している事例を漁りながら設定していました。この辺は何を見ればわかるのでしょうか…
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:
  1. DockerImageをカスタマイズしてDockerHubに登録する
    こっちが本題だったような… まぁ気にせずに…

以下のページが参考になりました。
独自のDockerImageを作成する
DockerImageをDockerHubに登録の仕方

まずは編集したいDockerImageからコンテナを起動する。

docker run -it gogogonkun/logstash bash  

適当にファイルを配置したり、編集したりする

vi /usr/share/logstash/pipeline/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"
        }
    }
}
※省略

変更内容から新たにDockerImageを作成

docker container ps
docker container commit [CONTAINER ID] [イメージ名(DockerHubのリポジトリ名と合わせる)]:[タグ]
例:docker container commit a94665bc5f13 gogogonkun/logstash_pub:latest

DockerHubへイメージをプッシュする

docker push gogogonkun/logstash_pub:latest

DockerHubから確認してみます

スクリーンショット 2019-05-22 2.41.28.png

DockerHubに登録できています。
docker-composeで起動するコンテナのイメージとして使用する場合には、登録されたリポジトリ名を指定すると、カスタマイズしたDockerImageが起動します。

おわりに

今回の対応方法が正しいかどうかは分かりません。詳しい人が居たら教えて欲しいです。あと、日本語ガバガバなのは大目に見つつもご指摘いただければ嬉しいです。