クラウドやコンテナ(仮想化)が当たり前の時代になり、活用の範囲・規模も巨大化してきました。さまざまなアプリケーションのデプロイは自動化され、高負荷時にはコンテナが自動でスケールするなど、これまでのオンプレミスでは考えられなかったようなことが実現できます。
一方で、弊害も生まれてきています。マイクロサービス化が進み、より細かい単位でコンテナを起動したり、高負荷時にはより細かい単位でコンテナをスケールさせたりできます。つまりコンテナが乱立し、運用管理が困難になってきているのです。
そんな中注目されているのがコンテナオーケストレーションツール「Kubernetes」(クーべネイティス。通称k8s)です。
ギリシャ語で「船の舵取り」を意味し、一言で言えばデプロイやスケーリングを含めたアプリやコンテナの運用管理を自動化するためのオープンソースのソフトウェアです。AWS、Pivotal Cloud Foundry、IBM Bluemix、Google Cloudなどのクラウド製品との親和性もよく、近年急速に注目度が上がってきています。
本連載ではクラウドやコンテナの基本としてDockerについて触れつつ、Istio/Stackdriverなどのk8s周辺系も含めて解説していきます。
仮想化によるオンプレミス時代のハードウェア管理からの解放
導入文を見て、「使っている言葉がわからない」「到底ついていけない」と思った方もいらっしゃるかもしれません。「仮想化」「クラウド化」について、まずは紐解いていきましょう。
仮想化・クラウド化がおこる前のシステムの構成はどんなものだったでしょうか。
クラウドとの対比で語られ、自前のデータセンターに基盤技術者がWebサーバやDBサーバなどを個別に導入していく、いわゆる「オンプレミス」の構成です。この時代にはハードウェア上に載せる機能(ミドルウェアなど)が1:1で対応していました。ハードウェアの搬入・結線、およびOSやミドルウェアのインストール作業に多くの時間がかかるばかりか、日中はCPUを使い切っているが夜間は空いているといったことも発生しました。
これらを解決するために生まれたのが仮想化です。仮想化は機能とハードウェアを疎結合にし、1:nやn:mの関係を実現します。これにより、インストール作業を軽減しリソースを有効します。多重度で分類すると、1:nを実現するのが、VMWareやDockerなどであり、n:mを実現するのがKubernetesやDocker Swarmなどです。
機能とハードウェアの多重度の違い |
クラウド時代における仮想化レイヤ
クラウド時代においては、サーバリソースは伸縮性を持ち、アプリケーションの配備に関わる考え方も激変しました。OS層における仮想化(下図レイヤ3)は起動に時間がかかるため、サーバリソースの即時スケールに課題がありました。
仮想化の種類 |
ハイパーバイザの登場により、ホストOSが不要になり、仮想化によるサーバリソースのオーバーヘッドは減少したものの、起動速度はOSの起動速度に依存し、秒単位の即時スケールは困難でした。
そんな中、OS層(レイヤ3)ではなく、Dockerなど一層上の領域(レイヤ4)を仮想化するコンテナが登場しました。Kubernetesはさらに上位レイヤ(レイヤ5)を仮想化し、個別のコンテナの管理を意識しなくてよくなったと捉えると良いでしょう。
Kubernetesの3つの価値とは
Kubernetesには、大きな価値が3つあります。
1つ目は高い抽象度です。Dockerコンテナは通常一台のサーバ内に閉じて構築されます。複数台のサーバにまたがるコンテナ環境を構築するためには、ネットワークにおけるNAT設定など、さまざまな設定が必要になります。
こういった問題にアプローチするのがKubernetesです。Kubernetesを使うとコンテナのクラスタ化が容易になります。クラスタはサーバ単位でコンテナを管理するPodと、サーバをまたがるPodを管理するReplicaSetの組み合わせで構築されます。
2つ目は高い信頼性・回復性です。セルフヒーリングと呼ばれ、障害により設定された台数を下回った場合には、自動的にコンテナが再起動されます。これにより、ゼロダウンタイムを実現します。
3つ目は中立性です。Kubernetesを実現するサービスはGoogle Cloud PlatformやOpenStackなどさまざまに存在します。CNCF(Cloud Native Computing Foundation)により標準化されており、Kubernetesが各クラウドを抽象化する層を担うことで、ベンダーロックインを防ぎます。
Kubernetesの仕組み
Kubernetesのアーキテクチャを理解するには、以下4つの「コンテナの管理単位」の理解が必須です。誤解を恐れずに言えば、[Pod] < [ReplicaSet] < [Deployment] < [Service]の順に単位が大きくなっていくとイメージすると良いでしょう。
Podは1つ以上のコンテナで構成され、以下のような単位でまとめてコンテナを格納します。
デプロイ単位 : nginxを使ったリバースプロキシのコンテナと、バックエンドのアプリケーションのコンテナなど、同期をとってデプロイする必要があるケース
ローカルアクセス : Pod内のコンテナは同一ノードに配備されるため、ローカルでのネットワークアクセスやストレージアクセスが必要なケース
ReplicaSetは同一Podを複数生成することで、信頼性を確保します。回復性を併せ持ち、1つのPodがダウンしても自動で再起動します。
DeploymentはReplicaSetと似ていますが、コンテナのバージョンアップ時など、ReplicaSetを複数バージョン管理でき、デプロイ時のダウンタイムを制御します。
Serviceはロードバランサ機能も有しており、外部からのアクセスを請負います。
Pod/ReplicaSet/Deployment/Service |
以下の例では、プロキシサーバとしてnginxとバックエンドのアプリケーション(ap)に対し外部クライアントからアクセスするケースを想定します。
Kubernetesの最小単位であるPodを起点として、ReplicaSetにより3多重にしたPodをv2へのバージョンアップと同時に2多重に変更しています。外部からのアクセスはServiceが一元的に受けています。
Kubernetesのアーキテクチャの基本 |
KubernetesのHello World
[kubectl]を使ってKubernetes環境を構築してみましょう。なお、今回はコマンドのイメージをご理解いただくのみとし、前提となるDockerやKubernetesのインストール手順などは次回以降説明します。
$kubectl run nodeapp --image=nginx:latest --replicas 3 --labels="app=nodeapp"
deployment.apps/nodeapp created
$kubectl create service loadbalancer --tcp 9000:80 nodeapp
service/nodeapp created
ブラウザから[http://localhost:9000/]にアクセスします。
http://localhost:9000/ のアクセス結果 |
YAMLの壁とKubernetesの周辺技術
「YAMLの壁」と呼ばれ、Kubernetesを構築する際に数々のyamlファイルを作成しなければならないと言われることもあります。Webアプリケーションで言えば、StrutsやSpringフレームワークが流行した際に数々のxmlファイルを作成しなければならなかった「XML地獄」と状況が似ています。こうした課題を解決するため、パッケージマネージャであるHelmなどが注目されています。
他にも、Kubernetes環境を手軽に構築するRancherやさまざまな種別のコンテナをサービスメッシュとして一元管理する「Istio」、コンテナの稼働状況を一元的に見える化する「Stackdriver」などがあります。Kubernetesを最大限に活用するためには、こういった周辺技術も併せて習得していと良いでしょう。
* * *
クラウド時代において仮想化の活用が進んできており、Dockerなどのコンテナ技術や、Kubernetesなどのコンテナオーケストレーション技術が注目されています。Kubernetesの周辺技術もさまざまに存在し、全体像を抑えた上での活用が望まれます。
Kubernetesはバージョンアップが早く書籍やWeb記事の記載については、最新版では仕様が変わっている可能性があるため、注意が必要です。
次回以降はDockerやKubernetesに実際に触れることで、理解を深めていきます。
著者紹介
正野 勇嗣 (SHONO Yuji ) - NTTデータ 課長
2011年まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。
最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。3児のパパ。