locustのNUM_CLIENTSとHATCH_RATEについて
背景
GAEで作ったAPIサーバーを本番反映するに当たり必要なリクエスト数さばけるのかを確認する必要があった。先輩社員がlocustを使っていたので自分もlocustを使ったが、NUM_CLIENTSとHATCH_RATEの挙動が分からな過ぎた。NUM_CLIENTSとHATCH_RATEの関係が分からなかったし、locustを動かしているとAll locusts hatched
というログを残して計測した情報が一旦リセットされる理由もわからなかった。
結論
NUM_CLIENTSは同時接続数でサーバーでさばきたい接続数でOK。
問題はHATCH_RATEでこいつはクライアントを毎秒いくつ作るかを指定する。そしてNUM_CLIENTSで指定した数までクライアントを作ったら統計情報がリセットされる。
つまり最初クライアントは0で、HATCH_RATEで指定した数だけクライアントが作られていくことで、接続数が徐々に増えていく状況をシミュレート出来る。これによりオートスケールの設定が正しく動いているかが確認できる。また、本当に計測したいのは"オートスケールした後のピークリクエスト時に正しくリクエストを捌けるか"なので統計情報がリセットされる。
docker multi stage buildを試す
背景
reviewdogのDockerfileについて先輩社員にレビューもらうと、dockerのmulti stage build使うと幸せになれるよと教えてもらった。
レビューをもらったDockerfileは以下。pythonのdockerイメージにgoをインストールしてからgo getでreviewdogを入れている。これをまずgoのイメージでreviewdogをgo getしてきて、pythonのイメージにコピーしてくればいいんじゃないの?という意図で言ったのだと思う。
FROM python:3.6 USER root ENV HOME /root # install Golang ARG GO_VERSION=1.8.3 RUN mkdir /tmp/go && \ cd /tmp/go && \ curl -O -sS -L https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz && \ tar zxf go${GO_VERSION}.linux-amd64.tar.gz && \ mkdir /usr/local/go && \ mv go/* /usr/local/go && \ rm -rf /tmp/go ENV GOPATH=${HOME}/go ENV PATH=${PATH}:/usr/local/go/bin:${GOPATH}/bin # install reviewdog RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog ENV GITHUB_API="https://github.com/api/v3/" ARG GITHUB_API_TOKEN="" ENV REVIEWDOG_GITHUB_API_TOKEN=${GITHUB_API_TOKEN} # リポジトリをコンテナにマウント ARG WORK_DIR WORKDIR ${WORK_DIR} ENV APP_ROOT ${WORK_DIR} COPY . ${APP_ROOT} # install flake8 RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming
結論
やってみた。こんな感じになった。goはバイナリに出来るので、ランタイムが不要になるのでこういうことが出来るのか。素晴らしい。golangのインストールとかGOPATHの設定がなくなっていい感じになりました。
FROM golang:latest as reviewdog # install reviewdog RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog # ------------------------------------------------------ FROM python:3.6 USER root ENV HOME /root # reviewdogの設定 COPY --from=reviewdog /go/bin/reviewdog /usr/local/bin/reviewdog ENV GITHUB_API="https://github.com/api/v3/" ARG GITHUB_API_TOKEN="" ENV REVIEWDOG_GITHUB_API_TOKEN=${GITHUB_API_TOKEN} # install flake8 RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming # リポジトリをコンテナにマウント ARG WORK_DIR WORKDIR ${WORK_DIR} ENV APP_ROOT ${WORK_DIR} COPY . ${APP_ROOT} # 自前のflake8 pluginのインストール RUN pip install flake8_ml_batch/
IntelliJでproject painとかをショートカットでリサイズする
背景
IntelliJと書いたがPyCharmもRubyMineでも同様。
Command+1でプロジェクトペインが開けるが、windowをガチャガチャリサイズしたあとだとプロジェクトペインのサイズが以上にデカかったり小さかったりする。マウスでサイズ調整してたが、キーバインド割り当てられてないのか?と思って調べた。
結論
Resize (tool) windows with keyboard | IntelliJ IDEA Blog
リサイズしたいペインにフォーカスを当てて、Shift+Command+カーソルキーでリサイズできた。
docker runでローカルのgoファイルを実行する
背景
RealWorldHTTPを読み始めた。goでサンプルのHTTPサーバを立ててcurlで色々オプションを付けてリクエストを試しながら挙動を確認していくようだった。
それで、サンプルのHTTPサーバーを書いたんだけど、dockerで実行したくて以下のようにした。
$ docker run golang go run server.go
が、当然docker runに渡すコマンドはコンテナ内で実行されるので、server.goはコンテナ内には無いのでこうなる。
stat server.go: no such file or directory
結論
まずdockerコンテナのワーキングディレクトリを調べる。
$ docker run golang pwd /go
/goらしい
そしたらローカルのカレントディレクトリを/goにボリュームしながらrunする。
$ docker run -v $PWD:/go golang go run server.go
docker run -vに渡すパスは絶対パスでないとならないので.(ドット)で渡すとdockerに怒られるため$PWDとするしかない。
あとはdocker-composeのvolumesを使う方法もあるけど、そのためだけにdocker-compose.ymlを書くのも馬鹿らしいので上でやることにした。
drone.ioでdocker run -vしてハマった
背景
drone.ioでreviewdogを使いたくてこんな感じで書いた。
Dockerfile.reviewdog
FROM python:3.6 USER root ENV HOME /root ARG WORK_DIR WORKDIR ${WORK_DIR} ENV APP_ROOT ${WORK_DIR} # install Golang ARG GO_VERSION=1.8.3 RUN mkdir /tmp/go && \ cd /tmp/go && \ curl -O -sS -L https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz && \ tar zxf go${GO_VERSION}.linux-amd64.tar.gz && \ mkdir /usr/local/go && \ mv go/* /usr/local/go && \ rm -rf /tmp/go ENV GOPATH=$HOME/go ENV PATH=$PATH:/usr/local/go/bin:$GOPATH/bin # install reviewdog RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog ENV GITHUB_API="https://github.com/api/v3/" ARG GITHUB_API_TOKEN="" # build時にGITHUB_API_TOKENを渡す ENV REVIEWDOG_GITHUB_API_TOKEN=$GITHUB_API_TOKEN # install flake8 RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming
.drone.yml
pipeline: reviewdog: image: drone-build:latest volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WORK_DIR=/usr/src/app commands: - export GITHUB_API_TOKEN="GITHUB_API_TOKEN" - docker build --build-arg WORK_DIR=$WORK_DIR --build-arg GITHUB_API_TOKEN=$GITHUB_API_TOKEN -t reviewdog:latest -f Dockerfile.reviewdog . - docker run -v $PWD:$WORK_DIR reviewdog:latest /bin/bash -c "flake8 . | reviewdog -ci=droneio -f=pep8" when: event: pull_request
だが、reviewdogがreviewをしてくれない。(flake8が文句を言うコードはリポジトリに含まれている)
docker run -v $PWD:$WORK_DIR reviewdog:latest /bin/bash -c "flake8 ."
としてもflake8も何も出力してくれなかった。
仮設
docker run -v $PWD:$WORK_DIR reviewdog:latest ls
としたが、droneのログに出力されなかったので、docker run -vが何らかの理由で効いておらずマウントされていないのでないかと考えた。
結論
https://stackoverflow.com/questions/31381322/docker-in-docker-cannot-mount-volume
A Docker container in a Docker container uses the parent HOST's Docker daemon and hence, any volumes that are mounted in the "docker-in-docker" case is still referenced from the HOST, and not from the Container.
Dockerコンテナの中で動かすDockerデーモンはHOSTのものらしい。なので、docker run -v で渡すファイルパスはHOSTのものになってしまっているとのこと。
なので、droneではdocker in dockerは使わないで予めDockerfile.reviewdogの中でCOPYをしてから、prepareでdocker buildするようにしました。
Dockerfile.reviewdog
FROM python:3.6 USER root ENV HOME /root ARG WORK_DIR WORKDIR ${WORK_DIR} ENV APP_ROOT ${WORK_DIR} # install Golang ARG GO_VERSION=1.8.3 RUN mkdir /tmp/go && \ cd /tmp/go && \ curl -O -sS -L https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz && \ tar zxf go${GO_VERSION}.linux-amd64.tar.gz && \ mkdir /usr/local/go && \ mv go/* /usr/local/go && \ rm -rf /tmp/go ENV GOPATH=$HOME/go ENV PATH=$PATH:/usr/local/go/bin:$GOPATH/bin # install reviewdog RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog ENV GITHUB_API="https://github.com/api/v3/" ARG GITHUB_API_TOKEN="" # build時にGITHUB_API_TOKENを渡す ENV REVIEWDOG_GITHUB_API_TOKEN=$GITHUB_API_TOKEN # install flake8 RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming COPY . $APP_ROOT # ここを追加
.drone.yml
pipeline: prepare: #prepareでdocker buildをしてしまう image: drone-build:lates volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WORK_DIR=/usr/src/app commands: - export GITHUB_API_TOKEN="GITHUB_API_TOKEN" - docker build --build-arg WORK_DIR=$WORK_DIR --build-arg GITHUB_API_TOKEN=$GITHUB_API_TOKEN -t reviewdog:latest -f Dockerfile.reviewdog . reviewdog: image: reviewdog:latest environment: - flake8 . | reviewdog -ci=droneio -f=pep8 when: event: pull_request
GCPでprojectをまたいだ権限の設定方法
背景
読み飛ばしてOK。自分用メモ。
AppEngineからBigTableを読み込みたかったが、BigTableはprdにあり、AppEngineはdev,stg,prdに立ち上げる予定で、devのAppEngineからprdのBigTableを読み込むとい うprojectを跨いでアクセスする必要があったが、やり方がわからず権限周りに詳しいひとに聞いたので、メモ。
結論
devのAppEngineのサービスアカウントproject-dev@appspot.gserviceaccount.comをprdのIAMから追加しBigTable読み込みの権限を付ける。
サービスアカウントについて
https://cloud.google.com/iam/docs/service-accounts?hl=ja
サービスアカウントについて理解している必要があったので読んだ。
サービスアカウントが良くわからなかったんだけど、公式のマニュアルを読んで理解した。
サービス アカウントは、個々のエンドユーザーではなく、アプリケーションや仮想マシン(VM)に属している特別な Google アカウントです。アプリケーションはサ ービス アカウントを使用して、ユーザーの関与を必要とせずに Google のサービス API を呼び出すことができます。
なので、VMを作るとそのVMに対してサービスアカウントが作られて、そのサービスアカウントに設定されている権限の範囲でVMは動作するということだった。
今回の場合はAppEngineのサービスアカウントに対して、BigTableの読み込み権限を付けることで、AppEngineはBigTableを読み込むことができるようになる。