- 真野隼記
- 約 2,900 文字
- 800 View
目次
はじめに
TIG 真野です。
2023年3月31日にリリースされたLocalStack v2.0.0から、LocalStackのイメージ構成に変更が入りました。利用する環境によってはKinesis Data Streamsなど一部のサービスを利用するときにカスタムCA証明書をダウンロードする必要がありました(後述する通り、Kinesis Data Streamsに関しては現在のバージョンでは対応不要ですので安心ください)。
この記事では、DockerのマルチステージビルドでOpenSSLを使って証明書をダウンロードして、LocalStackのカスタムイメージを作成する流れをまとめます。
#8782のIssueを見つけて対応を考えている人や、installation of kinesis-mock failedといったエラーログが出ていて困っている場合、おそらくこの記事が参考になります。
ただし、少なくてもKinesis Data Streamsに関しては、v2.3.0 からアップデートが入り本記事の対応が不要になりました。LocalStackのその他サービスでハマった場合にこの記事を確認いただくと良いかなと思います。エラーログでこの記事を見つけた方は、LocalStackのバージョンを上げることで解決することもあるようですので、まずバージョンアップを試してみることを推奨します。
背景
LocalStackは様々なAWSサービスをローカルやCI環境で再現してくれるエミュレータです。こういったサービスの難しいポイントの1つは、AWSのサービスや機能はどんどん増え豊富になっていくため、追随するためにはイメージサイズが肥大化しいくことでしょう。
そのため、v2.0.0からは起動時に一度だけ外部からサービスが必要とするパッケージ読み込みキャッシュ。それにより、開発者の利用しないサービスが依存するパッケージは元のイメージから取り除き、容量削減を狙う方式になりました。
少しばかり複雑な手順を踏んでいる気がしますが、イメージサイズと利用勝手のバランスを取った賢いやり方に思えます。CIで利用するユーザにとってはイメージのpull時間の節約、しいては費用削減となるため嬉しい施策出ると思います。
一方でこれにより、DynammoDBなどでは色々と問題が多かったらしく、利用頻度が高いサービス(Issueではトップ15と書かれていますが今のところは数種類)が再びプリインストールする方向にするよという話も出ていました。
v3.1.0では、Dockerfileを見る限り、DynamoDBとLambdaはプリインストール方式に戻っていました(DynamoDBは(多分)DynamoDB LocalのJAR増加で、47MB程度イメージサイズが増えたようです)。
# Install packages which should be shipped by default |
Kinesis Data StreamsなどもDynamoDBと同じようにプリインストールできないかという要望も#8300で上げられましたが、やはりイメージサイズとのバランス問題で棄却されています。何かしらプリインストールしないと困るユースケースが無いと追加はされないような雰囲気があります。
Installation of kinesis-mock failed
LocalStackでKinesis Data Streamsのストリームを作成しようとした場合に、Installation of kinesis-mock failed というエラーが出るケースについて話します。ログ内容としては次のようなものです。
localstack-1 | SERVICES variable is ignored if EAGER_SERVICE_LOADING=0. |
公式ドキュメントCustom TLS certificatesにも触れられています。非標準の TLS 証明書を使用するプロキシサーバーを利用する場合に発生するようです。原因はプロキシ、慣れたものです。
ドキュメントにDockerfileを拡張して証明書をインストールする手順があり、Installation of kinesis-mock failed in LocalStackの記事では、https://api.github.comのCA 証明書にアクセスして取得する例が書かれています。
しかし、チームメンバー全員にこの手順を行ってもらうのは手間ですし、証明書をGit管理にもしたくないでしょう。ファイルサーバやGoogle Driveのようなコラボレーションツール上にも、こういった手順は廃れがちであるため、あまり配備したくない場合が多いでしょう。
Dockerfile上で対応する
サーバからTLS証明書をダウンロードするために、OpenSSLを利用します。
Get SSL Certificate from Server (Site URL) – Export & Download という記事が参考になります。
さきほどの https://api.github.com から証明書を取得するのであれば次のようなコマンドです。
echo | openssl s_client -servername api.github.com -connect api.github.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > custom-ca.cer |
取得した custom-ca.cer を公式ドキュメント通り、 CURL_CA_BUNDLE、 REQUESTS_CA_BUNDLE、NODE_EXTRA_CA_CERTS の環境変数にセットしたイメージを作れば対応完了です。
Dockerfileのマルチステージビルドを利用すると次のようになると思います。
FROM alpine/openssl:3.1.3 AS build |
docker-compose経由で起動したいので、次のようなYAMLファイルを準備します。
version: "3.8" |
docker-compose up localstack などで起動すると、Kinesis Data Streamsのリソース作成ができるようになっていると思います。3つのほどストリームを作成してみたときのログです。
localstack-1 | |
動的にパッケージを取得し、Kinesisのストリームが上手く作成されていることが分かります。
LocalStack側でアップデートが入ったのか、Kinesis Data Streamsに対しては対応が不要になったようです
この記事を書くにあたり、元のエラーログを発生させようとしていて気がついたのですが、v2.3.0 でアップデートが入ったようで、Kinesis Data Streamsについては対応が不要です。
v2.0.2→✘ エラー発生v2.1.0→✘v2.2.0→✘v2.3.0→✅ 正常動作v3.0.0→✅v3.1.0→✅
おそらく、Kinesisのモックをバイナリからscala.js版に入れ替えた Use scala.js for executable and docker image #531 で解消されたのかなと予測しますが、詳細は未調査です。
まとめ
LocalStack v2からイメージの構成が変わって、起動時に動的にパッケージをインストールするケースがあります。その場合にネットワーク環境によっては外部リソースの取得に失敗するため、CA証明書の設定が必要。OpenSSLで自動化すると楽になるかもしれない、という記事でした。
みんなハマっていないのかな? と思っていましたが、NGだった期間は v2.0.0 が公開されたときから、v2.3.0 が公開された 2023.3.31 ~ 2023.9.29 と半年足らずだったので、レアな経験だったのかもしれません。