その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

CircleCI 2.0でElasticsearchを起動しつつテストする

例えばElasticsearchを使ったプロジェクトがあったとして,それをCircleCIで継続的にテストしたいとする.CircleCI 2.0はコンテナベースのCI環境なので,そのプロジェクトが採用している言語のコンテナの上でElasticsearchを動かす必要がある.どうするか.

circleci.com

CircleCIのドキュメントに記されている通り,docker imageは複数起動することができる.一番目に指定したdocker imageはprimary containerとして取り扱われ,stepsに書く手続きは全てそのコンテナ上で実行される.それ以降にdocker imageを指定した場合はそのimageがprimary containerと共通のネットワーク上で立ち上がり,そのコンテナ上で公開されているポートについてはprimary containerのlocalhost経由でアクセスすることが可能となる.これで手っ取り早く依存しているストレージをdockerで立ててテストすることができる (今回はたまたまElasticsearchの話題だったが,これはRedisでもmemcachedでも,docker imageがあるものであればなんでも応用が効く).

つまり,例えばjavaのプロジェクト上でElasticsearchのテストを行いたい場合は以下のようなconfig.ymlを書くと良い;

# https://circleci.com/docs/2.0/language-java/
version: 2
jobs:
  build:
    docker:
      - image: circleci/openjdk:8-jdk
      - image: docker.elastic.co/elasticsearch/elasticsearch:5.6.1

    working_directory: ~/awesome-project

    steps:
      # do something!

この場合,JDK8のコンテナがprimary containerとなり,Elasticsearchはsecondary container (という言い方が正しいのかどうかはわからないが) として立ち上がる.

さて,Elasticsearchのデーモンの設定を手っ取り早くいじりたいんだけど (要はdocker run -e'xxx=yyy'みたいな感じで制御したいんだけど) みたいな時にどうすれば良いのかというと

circleci.com

にあるように,environmentを設定すると良い.
例えば,

      - image: docker.elastic.co/elasticsearch/elasticsearch:5.6.1
        environment:
          http.host: '0.0.0.0'
          http.port: 9200
          xpack.security.enabled: false

というふうにしてやると,localhost:9200をlistenしつつ,xpackのセキュリティ設定 (要はBASIC認証) をバイパスしてElasticsearchを立ち上げることが可能となる.

ところで.CircleCIの弱いインスタンスを使っているとElasticsearchがOOMしてずっこけるという事態に出くわす.出くわすのです.僕は出くわした.そういう時にどうすればいいかというと,

  • CircleCIを良いプランにする (本質的な改善!!!)
  • Elasticsearchのヒープサイズを低くする

という方法が考えられる.色々な理由から前者が難しい場合,後者に頼るほか無いのでこうしてやるしかない;

      - image: docker.elastic.co/elasticsearch/elasticsearch:5.6.1
        environment:
          ES_JAVA_OPTS: '-Xms256m -Xmx256m'

プロダクションでは考えがたい蛮行だがまあテストだし……というわけで動く.
これでテストがハチャメチャに遅くなって支障をきたすようであれば調整する必要があるだろう……ガンバだよ!!!