AWS CLI version 2 を準備する bash function

bitbucket.org

ずっと放置してたけどやる気になったので準備した。

細かいエラー制御はしてないし、環境変数の調整も適当だけど、 awscli-install するだけで OK。

次のような動機がある人には有用かなと。

  • 普段は Windows 10 + WSL2 な環境で過ごしてる
  • AWS CLI version 1 から移行したほうがいいと思ってる
  • pip install awscli と同じくらい楽でないとやる気にならない

Amazon Linux 2 なら yum install で導入できるか導入済みなんだと思うけど、他の環境やディストリビューションは様子見なのかなぁ。

oracle/database:11.2.0.2-xe をビルドするときは buildkit を無効にする

状況

Oracle の公開しているリソースを利用すると Oracle Database 11g R2 (XE) のコンテナイメージをビルドできるみたいなので試してみた。

Docker daemon のバージョンはこんな感じ。

$ env|sort|grep DOCKER
DOCKER_CERT_PATH=C:\Users\user\.minikube\certs
DOCKER_HOST=tcp://192.168.3.14:2376
DOCKER_TLS_VERIFY=1
DOCKER_BUILDKIT=1

$ docker version
Client:
 Version:           19.03.1
 API version:       1.40
 Go version:        go1.12.7
 Git commit:        74b1e89e8a
 Built:             Wed Jul 31 15:18:18 2019
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.12
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       48a66213fe
  Built:            Mon Jun 22 15:49:35 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

問題

  • DOCKER_BUILDKIT=1 にしていると docker build がハングアップする

    • RUN 命令の yum install がスタックする
    • ベースイメージの oraclelinux:7-slim で実行したら普通に動くのでお手上げになった
    • 詳しい原因は分からない
  • Oracle RAC について問題は異なるけどやはり buildkit に起因する失敗が報告されてる

回避策

  • docker build するときは DOCKER_BUILDKIT=0 にする

第4回 Chaos Engieering 読書会@リモートのログ

learning.oreilly.com

javaee-study.connpass.com

引き続き Discord によるオンライン開催。

合計 300 ページくらいのところを毎回 30 ページくらい進んでるので、全部で 10 回くらいになるのかなぁ。

次回は 8/15(土曜日)で、CapitalOne の事例から。

javaee-study.connpass.com

対象

  • 6 Microsoft Variation and Prioritization of Experiments
    • 6.3 Prioritization of Failures
    • 6.4 Degree of Variation
    • 6.5 Deploying Experiments at Scale
    • 6.6 Conclusion
  • 7 LinkedIn Being Mindful of Members
    • 7.1. Learning from Disaster
    • 7.2. Granularly Targeting Experiments
    • 7.3. Experimenting at Scale, Safely
    • 7.4. In Practice: LinkedOut
    • 7.5. Conclusion

トピック

  • 便乗してマイク買った! SHURE MV88+ VIDEO KIT
  • オーディオミキサー買った! MAONCASTER
  • エンジニアの情報発信スキルに動画制作スキルが加わる未来が来る
    • 「ブログエンジンを書く」から「いい感じの動画を公開する」へ
  • テキストと比べた動画の(発話の)難しさ
    • 滑舌や言い間違い、つっかえたり
  • Evernote から Notion へ移行した
  • Twitter の障害に巻き込まれた
  • やっぱり座椅子じゃなくてアーロンチェア買うことにした

ディスカッション

6. Microsoft Variation and Prioritization of Experiments

6.3 Prioritization of Failures

6.4 Degree of Variation

  • もしMicrosoftやAmazonやAakamaiがニュースになるような障害を起こしても顧客はそんなに気にしないかもしれません。彼らは彼らのサービスの回復のみを望むでしょう。
    • 契約を変えるか金を出すのか、どちらかの選択肢しかない
    • CDN がエッジコンピューティング機能を持つようになってきてるからいろいろと不安感が増してる気がする
  • DataDog を使うとどういうふうに依存関係を見れるようになるの
    • 分散トレーシングのメトリクスからサービスマップを生成するとかそういう感じで見れる

6.5 Deploying Experiments at Scale

  • そもそもだけど、カオスエンジニアリングに取り組む前提になっているのは、監視ができているとかそういう状態なのかな?
    • そうだと思う
    • 定常状態を定義できることが前提だから
  • メトリクスとしてログを見れる人が限定されている環境がほとんどだと思うけどそれってどうなんだという
    • それぞれのサービスのログを見れるのはサービスの担当者だけってなってる
      • 必要な情報は最近の分なら DataDog に集約して見えるようにしてる
  • 公開されてるカオス実験のレポートって見ないけどログも入ってるのかなぁ
    • 障害報告書と同じような構成になるから入ってるんじゃないかな
    • システムの内部から見た場合と外部から見た場合で求める粒度が違いそう

6.6 Conclusion

はい

7. LinkedIn Being Mindful of Members

7.1. Learning from Disaster

  • 1986 年のチェルノブイリ原子力発電所事故の事例から学びましょう
    • カオスエンジニアリングに興味を持った人は皆知っておいた方がいい事例だった
    • 実験は、ユーザーへ影響を与える可能性を最小化するため、安全第一でやらないといけない

7.2. Granularly Targeting Experiments

7.3. Experimenting at Scale, Safely

  • 連鎖障害しそうな分散システムで緊急停止ボタンはどうあるべきなんだろう
    • サーキット・ブレーカーがどうあるべきか、みたいな
    • 定常状態の定義によって変わってきそう
      • メンテナンスページ出して終わり、なんてことはない
    • 実験のために細工したことを戻すだけじゃ済まないだろう
    • リクエスト注入型なら割合を変更するだけでよさそう
    • kill -KILL で回復する状況って何
      • ツールを止めるとかそういう
      • サービスプロセスを再起動させるようなものかなと
    • 壊れたデータは取り返しがつかないような
    • 実験を中止するだけで、障害自体の復旧は別なのかもしれない

7.4. In Practice: LinkedOut

  • 他の事例だとすごいコストがかかる活動をイメージしがちだったけど、LinkedIn の事例はフレームワークやツールや自動化に触れていてイメージしやすい
    • 余剰でやる活動、というより、普通に行う活動に一体化してるのがよい
  • 実験することを念頭に設計したフレームワークで開発し、実験することを前提に利用者を考慮したツールを整備する考え方は今後大切になってくる

参考情報

いろいろ並べたけど全部は読めてない。

トピックより

ディスカッションより

第3回 Chaos Engieering 読書会@リモートのログ

learning.oreilly.com

javaee-study.connpass.com

引き続き Discord によるオンライン開催。

合計 300 ページくらいのところを毎回 30 ページくらい進んでるので、全部で 10 回くらいになるのかなぁ。

次回は 7/18(土曜日)です。

javaee-study.connpass.com

対象

  • 4. Slack’s Disasterpiece TheaterGetting Management Buy-in から

トピック

ディスカッション

4. Slack’s Disasterpiece Theater

Getting Management Buy-in

Impossibility Result

  • 設定変更を司るサービスを停止しても本体機能には何も影響しないと期待していた
  • 実際は本体機能の設定変更 API をつついたら応答が返ってこなかった
  • 本体は設定変更ができないときはエマージェンシーモードで動くようになっていたけど、通常モードのときと同じく Slack Channel に投稿して何かを待機する状態になっていた
  • ということで設定の不整合があるのは残念な結果だった、ということかなと

そのほか

  • この文章書いたの誰だっけ

  • 結構前から仕事でも Slack 使ってるけどときどき意味不明なエラーが起きることがあった

    • もしかして実験してたのかな
    • 人によって問題に対する感度が違うような気もする

5. Google DiRT: Disaster Recovery Testing

LEGENDS: テックリードが休暇に入るとコード検索が途切れる

  • あるあるすぎて辛い

The Rules of Engagement

What to Test

  • 項目の粒度がばらばらなのが気になる
  • 分散サービスだとバックアップからのリストアがとてもややこしい問題になりそう
  • Kafka のバックアップについて
    • 伝統的には別々の SAN を用意するんだけどできない
    • バックアップクラスタを用意するのが無難
  • 結果整合性に基づくシステムではどこにバックアップの断面を設定することになるのか
    • サーガしてるならその辺でどうにかする
    • Event Sourcing してるならメッセージングブローカーでどうにかする
  • 孤立したそれぞれのリージョナルネットワークで発生したトランザクションを同期するのは難しそう
    • それぞれの水準でどこまで何を保証するのか設計しないといけないね

How to Test

  • かなり影響を気にしながらやっているんだなという雰囲気

全体

  • この水準の取り組みができる会社はそれなりにあると思った派と、この水準の取り組みができてるのが恐ろしいと思った派の会話
  • lottery factorトラックナンバーバスファクター より配慮されたフレーズだなと思った
    • 流行って欲しい

Scope of Tests at Google / Conclusion

  • Borg のケーススタディで言いたいこと

    • ユーザーはタスクがエビクションされないことに慣れきっている
    • それでは信頼性のあるタスクを開発できない
    • 強制的にエビクションする実験をすればどういうふうに対応したらいいか学んでくれるはずだ
  • 嫌なことを頑張る印象があったけど、前向きに取り組むような記述に感動した

Microsoft Variation and Prioritization of Experiments

  • Varying real-world events in Chaos Engineering is exactly what we’re concerned about here. の解釈
  • カオスエンジニアリングでは多様な現実世界の事象こそが,ここでの私たちの関心事です。 のほうが妥当かなと

参考: カオス原則

実世界の事象は多様である

カオス変数は実世界の事象を反映します。潜在的な影響または推定頻度のいずれかで事象の優先順位付けを行います。サーバーが落ちているようなハードウェア障害、不正な応答のようなソフトウェア障害、トラフィックやスケーリングイベントの急増など障害ではない事象に対応する事象を考えましょう。定常状態を破壊することができる事象は、カオス実験において潜在的な変数となります。

参考情報

Geb で長いページの完全なスクリーンショット画像を保存する

まとめ

背景

  • Geb には任意の時点でブラウザの表示内容を png 画像に保存できる ScreenShotReporter が付属している
  • 取得できる内容は WebDriver の実装に依存している
  • たいていの WebDriver 実装は viewport つまりウインドウに表示している部分しか取得しないようになっている
    • viewport を広げるためウインドウサイズを調整するのもいいけど根本的な対応にはならない

検討

  • WebDriver の viewport を移動してページ全体のスクリーンショットを取得できるライブラリ aShot がよさそうだった
  • Geb のレポーターとして実装すれば実現できそう

実現方法

こんな感じのレポータークラスを用意した。

package com.example
 
import geb.report.ReportState
import geb.report.ScreenshotReporter
import ru.yandex.qatools.ashot.AShot
import ru.yandex.qatools.ashot.shooting.ShootingStrategies
import ru.yandex.qatools.ashot.util.ImageTool
 
/**
 * 全画面のスクリーンショットを取得する操作を提供するレポートクラス。
 */
class WholePageScreenShotReporter extends ScreenshotReporter {
 
    def scrollTimeout = 1000
 
    @Override
    void writeReport(ReportState reportState) {
 
        def screenShot = new AShot()
            .shootingStrategy(ShootingStrategies.viewportPasting(scrollTimeout))
            .takeScreenshot(reportState.browser?.augmentedDriver);
 
        def file = super.saveScreenshotPngBytes(reportState.outputDir, reportState.label, ImageTool.toByteArray(screenShot))
        super.notifyListeners(reportState, [file])
    }
}

GebConfig.groovy では次のようにレポーターを設定する。 PageSourceReporter は Geb に同梱されているレポーターで、 html をそのまま保存する。

reporter = new CompositeReporter(
    new PageSourceReporter(),
    new WholePageScreenShotReporter(),
)

Maven の依存関係も追加しておく。

<dependency>
    <groupId>ru.yandex.qatools.ashot</groupId>
    <artifactId>ashot</artifactId>
    <version>1.5.4</version>
</dependency>

debian:stable-slim に adoptopenjdk-8-hotspot をインストールすると postinst スクリプトが失敗する

そもそもの話

AdoptOpenJDK は各種OS(ディストリビューション)向けのインストーラーを提供してる。

medium.com

DebianUbuntu のように APT を使ってるなら adoptopenjdk-8-hotspot みたいなパッケージとして導入できる。

できなかった話とできるようにした話

  • debian:stable-slim では openjdk-8-headless が無くなってたので adoptopenjdk-8-hotspot をインストールしようと試みた
  • adoptopenjdk-8-hotspotpostinst スクリプトが実行時エラーになるため、 docker image のビルドが完了できない
    • /usr/share/man/man1 が存在しないから update-alternatives に失敗するとかその程度の問題だった
  • /usr/share/man/man1 を作成すれば以降の対応はすべて不要
  • RUN 命令に指定した apt-get install の結果を無視する方法を模索
    • パイプで右辺評価させてもだめ apt-get install adoptopenjdk-8-hotspot || true
    • サブシェルで評価させてもだめ ( apt-get install adoptopenjdk-8-hotspot; echo )
  • らちが明かないので .deb ファイルを改変して対応
    • dpkg-deb を駆使するといろいろできる
    • 該当部分をごまかした postinst.sh に差し替えた .deb ファイルを作成
  • そういえば maven も必要だったけど同じように postinst スクリプトが失敗する
  • やっぱり同じように .deb ファイルを改変して対応

結果的にこういう Dockerfile になった。よくない。

たぶん sdkman を利用するのが一番早いと思います。

FROM debian:stable-slim

ENV DEBIAN_FRONTEND=noninteractive
ENV LANG="ja_JP.UTF-8"

RUN set -x \
 && apt-get update --quiet \
 && apt-get upgrade --quiet --yes \
 && apt-get autoremove --quiet --yes \
 && apt-get clean \
 && rm -rf /var/cache/* /var/tmp/* /var/lib/apt/lists/*

RUN set -x \
 && apt-get update --quiet \
 && apt-get install --quiet --no-install-recommends --no-install-suggests --yes \
    curl \
    gnupg \
    locales \
    software-properties-common \
    unzip \
    zip \
 && apt-get autoremove --quiet --yes \
 && apt-get clean \
 && rm -rf /var/cache/* /var/tmp/* /var/lib/apt/lists/*

RUN set -x \
 && sed -i -e "s/^#.*${LANG} UTF-8/${LANG} UTF-8/" /etc/locale.gen \
 && dpkg-reconfigure locales \
 && update-locale LANG="${LANG}" \

RUN set -x \
 && curl -fsSL --output /var/tmp/key https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public \
 && apt-key add /var/tmp/key \
 && add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ \
 && apt-get update --quiet \
 && apt-get install --quiet --no-install-recommends --no-install-suggests --yes \
    java-common \
    libasound2 \
    libjansi-java \
    libmaven3-core-java \
    libwagon-file-java \
    libwagon-http-shaded-java \
    libxrender1 \
    libxtst6 \
 && apt-get autoremove --quiet --yes \
 && apt-get clean \
 && rm -rf /var/cache/* /var/tmp/* /var/lib/apt/lists/*

RUN { \
        echo '#!/bin/sh'; \
        echo ''; \
        echo 'set -eu'; \
        echo ''; \
        echo 'priority=1081'; \
        echo 'jdk_base_dir=/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64'; \
        echo 'tools="appletviewer extcheck idlj jar jarsigner java javac javadoc javah javap jcmd jconsole jdb jdeps jhat jinfo jjs jmap jps jrunscript jsadebugd jstack jstat jstatd keytool native2ascii orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc jexec"'; \
        echo ''; \
        echo 'case "$1" in'; \
        echo 'configure)'; \
        echo '    for tool in $tools ; do'; \
        echo '        for tool_path in "$jdk_base_dir/bin/$tool" "$jdk_base_dir/lib/$tool" ; do'; \
        echo '            if [ ! -e "$tool_path" ]; then'; \
        echo '                continue'; \
        echo '            fi'; \
        echo ''; \
        echo '            slave=""'; \
        echo '            tool_man_path="$jdk_base_dir/man/man1/$tool.1"'; \
        echo '            if [ -e "$tool_man_path" ]; then'; \
        echo '                mkdir -p /usr/share/man/man1'; \
        echo '                slave="--slave /usr/share/man/man1/$tool.1 $tool.1 $tool_man_path"'; \
        echo '            fi'; \
        echo ''; \
        echo '            update-alternatives \\'; \
        echo '                --install \\'; \
        echo '                "/usr/bin/$tool" \\'; \
        echo '                "$tool" \\'; \
        echo '                "$tool_path" \\'; \
        echo '                "$priority" \\'; \
        echo '                $slave'; \
        echo '        done'; \
        echo '    done'; \
        echo ';;'; \
        echo 'esac'; \
    } > /var/tmp/adoptopenjdk-8-hotspot.postinst

RUN set -x \
 && cd /var/tmp \
 && apt-get update --quiet \
 && apt-get download adoptopenjdk-8-hotspot \
 && mkdir src \
 && dpkg-deb -R adoptopenjdk-8-hotspot*.deb src \
 && mv /var/tmp/adoptopenjdk-8-hotspot.postinst src/DEBIAN/postinst \
 && chmod 755 src/DEBIAN/postinst \
 && dpkg-deb -b src new.deb \
 && dpkg --install new.deb \
 && cd / \
 && apt-get autoremove --quiet --yes \
 && apt-get clean \
 && rm -rf /var/cache/* /var/tmp/* /var/lib/apt/lists/*

RUN { \
        echo '#!/bin/sh'; \
        echo ''; \
        echo 'set -e'; \
        echo ''; \
        echo 'basedir=/usr/share/maven'; \
        echo 'priority=300'; \
        echo ''; \
        echo 'case "$1" in'; \
        echo 'configure)'; \
        echo ''; \
        echo '    update-alternatives \\'; \
        echo '    --install /usr/bin/mvn mvn $basedir/bin/mvn $priority \\'; \
        echo '    --slave \\'; \
        echo '        /usr/bin/mvnDebug \\'; \
        echo '        mvnDebug \\'; \
        echo '        $basedir/bin/mvnDebug \\'; \
        echo '    ;;'; \
        echo 'esac'; \
        echo ''; \
        echo 'exit 0'; \
    } > /var/tmp/maven.postinst

RUN set -x \
 && cd /var/tmp \
 && apt-get update --quiet \
 && apt-get download maven \
 && mkdir src \
 && dpkg-deb -R maven*.deb src \
 && mv /var/tmp/maven.postinst src/DEBIAN/postinst \
 && chmod 755 src/DEBIAN/postinst \
 && dpkg-deb -b src new.deb \
 && dpkg --install new.deb \
 && cd / \
 && apt-get autoremove --quiet --yes \
 && apt-get clean \
 && rm -rf /var/cache/* /var/tmp/* /var/lib/apt/lists/*

RUN java -version \
 && mvn -version

ENTRYPOINT ["mvn"]
CMD ["test"]

オンラインリソース

第2回 Chaos Engineering 読書会@リモートのログ

javaee-study.connpass.com

前回から引き続き Discord によるオンライン開催。

対象の本はこれです。

learning.oreilly.com

こんな感じで進めてます。

  • 当日まで
    • 分担を決めた部分を要約してくる(立候補制)
      • 最終的に内容が理解できるなら形式は自由です
      • 非公開の Dropbox Paper で共有してます
  • 当日
    1. 自己紹介
      • 好きなものとか最近の興味とかそういう
    2. 要約した人が読む!(文字通り読み上げてる)
    3. 原文の意図であろうと、要約した結果であろうと、意味のわからないところにつっこみを入れ、納得できる落としどころを探る
    4. 次の章に進む(2に戻る)

次回は 2020-06-20 の 13 時から始まる予定です。

javaee-study.connpass.com

イントロダクション

読んだ範囲

  • 3.2 から 4.3 まで

議論

3.2 What Chaos Engineering Is Not

3.3 Advanced Principles

  • 本番環境で実験しよう

    • カオスエンジニアリングのスコーピングの話のような気もする
  • 実験で見つけた問題の重要度の評価はとても難しい

    • DR のコスト試算とか難しい
    • 経営陣を説得するのは大変なんやで
  • after コロナで破滅したトレンド予測に対して、カオスエンジニアリングの存在感が増している可能性

3.4 The Future of “The Principles”

Part II. Principles in Action(行動原則)

4. Slack’s Disasterpiece Theater (Slackのディザスタピースシアター)

4.1 Retrofitting Chaos (カオスを組み込む)

4.2 Disasterpiece Theater

  • 回帰テストっぽい
  • Goal と Anti Goal の捉え方 (参加者の意見、面白い考え方だなと思った)
    • カオス原則に則ってるのは Goal で、そうでないのは Anti Goal にしてるのかな

4.3 Process

  • もはや避難訓練そのもの
  • 負担を考えると毎週やると死ねる

    • 開発者はズルし始める(出張したり休んだり)
  • ユーザーへの影響を最小化する、という考え方ではなく、どこで障害を発生させるのか、から考え始めてる様子に違和感があった

  • なんで開発環境、本番環境の順に実験するのか

    • 開発環境と本番環境は別の環境だから
    • 片方で発生したものがもう片方で発生するとは限らない
    • リハーサル的な。
    • つまるところ規模の違いが要因になってるような気もする

参加者それぞれが環境の違いによる問題の発生体験を開陳。引きそうな内容もちらほら。

オンライン読書会 Tips

  • 休みどころがつかみにくい
    • 1時間以上続くやりとりでは、意識して休憩時間を設けないとたぶん消耗する
  • Krisp の無効化
    • 最近 Discord の音声入力設定でノイズキャンセリングのための Krisp が使えるようになったけど、有効にすると音声がプツプツと途切れがちになる
    • たぶん話し手が意識すればいいんだけど、それはそれで面倒なので無効化しておく
  • Discord アプリの音声入力設定
    • いろいろ自動調整を無効化しておくとよい(音量自動調整を無効化しておくと発話の最後が切れにくくなるとか)
  • リアクション問題
    • Discord の Live 配信にはリアクションを送れないのでチャットのほうであれこれ書くことになる
    • たぶん Discord はそういう文化なので利用する側が最適化したほうがいいんだと思う