著者: 吉町優, 株式会社日立製作所
はじめに
普段の業務ではOSSとコンテナ技術を積極的に活用し、製品/サービスの開発速度向上に役立てています。
OSSの活用は当たり前となりましたが、製品/サービスの素材としてOSSを使うには多くの課題があります。
今回はOSS利用する上でのリスクと対策、そして流行のコンテナ開発におけるOSS観点について紹介します。
OSS利用の問題点
OSSを活用した製品/サービス開発には多くの課題があります。
例えば、以下のようなOSS利用のリスクがあります。
- 社内環境(ネットワークプロキシなど)の制約
- コピーレフトライセンス(GPLなど)の伝播の考慮
- OSSパッケージの保管/管理方法
実際に製品/サービス開発する際に考えられるリスクを紹介します。
製品/サービス開発におけるOSS利用のリスク
社内ネットワークの制約
yum, pipなどのOSSパッケージはオンラインリポジトリサーバからインストールするため、社内環境ではプロキシの影響を受けることがあります。
インストールの過程で認証が必要になることや、コンテナ内にログが残ることがあります。
パッケージの再入手性
OSSの特性上バージョンアップが早く、過去に入手したバージョンの配布パッケージが再入手できなくなることがあります。
環境の再現性の低下
OSSパッケージの再入手不可、オンラインリポジトリ依存 というのは将来的に同一環境のソフトウェア/システムを構築できないリスクに繋がります。
これらのリスクを回避するために、製品/サービスの素材としてOSSを採用する場合は社内ローカル環境で完結して成果物を構築できることが必要です。
コンテナにおけるリスク
コンテナ再ビルド時の構成の変化
マイクロサービス化の流れに合わせてコンテナを用いた製品/サービス開発も増えてきています。
個人利用ではDocker Hubなどの構築済みコンテナイメージを使うことも多いかと思います。
Docker Hubなどの構築済みコンテナイメージではコンテナのビルドでapkやrpmなどのパッケージ(依存を含む)はオンラインリポジトリからインストールされるものが多いです。
構築済みコンテナイメージを利用・運用する中で、セキュリティパッチなどの任意の修正が必要になった際、時の経過により同梱OSSの取得バージョンの変化やOSSパッケージ自体の取得が不可能になることがあります。
ベースコンテナの同梱OSSが不明瞭
構築済みイメージをそのまま使わずとも、ベースコンテナにDocker Hubなどの構築済みイメージを使っている場合は同様の構成変化のリスクがあります。
製品/サービスでは仕様維持のために導入済みのコンテナのOSSを変更できないことがあるので、同一環境を再現できないことは大きなリスクです。
OSSライセンスのリスク
OSSのライセンスはMITライセンスやApacheライセンスのように多くのライセンス種があり、この中でコピーレフトライセンスと呼ばれるGPLがあります。
ここでGPLについて深くは触れませんが、OSSの取り込み方によって独自開発部分のソース開示が必要になります。
このため、コンテナにGPLが含まれる場合GPL汚染が発生するリスクがあります。
このように不明瞭にOSSを利用することにはリスクがあり、コンテナに同梱するOSSを管理する必要があります。
開発でOSSを活用するために達成したいこと
このようにOSSに課題は多いですが、メリットも多いため積極的に使っていきたいものです。
流行のコンテナを製品/サービス開発をするためにやりたことは以下です。
- 社内ネットワーク(Proxyなど)の制約を回避したい
- 社内ローカル環境でコンテナビルドが完結できる
- アップデート/脆弱性 対応ができるようにしたい
- コンテナ内の同梱OSSを単体で入れ替えができる
- コピーレフトライセンスのライセンス伝播リスクを回避したい
- 同梱OSSが不明瞭なコンテナは使わない
これらを達成するためにプライベートリポジトリを作成することしました。
プライベートリポジトリの構築
docker-composeによる構築例
プライベートリポジトリの構築にdocker-compose
を採用しました。
プライベートリポジトリを使うことで、製品/サービスで使うOSSを明確に管理できます。
管理したいパッケージ種は多くあり、以下のように必要なリポジトリを追加すると使いやすいです。
プライベートリポジトリの構築例
リポジトリ | ポート番号 | 構成OSS |
---|---|---|
FileServer | 10001 | nginx |
yum | 10002 | nginx |
apt | 10003 | debian-repository |
apk | 10004 | nginx |
pypi | 10005 | pypi-server |
Dockerレジストリ | 80 | Nexus Repository Manager 3 |
OSSパッケージを管理しやすい
OSSパッケージ種単位でリポジトリサービスのコンテナをデプロイでき、ポートフォワード機能による受信ポートの変換も可能です。
Development
, Staging
, Production
毎にリポジトリを分け、誤ったOSSの混入を防ぐ仕組みも実現可能です。
コンテナイメージ管理
パッケージとしてのコンテナイメージの永続管理
製品/サービスをコンテナで開発する場合、コンテナイメージがソフトウェアパッケージであり保守管理対象になります。
社内のローカル環境で完結してコンテナイメージを再ビルドできることは大切ですが、一度ビルドしたイメージを保管する仕組みも必要です。
コンテナを再生成する場合はコンテナイメージのラベルの変化やベースイメージの変化の影響を受けるため、将来にわたり同一のコンテナを再生成できる保証はありません。
コンテナイメージのハッシュ値からイメージの変化を検知するためにも、製品/サービスのリリース版のコンテナイメージの管理が必要です。
コンテナイメージの保護
コンテナイメージを開発/管理する際、Dockerレジストリをプライベートで運用し作成したコンテナイメージをpushやpullすることになります。
しかし開発中に誤って同一タグのコンテナイメージをpushすると上書きされてしまいます。
このため製品/サービスのリリースバージョンのコンテナイメージを書き込みできないように保護することが好ましいです。
コンテナイメージの保護の構成例
Nexus Repository Manager 3にはDockerレジストリ機能があり、hosted
, proxy
, group
の考えがあります。
複数のDockerレジストリを構築可能で、複数のレジストリを纏めたgroupレジストリを作ることができます。
Dockerレジストリに格納されている過去リリース分のコンテナイメージをpullして使うことはありますが、pushでイメージ更新することはありません。
開発中に新たなコンテナイメージをレジストリにpushしますが、誤ってコンテナを上書きしてしまうリスクがありました。
そこで、group内のDockerレジストリを開発向けpush用の書き込み可能なDockerレジストリ
と過去リリースイメージpull用の読み込み専用なDockerレジストリ
に分けます。
さらにリバースプロキシサーバをDockerレジストリ向けの通信の間に配置し、HTTP Methodを条件にpull
とpush
のリクエストを適切なDockerレジストリに分類します。
これにより、Dockerクライアント側でレジストリ構成を意識せずイメージが保護されたDockerレジストリを使うことができます。
まとめ
OSSのライセンス、パッケージの管理方法、コンテナ開発のノウハウを紹介しました。
OSSは個人では手軽に使えますが、企業として製品/サービスにOSSを取り込む場合は正しくリスクを認識し、対策が必要です。
企業の業務活動においてOSS特性を理解した上で活用し、OSSコミュニティを盛り上げていきましょう。