はじめに
今回の記事は、Ruby3.2でLambdaを使用しようとしたときに、「/var/lang/bin/ruby: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory」というエラーが出たので、なんとか解消できたときのお話です。もしかしたらRubyでもこちら(Pythonです)のように、出来上がったレイヤーを配布しているかもしれませんので、お時間ある方は探してみてください。
なぜエラーがでたのか?
Lambdaでは最近Rubyの3.2のランタイムが提供されるようになりました。しかし、Rubyのランタイムが依存しているLinux依存のライブラリまでは網羅されていないため、見つけることができずタイトルにあるエラーが出てしまいました。
どのように解消したのか?
別の環境でライブラリをLambdaのレイヤーとして作成して追加しました。ただし、それなりに手間がかかったので、順に説明します。
1. DockerでAmazonLinux2のコンテナイメージをpullする。
現在(2023年7月30日時点)ではLambdaのOSはAmazonLinux2のOSがベースになっているようでしたので、このコンテナを選びました。
docker pull amazonlinux:2
2. ローカル環境のディレクトリをマウントしてコンテナを起動する。
pwd
というコマンドで自分が今どこにいるのか(作業中のディレクトリ)を絶対参照で知ることができるかと思いますが、今回はそれを使って、カレントディレクトリのフルパスを取得してマウントします。そうしないと後々コンテナ内での作業の成果物を取得できないのです。。。
docker run -v "$PWD":/var/task -it amazonlinux:2 bash
3. コンテナ内で作業するのに必要なコマンドをインストールする。
とはいえ、.zipにしてレイヤーに追加するだけなので、実際にはzipだけです!!!
yum install -y zip
4. libcrypt.so.1を探す
4-1. find
コマンドでファイル名を指定して探しましょう。
find / -name "libcrypt.so.1"
本体ではない可能性があるので一旦ls
してみましょう
bash-4.2# ls -l /usr/lib64/libcrypt.so.1
lrwxrwxrwx 1 root root 16 Jun 28 19:09 /usr/lib64/libcrypt.so.1 -> libcrypt-2.26.so
こういうことですね!!!
シンボリックリンクというものでした。
4-2. 本体側(今回はlibcrypt-2.26.so)がどこにあるのか探しましょう。
find / -name "libcrypt-2.26.so"
5. 必要なライブラリをひとまとめにする。
ここでLambdaのレイヤーに配置することを想定して、zip形式にします。Lambdaのレイヤー配置はzip形式でアップロードする必要があります!また、今回はシンボリックリンクもzipに入れるので、cpコマンドのオプションに注意してください。
cd /var/task
mkdir lib
cp -pa /usr/lib64/libcrypt* ./lib/
zip libcrypt.zip ./lib/*
6. 出来上がったzipファイルを取得する。
カレントディレクトリにruby-layer.zipというファイルが出来上がっていることと思います。これをAWSのLambdaへ配置すれば完了です!!!
7. Lambdaのレイヤーに追加する。
これらはAWSのデベロッパーガイドに従って行ってください。
7-1. レイヤーを作成する。
7-2. Lambdaにレイヤーを紐付ける。
以上で完了です!おつかれさまでした!!!
まとめ
今回遭遇したエラーは実はここまですんなりと解決できておらず、数日かかっています。その試行錯誤した結果をhistoryコマンドで遡ってまとめました。こちらの記事では一度で済ませられるようにまとめてありますが、正直かなりしんどかったです。ただ、頭の中にたくさんインデックスを貼ることができたので、学習だと思えば良い経験ができたと思います。
ここまで読んで頂きありがとうございました。
ではでは、今回はこの辺で👋