以下は共有ライブラリに虐げられ共有ライブラリをもう使いたくないという個人的な愚痴をまとめたものです。特にことわらない場合は Linux の話です。
何故共有ライブラリを使うのか?
前回説明したように共有ライブラリをリンクした実行ファイルは必要な共有ライブラリを実行時にシステムから検索してロードします。この際ライブラリを検索する方法は名前です。先に見つけたものを使います。しかもこの検索パスは環境変数 LD_LIBRARY_PATH
によって変更できます。また検索する順序に当然依存します。
この機構は何のために存在するのでしょう?いくつかの目的があげられます。
ディスク容量を節約する
複数の実行バイナリで同じ関数のバイナリを持たなくていいので単純にディスク容量を節約できます。これは現代のように十分大容量なディスクが安価で利用できる時代には特に問題になりません。
共有ライブラリを更新すればそれを利用している全ての実行ファイルで更新したものを利用できる
例えば利用しているライブラリに脆弱性が見つかったとしましょう。そのライブラリを使用している実行ファイルには全てその脆弱性がある事になります。急いで全ての実行ファイルを更新しなければなりません。この時共有ライブラリの形で提供してあれば、その共有ライブラリを更新すれば全ての実行ファイルを再ビルドせずに済みます。これは使うライブラリが増えれば増えるほど組み合わせ論的に増えます。もし静的にリンクしていたら使っているライブラリが更新される度にビルドをする必要があるでしょう。これはシステムを提供する立場では看過出来ません。
何故共有ライブラリは辛いのか?
はい、共有ライブラリは大事ですね。どうしてこんな記事を書いたのでしょうか?
アプリケーションを書いているときに、あるライブラリを使おうとしたとしましょう。ライブラリを使うのはとても良いことです、多くの処理は既に誰かが上手く解決してライブラリとして提供してくれています。ではこのライブラリを静的にリンクするべきでしょうか?動的にリンクするべきでしょうか?
静的にリンクすることの利点は、そのライブラリをビルド時の状態で固定出きることであり、動的なリンクの利点は実行時にこのライブラリを入れ替えることによって状態を固定しない事です。
動的にシステムからライブラリを取得する事は上に述べたように問題が発生した場合に簡単に置換出来る事が出来る一方、アプリケーションは勝手に共有ライブラリがすげ替えられてもちゃんと動作し続けないといけないことになります。しかも共有ライブラリはアプリケーションの実行バイナリ本体に含まれていないため、正しくシステムにライブラリがインストールされていないとアプリケーションが動きません。こうなるとアプリケーション開発者が実行環境を制御したいと思うことは自然な事でしょう。アプリケーションを安定して動作させる環境を用意しようと考える事でしょう。そうだ実行環境をコンテナで配布すればいいんだ!
はい、コンテナ内の共有ライブラリはシステムから置き換えれませんね。
https://www.slideshare.net/Docker/dockercon-eu-day-1-general-session
何を間違えたのでしょう?対立しているのは次の2点ですね
- 共有ライブラリを変更する事で問題に対処できる
- アプリケーションを安定に動作させるために共有ライブラリを更新して欲しくない
共有ライブラリを置き換える事で実現しようとしたセキュリティは上の図でコンロに鍵をかけているのと等しく、コンテナ技術の発達によって共有ライブラリを更新することで脆弱性に対応できる、というのは全く現実的でなくなってしまいました。もうこうなってしまうとわざわざ実行時に共有ライブラリを探す理由がありません。探すまでもなくコンテナで固定されてしまっているのですから。