Red Hatでコンサルタントをしている @mamomamo です。この記事は、赤帽エンジニア Advent Calendar 2018 の15日目です。
はじめに
2018/12/3に Kubernetes 1.13 がリリースされました。このニュースリリースにおいて、"Container Storage Interface (CSI) Goes GA" という項目があり、v1.9からベータ版が採用された CSI(Container Storage Interface) がv1.13から正式版になったと発表されています。
CSI(Container Storage Interface)は、Kubernetesなどのコンテナオーケストレーションツールとストレージとの間のインターフェースの標準仕様ですが、他にもコンテナ関連にはいくつかの標準仕様が存在しています。本記事では、いくつかの代表的なコンテナ関連の標準仕様について、その概要を調査した内容を書いてみたいと考えています。
OCI(Open Container Initiative)とは
Open Container Initiative(OCI)とは、コンテナのランタイムとイメージ関連のオープンな業界標準を作成するため、2015年6月にDocker社などの複数の企業により設立された、現在はLinux Foundation傘下のオープンソース団体です。
2018年12月時点のメンバは以下の通りで、Red Hatをはじめほとんどの大手テクノロジー企業が参加しています。
※引用: https://www.opencontainers.org/about/members
2017年7月に「OCI v1.0」が策定され、コンテナランタイムの標準仕様である「Runtime Specification」と、コンテナイメージの標準仕様である「Image Format Specification」がリリースされています。
また、2018年4月にはコンテナイメージ配布の標準仕様を策定する、「Distribution Specification」プロジェクトへの着手が発表されています。
※参考: https://www.opencontainers.org/blog/2018/04/09/distribution-spec-is-here
OCI Runtime Specification
コンテナランタイムの標準仕様であり、現在の主要なコンテナランタイムが全て準拠しており、広く普及した標準仕様となっています。また、Linuxコンテナの標準仕様だけでなく、Solaris・Windows・Virtual Machine上のコンテナランタイムの仕様についても決められています。
詳細な仕様はGitHubのSpecificationのページを確認してもらった方が確実ですが、Linuxコンテナの場合には Default Filesystem・Namespace・cgropus などの仕様が決められています。
OCI Image Format Specification
OCI Runtime Specificationと同じタイミングの2017年7月に策定され、こちらも広く普及しているコンテナイメージの標準仕様です。Image Manifest・Image Index・Image Layout・Filesystem Layout・Image Configuration などの仕様が決められています。
OCI Distribution Specification
前述の通り2018年4月に着手開始が発表されたコンテナイメージ配布の標準仕様ですが、OCIのニュースリリースやGitHubのコミット履歴を見る限り、本記事の執筆時点(2018年12月中旬)では仕様の策定が止まっているように見えます。
CRI(Container Runtime Interface)とは
CRI(Container Runtime Interface)とは、2016年12月にKubernetes 1.5からαリリースされた、kubeletとコンテナランタイムが通信するためのインターフェースを規定したものです。
CRIの概要は以下の図の通りです。
※引用: https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/
CRIが規定される以前は、コンテナランタイム側がkubeletの内部構造を理解しなければならず、新しいコンテナランタイムをKubernetesに組み込むことは非常に障壁の高いことでした。しかし、CRIが規定されることにより、KubernetesはDocker以外のコンテナランタイムを組み込み易くなっています。
このため、Red Hatが提供する OpenShift Container Platform では、Dockerよりも軽量なコンテナランタイムである、CRI-O をv4.0からデフォルトのコンテナランタイムに採用する予定です。
CSI(Container Storage Interface)とは
CSI(Container Storage Interface)とは、Kubernetesなどのコンテナオーケストレーションツールとストレージとの間のインターフェースの標準仕様であり、2018年11月にv1.0に到達しました。
CSIの策定が開始される以前には、外部ストレージを開発するベンダーがコンテナオーケストレーションツール側の内部構造を理解していなければならず、機能追加や修正を行う場合にはコンテナオーケストレーションツール側に手を入れる必要がありました。
これに対応するため、コンテナオーケストレーションツールとストレージのインターフェースの間の標準仕様を策定することにより、コンテナオーケストレーションツール側に依存せず、独立にストレージ側の機能追加や修正を行えることを目指しています。
CSIのアーキテクチャは以下の通りです。
※引用: https://medium.com/google-cloud/understanding-the-container-storage-interface-csi-ddbeb966a3b
CSIでは、Kubernetes(コンテナオーケストレーションツール)側が、以下の3つのサイドカーコンテナを提供することになっています。
- external-attacher: VolumeAttachmentオブジェクトを監視し、CSIエンドポイントに対してボリュームをノードにアタッチする命令を行います
- external-provisoner: PersistentVolumeClaimオブジェクトを監視し、CSIエンドポイントに対してボリューム作成や削除の命令を行います
- driver-register: CSI driverをkubeletに登録します
また、ストレージベンダー側は、以下の3つのサービスを実装する必要があります。
- Identity Service: コンテナオーケストレーションツールがプラグインに対してCapability/Health/その他メタデータなどを問い合わせるために実装します。
- Controller Service: ボリュームやスナップショットの作成・削除・一覧表示を行う機能を実装します。
- Node Service: コンテナオーケストレーションツール側からボリュームをマウントする際に呼び出される機能を実装します。
CNI(Container Network Interface)とは
CNI(Container Network Interface)とは、CNCF(Cloud Native Computing Foundation)にホストされたプロジェクトの一つであり、コンテナがネットワークに接続するインターフェースの標準仕様とリファレンスプラグインを提供しています。
CNIは、コンテナが作成された際のネットワークの接続性の確保とコンテナが解放された際のリソースの解放を行っており、KubernetesやOpenShift Container Platformなどの様々なコンテナオーケストレーションツールで採用されており、デファクトになりつつあると考えられます。
※参考: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni
※参考: https://docs.openshift.com/container-platform/3.11/architecture/networking/network_plugins.html
また、2018年12月時点ではバージョンが1.0に到達しておらず、今後も仕様変更があると考えられます。
CNIの基本的な動作原理は以下の図の通りです。
JSONフォーマットのネットワーク設定が標準入力として、 CNIの設定が環境変数としてプラグインへ渡され、ブラグインが渡された情報に基づいて命令を実行します。
※引用: https://www.slideshare.net/weaveworks/introduction-to-the-container-network-interface-cni
CNIの標準仕様では、以下の4つがサポートすべきオペレーションとして決められています。
- ADD: コンテナをネットワークへ追加
- DEL: コンテナをネットワークから削除
- CHECK: コンテナのネットワークが期待したものかチェック
- VERSION: バージョンの確認
また、コンテナランタイムからブラグインへ渡されるネットワーク設定には、以下の内容を設定することができます。
- cniVersion (string): CNI Specificationのバージョン
- name (string): ネットワーク名
- type (string): 実行するネットワークプラグインのファイル名
- args (dictionary, optional): コンテナランタイムより与えられる追加情報
- ipMasq (boolean, optional): IPマスカレードの設定
- ipam (dictionary, optional): IPAM設定のための情報
- type (string): 実行するIPAMプラグインのファイル名
- dns (dictionary, optional): DNS設定のための情報
- nameservers (list of strings, optional): DNSネームサーバのリスト
- domain (string, optional): ローカルドメインの指定
- search (list of strings, optional): サーチドメインのリスト
- options (list of strings, optional): リゾルバに渡すオプションのリスト
さいごに
本記事では、コンテナの標準仕様について調査した結果を書いてみました。
全ての標準仕様について調査できたと思っていませんし、GitHubのSpecificationの内容をただ和訳するだけでは面白くないと考えたため、調査した4つの標準仕様について概要をまとめるに留めています。
もっと詳しい仕様を知りたい方は、以下の参考情報にそれぞれのリンクを貼っておきましたので、お時間のある時などにご確認ください。
参考情報
- Kubernetes 1.13: Simplified Cluster Management with Kubeadm, Container Storage Interface (CSI), and CoreDNS as Default DNS are Now Generally Available
- Open Container Initiative
- Open Container Initiative Runtime Specification
- Image Format Specification
- Open Container Initiative Distribution Specification
- Introducing Container Runtime Interface (CRI) in Kubernetes
- Container Storage Interface (CSI)
- Container Network Interface Specification