AWS Lambda に deploy した lxml が動かなくなったお話
発端
2023年11月上旬頃にアプリを修正してDeployしてエラー通知が届く
Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
これは BeautifulSoup の parser で推奨されてる、lxml が使えない(もしくはインストールされていない) 場合に出るログである。
調査
今回のアプリは serverless framework を利用し、github actions を利用して deploy したものである。
github actions 上で生成した deploy package で再現するか確認
パッケージに含まれるライブラリの更新により、時々 serverless deploy
時にエラーが出てこともあり、github actionsのstepに、 serverless package
が成功するか否か確認していた。
今回、そちらの成果物 (.serverless/) を artifact に保存するように修正、実行
- name: test for build package
run: |
npx serverless package --verbose --stage dev
# ↓ を追加
# deploy package の保存
- name: Archive deploy package results
uses: actions/upload-artifact@v3
with:
name: deploy-package
path: ./.serverless/**
実行後正常に成果物がuploadされていることを確認
こちらを手元にdownloadし、中身を確認。
$ mkdir -p /tmp/dist
$ cd /tmp/dist
$ unzip /path/to/deploy-package.zip
$ ls -l
total 30424
-rw-r--r--@ 1 tututen wheel 169934 11 14 09:59 app.zip
-rw-r--r--@ 1 tututen wheel 2077 11 14 09:59 cloudformation-template-create-stack.json
-rw-r--r--@ 1 tututen wheel 308269 11 14 09:59 cloudformation-template-update-stack.json
-rw-r--r--@ 1 tututen wheel 14622486 11 14 09:59 pythonRequirements.zip
drwxr-xr-x@ 64 tututen wheel 2048 11 14 09:59 requirements
-rw-r--r--@ 1 tututen wheel 2289 11 14 10:01 requirements.txt
-rw-r--r--@ 1 tututen wheel 459051 11 14 10:01 serverless-state.json
serverless-python-requirements
の custom.pythonRequirements.layer: true
に設定しているので、 pythonRequirements.zip の中身を見ていく。
$ mkdir dist
$ cd dist
$ unzip ../pythonRequirements.zip
$ tree .
.
└── python
├── beautifulsoup4-4.12.2.dist-info
├── bs4
(.. snip ..)
├── lxml
├── lxml-4.9.3.dist-info
(.. snip ..)
AWSの用意しているDockerimage、 public.ecr.aws/sam/build-python3.9:latest-x86_64 を利用して、main.pyを実行して再現するか確認してみる
from bs4 import BeautifulSoup
BeautifulSoup("<p>Hello world!</p>", "lxml")
$ docker run --rm -v .:/var/task public.ecr.aws/sam/build-python3.9:latest-x86_64 python main.py
Traceback (most recent call last):
File "/var/task/main.py", line 2, in <module>
BeautifulSoup("<p>Hello world!</p>", "lxml")
File "/var/task/bs4/__init__.py", line 250, in __init__
raise FeatureNotFound(
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
再現しました
BeautifulSoup の bs4.builder._lxml が読み込めるか
$ docker run --rm -v .:/var/task public.ecr.aws/sam/build-python3.9:latest-x86_64 python -c "from bs4.builder import _lxml"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/var/task/bs4/builder/_lxml.py", line 16, in <module>
from lxml import etree
ImportError: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /var/task/lxml/etree.cpython-39-x86_64-linux-gnu.so)
読み込めませんでした。
ImportError: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /var/task/lxml/etree.cpython-39-x86_64-linux-gnu.so)
GLIBC 2.28が見つからない、とのことなので、runner側でのglibcの互換性が更新されたのかなーという推測ができます。
glibc の version を見てみる
public.ecr.aws/sam/build-python3.9:latest-x86_64 内は 2.26
$ docker run --rm -v .:/var/task public.ecr.aws/sam/build-python3.9:latest-x86_64 /lib64/libc.so.6
GNU C Library (GNU libc) stable release version 2.26, by Roland McGrath et al.
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 7.3.1 20180712 (Red Hat 7.3.1-17).
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
runner(github actions の runner: ubuntu-20.04) は 2.31
- name: debug
run: |
/lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.12) stable release version 2.31.
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 9.4.0.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
まとめ
今回は runner の glibc の更新により、AWS Lambda上で lxml が動かなくなったという結論になりました。
github actions の runnerの更新は結構頻繁に行われいるので、安全に lxml を deploy するのであれば、 public.ecr.aws/sam/build-python を利用して build し、 deployするのがよい。 ただ、2023年11月時点では、 lxml を github actions を利用して、deploy する場合、20分以上のビルド時間を許容できるかどうか考える必要があります。
今回、速度を求めないのであれば、デフォルトの html.parser
を指定してしまうのも一つの手だと思います。
BeautifulSoup("<p>Hello world!</p>", "html.parser")
Discussion