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

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

ECS Agent 1.19.0だとDocker containerのメタ情報を取れない場合がある

表題のとおりですが,ECS Agent 1.19.0だとDocker containerのメタ情報を取れず (取れない場合がある),いろいろ困るという現象が発生します.

github.com

このissueにあるようにDocker Container IDをうまく取れないことが問題のようです.
おかげでElastic BeanstalkのDocker環境で動かしているアプリケーションが吐くログをうまく取れなくなってしまって大層困った……

なおこの問題はECS Agent 1.19.1で修正されているので,お使いの方はアップグレードしたほうが良いと思います.以上です.

Kyoto.なんか #4で最近運用しているJenkinsの情報について発表してきました

[2020-09-07追記]
この構成,もうウチではやってません!!!!
moznion.hatenadiary.com
[追記ここまで]


kyoto-nanka.connpass.com

表題の通り,最近AWS上で運用しているスケールする & 運用が省エネなJenkinsについて発表してきました.

簡単にまとめると

  • JenkinsのslaveをAWS CodeBuildに委譲することで実質無限のスケールアウトとメンテコスト削減を実現
  • JenkinsのストレージをAmazon EFSにすることでロバスト性と自動ボリューム拡張を実現
  • ElasticBeanstalk with Dockerを使って運用することで運用コストの省力化

という内容です.


会場やインターネットで質問されたことについては以下のとおりです:

値段的には従来のサービスを使うよりも下がったかどうか?

  • 試算的には下がっている
  • やはりCIが寝ている時間が多いと,CodeBuildの時間貸しスタイルがうまくはまって効くという感じ
  • とはいえ今後継続的にコストの実測を行って経過観察をする必要がある

強い環境でビルドしたいという話だったが,CodeBuildはインスタンスタイプを選べる?

  • 選べる
  • 3 GB メモリ、2vCPU
  • 7 GB メモリ、4vCPU
  • 15 GB メモリ、8vCPU
  • (会場ではうろ覚えで間違えたスペックを口走ったかもしれません,すみません)

CodeBuild上でのビルド環境はDockerということだったが,このDockerイメージはどこかにアップロードしておく? あとキャッシュみたいなのは効く?

  • CodeBuild上ではサポートされている言語であれば素のDockerイメージが提供されており,その上でビルドを行うことができる
  • 独自のビルド環境が欲しいのであれば自分でDockerイメージを構築してECRにアップロードして利用すれば良い
  • キャッシュについては任意のファイル (or ディレクトリ) をS3に突っ込んでキャッシュすることができるので便利
    • 例えば解決済みの node_modules のようなものをキャッシュしておくことが可能

プラグイン管理が魔界にならないか

Jenkins.instance.pluginManager.plugins.each{
  plugin ->
  println ("${plugin.getShortName()}")
}

Jenkinsは色々とランタイムを入れられて環境が汚くなる印象があるがどのように対処しているか

  • 実際のビルド環境は基本的にCodeBuild上なのでJenkinsがいたずらに汚くなることはなさそう
  • なんらかのランタイムをインストールする必要がある場合はDockerfileで構成管理するぞ,という気持ち
    • (まだその状況に至っていない)


という感じでした.参考になれば幸いです.

Kyoto.なんかはいろいろおもしろい話が聞けて楽しいですね.来年の開催も楽しみにしています!!

JenkinsでGitHub Pull Request Builder pluginを使いつつ任意のブランチにpushしたコミットもビルドする

JenkinsでGitHub Pull Request Builder (ghprb) を使っている時に,pull request以外のcommit (例えばmasterへのマージコミットや任意のブランチへの直push) もbuildしたいんすよね〜みたいなことをid:hdkshjmさんに相談したところ良い感じの方法を教えてもらったのでメモとして記すものです.ありがとうございます!

前提として

  • ghprbの設定は済んでいる
  • Git pluginがインストールされている
  • GitHub pluginがインストールされている
  • GitHubリポジトリのWebhook設定で $JENKINS_BASE_URL/github-webhook/ に向けてpushイベントを設定している

ものとします.

そんでもって以下のようにすると良い:

  • プロジェクト設定のGit SCMのリポジトリ設定でRefspecに +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* を指定する (高度な設定から設定できる)
    • ghprbではpull requestだけがターゲットなので +refs/pull/*:refs/remotes/origin/pr/* を指定しておけば良い
    • それに加えて +refs/heads/*:refs/remotes/origin/* を指定することによって任意のブランチへのpushも引っ張ってこれるようにしておく
  • 「ビルドするブランチ」にビルドしたいブランチの名前 (e.g. master, develop and etc) を指定する
    • ghprb向けには ${sha1} とか設定されているはずなので *1,そこに追加するという感じ
  • トリガ設定で GitHub hook trigger for GITScm polling にチェックを入れる

これでOK! 例えば「ビルドするブランチ」に master を設定しておけばmasterへのマージコミットや直push (まあ野蛮!) についてもbuildを回すことができて便利です.
pull-requestについてはghprb pluginがbuildをキックし,一方で指定したブランチへのpushについてはGitHub pluginがbuildをキックするという感じです.基本的に互いが重複してbuildをキックすることは無いでしょう (「ビルドするブランチ」に指定したブランチを他のブランチに向けるpull-requestを作ったら話は別ですが).


ところでJenkins 2.0以降を使っている場合Jenkinsfile及びパイプラインが使えますから,pipeline-githubあたりを駆使するとgroovyでプログラマブルに色々操作できるため,今となってはghprbを使わずにJenkinsfileでやったほうが良いかもわかりませんね.そう思います.現場からは以上です.

*1:${ghprbActualCommit} if you want to use the head of the pull request branch (e.g. refs/pull/4/head); or ${sha1}, to use GitHub's tentative merge of the compare and base branches (e.g. refs/pull/4/merge) if the PR can be automatically merged or the head of the pull request branch (e.g. refs/pull/4/head) if they can not be automatically merged. GitHub - jenkinsci/ghprb-plugin: github pull requests builder plugin for Jenkins

Over HTTPでやり取りするAWS Lambdaのfunctionを書く時にはKeep-Aliveがパフォーマンスに効く(場合がある)

サーバレスだ! Microservicesだ! というふうなアーキテクチャになってくるとAWS Lambdaのような実行環境でコードを動かすことが多くなってくると思います.そしてそうした環境下で他のコンポーネントとHTTP越しにやりとりをするコードを動かすこともままあるでしょう.
そういった時にKeep-Aliveを有効にしておくとLambdaは一度張ったコネクションを使いまわしてくれるので,「同じエンドポイントを頻繁に叩く」かつ「呼ばれる回数が多い」Lambda functionだと結構パフォーマンスに効いてきます (もちろん接続先がkeep-aliveに対応している必要がありますが).

ということをLambdaのパフォーマンス周りのトラブルシューティングを行っている最中にふと気づき,やってみたところ果たしてパフォーマンスの問題は見事解決したわけですが,その後AWSが出しているLambdaのベストプラクティスのドキュメントを読んでみるとまさに同じことが書いてあり,やはり公式のドキュメントは強い……

> 前回の呼び出しで確立した接続を (HTTP、データベースなど) をキープアライブにして再利用します
AWS Lambda 関数を使用する際のベストプラクティス - AWS Lambda

AWS Lambdaはそのプロセスが立ち上がってからはライフサイクルに従って一定期間同一のプロセスが使用されるので,一度確保したリソースを使い回すことができます.従ってKeep-Aliveを有効にしておくと一度確立したコネクションを使いまわしてくれるため,コネクションを毎度張らずに済んでそのぶんの実行コストが減って経済的という感じです.助かった!


なお他のコンポーネントとOver HTTPでコミュニケーションするタイプのLambdaのアーキテクチャの是非についてはid:y_uukiさんのブログに良い考察があります:


ところで

この件ですがみなさんはどう呼んでいますか? おたよりをお待ちしています.

builderscon tokyo 2018に登壇します

表題の通り,builderscon tokyo 2018に登壇します.JavaCardという環境をテーマにお話する予定です.

builderscon.io

今回はかなりマニアックな話になることが現時点で予想されていますが,内容はかなり面白いと思います (先日社内の専門家にディープな講習を受けました). いつものJavaとは一味違うJavaを目の当たりにすることになるでしょう……

9/7 (金) の15:30からセッション開始ですから,お昼から会場内のHUBで一杯引っ掛けてから来てもちょうど良い感じの時間ですね! 是非会場でお会いしましょう!!!!

pptxファイルから発表者ノートを一括削除する方法

カンペとしてスライドに発表者ノートを書くことはままあるとおもうんですが,そのスライドを共有する際には発表者ノートを削除したくなるのが人情というものです (カンペを見られるのは恥ずかしい).
Windows版のPowerPointであれば発表者ノートを一括削除するメニューがあるのですが,一方macOS版のPowerPointにはなぜかそのメニューが無いため手でポチポチやるしか方法は無いのか……と途方に暮れていたところ,pptxはそもそもzipでアーカイブされたxmlの集合体ということを思い出し,unzipしてxmlを書き換えてzipし直すという手法を思いつきました.

以下スクリプト:

#!/bin/bash

set -eu

PPTX_FILE_PATH="$1"
PPTX_FILE="$(basename "$PPTX_FILE_PATH")"

TMP_DIR="$(mktemp -d)"
trap 'rm -rf $TMP_DIR' EXIT

cp "$PPTX_FILE_PATH" "$TMP_DIR"

pushd "$TMP_DIR"

unzip "$PPTX_FILE"
rm "$PPTX_FILE"
gfind ./ppt/notesSlides/*.xml | xargs gsed -i'' -e's/<a:t>[^<]*<\/a:t>/<a:t><\/a:t>/g' # remove slide note contents
zip -0 -r "$PPTX_FILE" ./* # do not compress (-0)

popd

cp "$TMP_DIR/$PPTX_FILE" "note-removed-$PPTX_FILE"

これで発表者ノートを消すべきpptxファイルがたくさんあっても安心! よかったですね.