概要

HashiCorp のブログとサイトで、DevOps Defined(定義)に関する2つのドキュメントが公開されました。自分用に翻訳していたのですが、死蔵させておくのも無意味と思い、いつもの通り公開します。私はアプリケーションの開発者寄りではないため、開発寄りのキーワードの翻訳に誤っているところがあれば、ご指摘いただけますと幸いです。

HashiCorp、DevOps、そして、アプリケーション・デリバリ・プロセス

本日の DevOps Defined(DevOps定義)正式発表をとても嬉しく思います。DevOps Defined とは、DevOps の採用によりアプリケーション・デリバリ(application delivery)を速めるためのガイドです。2年前、私たちは Tao of HashiCorpHashiCorp 道)を公開しました。これは、私たちのツールの背景にある設計原理や哲学について詳しく述べたものです。そして、それ以降は、HashiCorp 道を追求すべく VaultNomad など新しいオープンソース・プロジェクトを立ち上げました。これは私たちの技術を共有するという方向づけには、とても有用な財産となりました。

しかしながら、技術とはソフトウェア開発における1つの側面にしかすぎません。ソフトウェアの組織を構成するのは、働く人々、過程(プロセス)、技術です。技術のみに集中するのは簡単ですが、突き詰めていけば、人と過程に対する成功を目指すことになります。つまり、重要なのはソフトウェア組織を支える人々のワークフロー(作業の流れ)と生産性に対する理解です。自らの組織設計にあたっては、ワークフローの強化を通してチームが連携できるようにすべきでしょう。これこそ、私たちにとっての DevOps の本質なのです。

私たちの技術設計思想を HashiCorp 道として定義したように、DevOps Defined では、開発・運用・セキュリティを横断するソフトウェア・チームが生産性をいかに高め、そして、並行して働けるかを定義します。DevOps の目指すところを念頭に置き、私たちは明確な方向性を持ってツールの技術開発します。すなわち、開発・運用・セキュリティの各専門家が生産性をより高めるためのツールを作り上げるのです。

アプリケーション・デリバリの7つの要素、アプリケーション・デリバリを高めるために DevOps 組織をどのように構築するのか、組織内における開発・運用・セキュリティ専門家を強化する技術の使い方について、それぞれを学ぶには DevOps Defined ガイドの全文 をご覧ください。

DevOps Defined(DevOps 定義)

Accelerating the Application Delivery Lifecycle(アプリケーション・デリバリ・ライフサイクルの加速)

課題

DevOps の定義はビジネスによって変化しますが、DevOps におけるツァイトガイスト(zeitgeist、訳者注:ドイツ語の「時代精神」であり、時代背景といった意味合い)とは、ソフトウェア・アプリケーションの出荷(shipping、訳者注;日本でいうところの「ソフトウェアのリリース」)・素早い繰り返し(rapidly iterating)・安全性の問題(securing)を最小限に抑えることです。HashiCorp が DevOps として定義するのは、現代のアプリケーションの必要性、すなわち個人のアジリティ(agility;敏捷性)向上に力を入れるのに関連する、組織のプロセス(過程)なのです。

DevOps is about minimizing the challenges of shipping, rapidly iterating, and securing software applications. (DevOps とはソフトウェア・アプリケーションの出荷・素早い繰り返し・安全性の問題を最小限に抑えること)

DevOps が主に対象とするのは、アプリケーション・デリバリ(delivering applications)に関係する人々であり、開発者、オペレータ、セキュリティ専門家です。3つの役割は持ちつ持たれつの関係であり、アプリケーション配信に寄与するため、密接に連結したツールが必要です。

DevOps とはソフトウェア・デリバリ(配信)のウォーターフォール・モデルから離れる運動(movement、ムーブメント)です。ウォーターフォール・モデルでは、様々なグループを直線上に流れる滝(ウォーターフォール)を通し、ソフトウェア・アプリケーションがデリバリ(配信)されます。開発者は要件を受け取り、アプリケーションを書き、テストを行う品質保証(QA, Quality Assurance)に渡します。開発段階が終われば、アプリケーションはパッケージング(packaging)とユーザ受け入れテスト(user acceptance testing)を行うリリース・チームに渡されます。テストが完了したら、セキュリティ専門家を迎え入れ、コンプライアンス(整合性)とベスト・プラクティスを裏付けます。それから、オペレータがアプリケーションをデプロイしたら、滝(ウォーターフォール)の落下点である監視チームに最終段階として至ります。

伝統的なウォーターフォール・ソフトウェア・デリバリ・モデルの問題点とは、アジリティ(敏捷性)を最大化するのではなく、リスク(危険性)を最小限に抑えることです。ウォーターフォールは個々の自主性を制限し、フィードバック・ループを遅くし、アプリケーションの細やかな変更のたびに多くのチームとチェックポイントを必要とします。

また、DevOps の盛り上がりは、分散型サービスとデータセンタ資源(リソース)を特長づけるハイブリッド・クラウド基盤(インフラ)の台頭にも関係しています。最新のアプリケーションはインターネットに接続しており、ブラウザやモバイル・アプリなどのシン・クライアント(thin client)を備えています。更新を素早く提供できますので、専門的なリスク管理を必要とする「リコール」(recall)はほとんどなくなりました。

DevOps を正しく行えば、ソフトウェア・デリバリ速度を最大化します。配信プロセスのすべてを全体的に眺めれば、よく起こる(traditionally happen)ボトルネックを解消できます。ボトルネックとは、ある処理(プロセス)を担う役割(ロール)に対する負担が高まること。つまり、ソフトウェアは一日のうちで最も遅いチームと同じ速さでしか配信できなくなるのです。

DevOps Defined

Provision, Secure and Run Any Infrastructure For Any Application

あらゆるアプリケーションのインフラ(基盤)でプロビジョニング(供給)、セキュア(安全)、実行を。

組織によってソフトウェア・デリバリ・プロセス(配信手順)の要素が微妙に違います。これは、技術の選択、コンプライアンス要件、あるいはその他の要因によるからです。しかし、木だけではなく森全体を見渡せば、ソフトウェア・配信のライフサイクルには7つの要素があります。

BUILD (構築)

アプリケーションは開発者がコードを書くところから始まります。新しいアプリケーションであれば初期バージョンを書く必要があります。既存のアプリケーションであれば、新しい機能の追加や、バグ修正、性能向上のために、絶え間ないサイクル(繰り返し)があります。この要素は主に開発者が関わるだけでなく、運用チームでも開発者がコードを書くための環境やツールを提供する役割を担うことがあるでしょう。

TEST(テスト)

アプリケーションの作成段階やリリース前には、複数種類のテストを実施します。最も簡単なテストは開発者が行う単体テスト(unit testing)です。そして、統合テスト(integration testing)、受け入れテスト(acceptance testing)、エンドツーエンド・テスト(end-to-end tests)などに階層化できます。これはアプリケーション・デリバリのライフサイクルにおいて重要な部分です。なぜなら、自動的なフィードバックと重要なリスク管理の制御をするからです。開発者の大半のみ関わるだけでなく、専門の QA チームやテスト基盤を管理する運用チームも関わる場合もあるでしょう。

PACKAGE(パッケージ)

アプリケーションを作成し、テストを終えたら、そのアプリケーションをプロダクション(production)用にパッケージ化する必要があります。パッケージ化にあたっては、技術と対象となる環境により、大きく依存する場合があります。たとえば、JBoss の場合は WAR ファイルですし、Kubernetes の場合は Docker コンテナです。アプリケーションの土台(基礎)となるものは、ソースコードを元に、対象の環境上で実行可能なファイルとしてパッケージされています。これらのパッケージは Artifactory (アーティファクトリ、訳者注:Terraform のアーティファクトを置く場所)などのレジストリに格納されています。

PROVISION(プロビジョン)

アプリケーションはどこかしらで実行する必要があります。あらゆる抽象化レイヤの下では、コンピューティング、ストレージ、ネットワークといったリソースの提供が依然として存在します。これらはベアメタルや仮想マシンで直接提供される場合もあれば、PaaS や Lambda-as-a-Service(サービスとしてのラムダ)フレームワークを通して間接的に提供される場合もあります。どちらの場合でも、アプリケーション要件にあわせてプロビジョニングと設定をし、時間の経過とともに更新し、役目を終えれば最終的に廃止する必要があります。通常、運用チームがプロビジョニングを管理(owned)しており、開発者に対して提供します。

SECURE(セキュア)

連結が少なければ少ないほど(as weakest link)、システムの全体的なセキュリティが強力になります。これは、アプリケーション配信プロセスの最初から、セキュリティが関与しているのを意味します。セキュリティ・チームは、開発中にベスト・プラクティスを用いる手助けをし、ネットワーク・トポロジのモデリングを支援し、インフラのプロビジョンに使うプロジェクトの資格情報(credential)を保護します。また、データベースのパスワードや API トークンなど、アプリケーションのデプロイに必要な秘密情報(secret、訳者注:パスワードや秘密鍵などセキュリティ上の重要な情報)に対する権限を与えます。一般的にはセキュリティは専属チームの役割ですが、アプリケーションを提供する他のチームも関与します。

DEPLOY(デプロイ)

デプロイ(展開)とは、基盤となるリソースをプロビジョニング(提供)した状態において、パッケージ化したアプリケーションを取得し、実行するのを意味します。マシンまたは仮想マシンが単一のアプリケーションを実行するよう特化している場合であれば、プロビジョニングとデプロイを密接に連携できます。一方、(プロビジョニングとデプロイが)分かれている場合であれば、スケジューラを用いてマシン上に動的にアプリケーションを置きます。

MONITOR(モニタ)

実行中のアプリケーションに必要なのは、実行が継続し、正常でありつづけるのを監視することです。サービスは障害または劣化したインスタンスからの通信を回避しながら、相互に通信する必要があります。これを担うのがサービス・ディスカバリです(service discovery)。きめ細かい生存確認からログ(logging)とテレメトリ(遠隔測定データ)に至るまで、監視は広範囲に至ります。監視に含まれる担当は、アプリケーションの動作を理解したい開発者と、インフラを管理するオペレータ、アプリケーションの広範囲を維持管理するサイト信頼性チーム(site reliability team)です。

DevOps Delivered (DevOps をもたらす)

Provision, Secure and Run Any Infrastructure For Any Application

あらゆるアプリケーションのインフラ(基盤)でプロビジョニング(供給)、セキュア(安全)、実行を。

高い能力を発揮するチームを設計する(組織する)のは、高性能アプリケーションの設計と似ています。つまり、調整を最小限に(minimal coordination)することです。ソフトウェアの場合はアムダールの法則(Amdahl’s law、計算機システムの並列度を上げたときの性能上限、ウィキペディア )で最も表されています。そこで、働く個人を「serial execution units」(連続実行ユニット、連続実行単位)と考えれば、同じように人間の生産性も調整(coordination)による支配を受けます。

アプリケーションを配信(デリバリ)するには、7つの要素を飛ばせません。つまり、各ステップの実行に必要な調整を最小限に抑えるのが最優先です。各チームが独立して働けるようになれば、調整を減らせられ、個々の生産性を高められます。すなわち、アプリケーションの配信速度を向上します。これこそが DevOps の中心です。そして、私たちが選択するツールは、これら重要な機能の優先度づけをする必要があります。一貫したプロセスを維持するには、大部分の組織の現実である技術的な不均質に対処するため、これらのツールは技術ではなくワークフローに集中する必要があります。

HashiCorp が提供するのは DevOps を考慮したツール一式であり、アプリケーション配信ライフサイクルの要素間における手動調整を減らすのに重点を置いています。

Vagrant(ベイグラント)

Vagrant は開発者が同僚やオペレータに相談しなくても、自分で開発環境を迅速にセットアップできるようにします。プロダクションのような環境を提供するだけでなく、開発者はより厳しいフィードバック・ループでコードを簡単にテスト可能となります。これは継続的インテグレーション(CI: Continuous Integration)の目標の1つであり、開発者は迅速なフィードバックを受け取ることで、個々の生産性を高められます。

Vagrant について学ぶ

Packer (パッカー)

Packer はアプリケーションをあらゆる環境で実行できるようパッケージするだけのワークフローを提供します。Packer の設定を共有することで、チームを切り離しても、調整をさけることが可能となります。調整に相当するのは Autifactory や Docker Hub のようなレジストリに送る(push)だけです。

Packer について学ぶ

Terraform (テラフォーム)

Terraform は共通のワークフローを使い、インフラとアプリケーション・リソースを提供(プロビジョン)するプロダクトです。Terraform はオペレータがプロダクション環境を安全かつ迅速に作成・変更・改善できるようにします。API を宣言的な設定ファイルで体系化しておく(まとめる)ことで、チームメンバ間での共有や、コードのように扱っての編集、レビュー、バージョン管理が可能となります。

Terraform について学ぶ

Vault (ボルト)

アプリケーション配信サイクルのすべての要素にわたり、秘密情報の管理を集中管理する手法を Vault がもたらします。Vault はアプリケーションとエンドユーザに対し、秘密情報を保管・公開するための高い可用性と安全な手法を提供します。たとえば、暗号化鍵、API トークン、データベースの資格情報です。Vault により、チームはセキュリティ・チームと調整することなく、必要なデータを利用できます。セキュリティ・チームは組織を横断した調整を必要なく、パスワードの変更、資格情報の更新、ポリシー変更が可能です。

Vault について学ぶ

Nomad(ノマド)

Nomad はクラスタ・マネージャかつスケジューラです。スケジューラを使えば、組織は懸念事項を解消し、開発者を完全にマシンから引き離せます。そうすることで、開発者は実行したいアプリケーションに集中でき、スケジューラを通してアプリケーションの配置とマシン性能を管理できるようになります。Nomad により、オペレータは多くのマシンに提供(プロビジョン)できるようになります。そして、このマシンは Nomad に対してジョブを送信した開発者とは切り離されているのです。Nomad はアプリケーションを実行可能なマシン上に配置するので、オペレータと開発者が主導で調整しなくても済むようにします。

Nomad について学ぶ

Consul(コンサル)

Consul は HashiCorp のサービス・ディスカバリと監視ツールです。Consul はアプリケーションの広範囲にわたる可用性を高め、他のアプリケーションから簡単に連携できるようにします。たとえば、ウェブサーバは Consul を使い、上流のデータベースや API サービスを見つけられます。また、Consul はアプリケーション全体の正常性を監視し、正常なインスタンスのみがトラフィックを受け取られるようにします。そして、問題があれば開発者やオペレータに通知します。これはマイクロサービスやサービス指向アーキテクチャとの登場と関連しています。モノリシックなコードを元にする場合の調整を行わなくても、サービス更新の更新は個々のチームが独立して並行して行うことにより、生産性が向上します。

Consul について学ぶ

DevOps done right - DevOps を正しく行うことにより、

Allowing Operations, Security and Development teams to work in parallel

(オペレーション、セキュリティ、開発チームが並行して作業できるようになります。)

すべての企業がソフトウェア会社になるにあたり、DevOps モデルを遂行することで、優れたアプリケーションを迅速に提供できるようになります。そして、これを実現すべく、世界中の何十万人ものソフトウェア専門家が HashiCorp DevOps Suite(DevOps ツールの一式)を使っています。

私たちがDevOps の各要素に特別設計したツールを提供することにより、ソフトウェア・サプライ・チェーンにおける様々な関係者(開発、運用、セキュリティ)が、同僚による障害を取り除き、主な関心事に集中できるようになります。つまり、直線的なウォーターフォールの手順(プロセス)を、3つのチームが並列して実行できる手順へと変えるのを意味します。

ワークフローの並行化こそが DevOps の本質なのです。すなわち、アプリケーションをあらゆるインフラ上に供給し、安全に、かつ実行できるのです。

原文

原文にはイラストも掲載されていますので、理解を深めるために是非ご覧ください。

HashiCorp, DevOps, and the Application Delivery process | HashiCorp - https://www.hashicorp.com/blog/hashicorp-devops-and-the-application-delivery-process.html

関連



概要

CoreOS の Blog に “Introducing Operators: Putting Operational Knowledge into Software” という記事が掲載されました。先日の KubeCon でも Keynote で取り上げられていた、 Operator という Kubernetes 上で指定した状態を維持するためのツールについての概要です。

「運用知識をソフトウェアに」と興味深いタイトルに釣られ、ついつい読んでしまいました。記事を書かれた Brandon Philips さん( @BandonPhilips )に翻訳を許諾いただきましたので、ここで公開します。翻訳に間違いがありましたら、どうぞお気軽に @zembutsu までご指摘ください。

Operator の紹介:運用の知見をソフトウェアに入れる

サイト信頼性エンジニア(SRE; Site Reliability Engineer)とは、ソフトウェアを書いてアプリケーションを運用(operate)する人です。SRE はエンジニアであり、開発者でもあり、特定のアプリケーション領域に特化したソフトウェアをどのように開発するかを知っています。結果として、アプリケーション運用範囲の知識を、ソフトウェアの要素にプログラムとして入れ込むことになります。

私たちのチームは Kubernetes コミュニティの企画や実装に対し、今日に至るまでずっと取り組んでいます。実装が目指すのは、 Kubernetes 上の複雑なアプリケーションを、先の概念にもとづき確実に作成・設定・管理することです。

私たちはこの種のソフトウェアを Operator (オペレータ)と呼びます。Operator とはアプリケーションに特化したコントローラです。Kubernetes の利用者に代わり、複雑でステートフルなアプリケーションを作成・設定・管理するために Kubernetes API を活用します。kubernetes 上にリソースとコントローラの概念を構築します。それだけでなく、特定の範囲(domain)やアプリケーション固有の知識を一般的なタスクに自動化します。

ステートレスは簡単、ステートフルは難しい

ウェブ・アプリケーションやモバイル・バックエンド、API サービスの管理やスケールにあたり、Kubernetes では細かな設定をしなくてもすぐ使えるため、比較的簡単です。なぜでしょうか。理由は、これらアプリケーションは一般的にステートレスだからです。追加の知識がなくても、Deployments のような基本的な Kubernetes API によってスケールしたり障害から復帰したりできるのです。

データベース、キャッシュ、監視システムのように、ステートフルなアプリケーションの管理に取り組むのは大変です。これらのシステムでは、正確なスケール、更新(upgrade)、再設定といったアプリケーション領域の知識が必要です。これは単なる知識ではなく、データの欠損(loss)や利用できなくなるのを回避するものです。私たちはこのようなアプリケーション固有の運用知識をソフトウェア内にエンコード(変換)することで、高性能な Kubernetes の抽象化を活用し、アプリケーションを正確に実行・管理できるようにしたいのです。

Operator(オペレータ)はこの領域の知識を変換(encode)します。そして Kubernetes API の拡張により、サードパーティ・リソース(third party resources) メカニズムに対して、利用者によるアプリケーションの作成・設定・管理を可能とします。Kubernetes の内部リソースのように、Operator はアプリケーションの単一インスタンスを管理するのではなく、クラスタを横断する複数のインスタンスを管理します。

Operator の概念がコードをして動くのを実演(デモンストレーション)するために、今日、2つの実装例をオープンソース・プロジェクトとして公開します。

  1. etcd Operator は etcd クラスタの作成・設定・管理をします。etcd は信頼性のある分散キーバリュー・ストアです。CoreOS では分散システムにおいて最も重要なデータを維持するために導入しています。また、Kubernetes 自身の主要な設定データの保存先としても使います。

  2. Prometheus Operator は Prometheus 監視インスタンスを作成・設定・管理します。Prometheus は高性能な監視とメトリック(訳者注:監視データの数値化)とアラート(通知用)ツールです。そして、クラウド・ネイティブ・コンピューティング・ファウンデーション(CNCF: Cloud Native Computing Foundation)のプロジェクトとして、CoreOS チームが支援しています。

どのように Operator が構築するのか?

Operator は Kubernetes の中心となる2つの概念、リソース(resources)とコントローラ(controllers)に基づき構築します。たとえば内部の ReplicaSet リソースの場合、ユーザは実行したいポッドの数を設定します。次に、コントローラは ReplicaSet リソースで設定した数を Kubernetes 内で 常に維持するよう、ポッドを作成、あるいは実行中のポッドの削除といった動作をします。これらの動作は Services、[Deployments]http://kubernetes.io/docs/user-guide/deployments/() 、Daemon Sets でも同様な挙動であり、 Kubernetes におけるコントローラとリソースの多くの基本となるものです。

例1a:1つのポッドが動作中で、ユーザは希望のポッド数を3に設定

例1b:数秒後、Kubernetes 内のコントローラは、ユーザが要求した数と一致するようポッドを作成

Operator は Kubernetes のリソースとコントローラの概念を基盤として、その上に知識や設定を積み上げます。そのため、 Operator は一般的なアプリケーション・タスクを実行できるようになります。たとえば、etcd クラスタを手動でスケール(拡大)しようとする場合、利用者は数ステップを踏みます。具体的には、新しい etcd メンバ用の DNS 名を作成し、新しい etcd インスタンスを起動します。それから、etcd 管理ツール( etcdctl member add )を使い、既存のクラスタに新しいメンバを追加するのを伝えます。この手順ではなく、etcd Operator があれば、利用者は etcd クラスタのサイズのフィールドを1から単に増やすだけで済むのです。

例2:ユーザの kubectl をトリガにバックアップ

複雑な管理タスクの例としては、Operator でアプリケーションを安全な状態のまま更新や、離れた場所にあるストレージに設定ファイルのバックアップ、ネイティブな Kubernetes API を通したサービス・ディスカバリ、アプリケーションの TLS 認証設定やサービスディスカバリなどに利用できるでしょう。

Operator はどのように作成するのか?

Operator は性質上、アプリケーションごとに固有のものです。アプリケーション運用領域に関するすべての知識を、適切なリソース設定と制御のループにエンコード(変換)するのは大変です。ここでは Operator で構築するにあたり、私たちが発見した一般的なパターンを紹介します。これがあらゆるアプリケーションで重要となるものと考えています。

  1. Operator のインストールには、1つだけデプロイします。たとえば kubectl create -f https://coreos.com/operators/etcd/latest/deployment.yaml を実行するのみであり、他にインストール作業はありません。

  2. Operator は Kubernetes に新しいサードパーティ・タイプを追加するでしょう。利用者はこのタイプを使い、新しいアプリケーションを作成するでしょう。

  3. 度重なるテストやコードに対する深い理解をする時に、 Operator は Kubernetes 内部のサービスやレプリカ・セットといったプリミティブのように扱います。

  4. Operator はユーザが作成したリソースの後方互換性と古いバージョンを理解します。

  5. Operator が停止または削除されても、Operator はアプリケーション・インスタンスが影響なく実行し続けられるよう設計しています。

  6. Operator は希望のバージョンを宣言し、希望のバージョンを元にしたアプリケーション更新のオーケストレートを提供するでしょう。ソフトウェアの更新を行っても、操作時のバグやセキュリティの問題を引き起こさないため、Operator を使えば確実に処理する手助けとなるでしょう。

  7. Operator は「Chaos Monkey」テスト・スイートによる試験を実施されることで、Pod や設定やネットワークに関する潜在的な障害をシミュレートするでしょう。

Operator の今後

CoreOS が提供する etcd Operator と Prometheus Operator は、今日時点での高性能な Kubernetes プラットフォームの例です。昨年より、私たちは幅広い Kubernetes コミュニティと行動を共にしています。焦点を当てているのは 、Kubernetes の安定・安全・簡単な管理・簡単なインストールです。

これでようやく Kubernetes の基本を構築できました。次に注力するのは、この上にシステムを構築することです。具体的には、新しい能力を Kubernetes に拡張するためのソフトウェアです。私たちが思い描く未来とは、利用者が自身の Kubernetes クラスタ上に Postgres Operator 、Cassandra Operator 、Redis Operator をインストールし、今日のステートレスなウェブ・アプリケーションを簡単にデプロイするかのように、これらプログラムのインスタンスをスケーラブルに操作できるようにすることです。

より詳しく学ぶには、GitHub リポジトリに飛び込むか、私たちのコミュニティ・チャンネルでの議論、あるいは、11 月 8 日に開催の KuberCon の CoreOS チームの登壇にお越しください。私のキーノートは 11 月 8 日(火) の太平洋標準時午後 5:25 です。そこで Operator とその他の Kubernetes トピックを話します。

FAQ

Q: StatefulSets (以前は PetSets )との違いは?

A: StatefulSets は Kubernetes 用アプリケーションをサポートするよう設計されています。アプリケーションはクラスタ上で IP やストレージのような「ステートフルなリソース」を必要とします。よりステートフルなデプロイ・モデルを必要とするアプリケーションは、障害・バックアップ・再設定のためのアラートや処理のための運用自動化(Operator automation)が必要です。そのため、これらデプロイ特性を必要とするアプリケーションの運用担当者は、Replica Setsや Deployments を活用する代わりに、StatefulSets を使えます。

Q: Puppet や Chef のような設定管理との違いは?

A: コンテナと Kubernetes では、運用担当者が実現できるのに大きな違いがあります。2つの技術は新しいソフトウェアのデプロイ、分散環境における設定の調整、複数のホスト上のシステム状態を一貫性に保つ確認と、Kubernetes API の利用を簡単にします。運用担当者は、アプリケーション利用者が使いやすくなるよう、これらプリミティブを一つにつなぎ合わせます。つまり、これは設定ではありません。今現在のアプリケーションすべての状態を示すのです。

Q: Helem との違いは?

A: Helem は複数の Kubernetes リソースを1つのパッケージにまとめるツールです。概念は複数のアプリケーションを一緒にまとめるものです。Operator はアプリケーション管理で補助的に使えるでしょう。たとえば、traefik はロードバランサであり、etcd をバックエンド・データベースとして使います。皆さんは Helm Chart で treafik のデプロイと etcd クラスタ・インスタンスを一緒にデプロイできます。そして etcd クラスタは etcd Operator を使ってデプロイや管理することもできます。

Q: Kubernetes にとっては何が新しいのですか? どのような意味があるのですか?

A: etcd や Prometheus や今後出てくる複雑なアプリケーションを簡単にデプロイしたい新しいユーザ以外は、これまでと殆ど変わらないでしょう。Kubernetes 上で実行するための推奨手法は、まだ minikube であり、kubectl run なのです。Prometheus Operator を使って監視するアプリケーションのデプロイには kuberctl run を使うでしょう。

Q: etcd Operator と Prometheus Operator のコードは今日から使えますか?

A: はい! GitHub の https://github.com/coreos/etcd-operatorhttps://github.com/coreos/prometheus-operator をご覧ください。

Q: 他の Operator を予定していますか?

A: はい、近いうちに。また、コミュニティを通して新しい Operator が作られるのを歓迎します。皆さんの Operator で何か出来るようになれば、ご連絡ください。

Q: Operator はクラスタを安全にするために役立ちますか?

A: いいえ。ソフトウェアの更新は、一般的に操作時のミスやセキュリティ問題があり、Operator ができるのは利用者に対し、より確実に更新処理を行うことです。

Q: Operator はディザスタ・リカバリに使えますか?

A: Operator が簡単にするのは、アプリケーション状態の定期的なバックアップと、バックアップから以前の状態を戻すことです。私たちが目指す機能としては、ユーザが Operator さえ使えば、バックアップから新しいインスタンスのデプロイを簡単に行えるようにすることです。

原文



概要

7月28日(日本時間29日)、Docker の新しいバージョン 1.12 が GA になりました。blog にも リリースに関する投稿があり、例によって日本語訳を作成しました。内容把握の参考程度にどうぞ。なお、和訳に自信がないトコロは括弧内で原文を表記しています。

Docker 1.12 が一般利用版(GA)に:プロダクション向けに準備が整った Docker 内蔵オーケストレーション

プロダクション環境向けに一般で利用可能な(generally available) Docker 1.12 を作り上げるという、重要な一里塚(マイルストーン)達成のために手助けいただいた、コミュニティの全ての皆さまに感謝を申しあげます。Docker プロジェクトが始まって以来、Docker 1.12 は単一リリースでは最大かつ最も高度な機能群を追加しました。1.12 のオーケストレーションに関しては、多くの技術者(Docker 社員と社外貢献者の皆さん)によって、 様々な面での貢献がありました。貢献とは、オーケストレーション機能の中心となるアルゴリズム、Docker Engine への統合、ドキュメント作成、テストです。

コミュニティの皆さんからの役立つフィードバック、バグ報告、新しいアイディアに、深く感謝を申しあげます。皆さんのご協力がなければ、このように達成できなかったでしょう。特に Docker for Mac と Windows に関しては、6月の DockerCon 以降、1.12 機能に関して何万ものベータテストの皆さんにテストしていただきました。UX のアップ・ダウン投票を通し、bash タブ補完こそが、皆さんが最も必要としている機能だと知見を得られました。DockerCon での公開時点と比較すると、著しい改善を達成しました。たとえば、swarm ノードのジョイン時のワークフロー(簡単に)、エラー報告(簡単に参照)、UX の改善(より論理的に)、ネットワーク(信頼性に関する問題を改善)などです。

また、コアチームは社外メンテナかつ Docker Captain の一人である Chanwik Kaewkasi に大きな感謝を申しあげます。彼は DockreSwarm2000 という素晴らしいプロジェクトで、多くの人々をまとめ上げました。このとき、1.12 RC の swarm モードを使い、コミュニティ全体で約 2,400 ノード、10 万コンテナ近くまでスケールしました。達成できたのは、世界中に拡がるコミュニティを通した提供があったからです。ベアメタルから Raspberry Pi 、様々なクラウドから仮想マシン、x86 アーキテクチャから ARM ベースのシステムに至るまで、ありとあらゆるマシンを提供いただきました。ライブ・データを使った評価を通し、Docker の内蔵オーケストレーションは、初期リリースからちょうど半年で、Docker のオーケストレーション規模が2倍になったと認識しました。これは、アーキテクチャのスケーラビリティを立証するものであり、今後も優れたパフォーマンス最適化の余地がまだあります。

それでは、新しい内蔵オーケストレーションのアーキテクチャについてと、なぜ他のコンテナ・オーケストレーションの手法と異なる構造上の手法をとったのか、それぞれ深掘りしていきましょう。

Swarm モード構造上のトポロジー

Docker 1.12 の内蔵コンテナ・オーケストレーションとは、swarm モードとして知られている機能を有効にするための、オプションの機能セットです。swarm は非集中的(decentralized)であり、Docker ノードの高可用性グループです。各ノードは内蔵型のオーケストレーション・サブシステムであり、Docker に対応した(Dockerized)サービスをスケジュールするために。共通リソースプールを作成する全ての機能を備えています。

Docker ノードの swarm (訳者注:「群れ」や「クラスタ」の意味)は、プログラマブルなトポロジー(接続形態)を作成します。これにより、作業者はノードをマネージャ(manager)にするか、あるいはワーカ(worker)にするかを選択できます。そして、ここには複数のアベイラビリティ・ゾーンを横断して分散化するような、共通の設定を含みます。これらの役割(ロール)は動的なので、API や CLI を通していつでも変えられます。

マネージャが責任を持つのは、クラスタのオーケストレーション、サービス API の提供、タスク(コンテナ)のスケジューリング、障害ヘルスチェック機能を持つコンテナの割り当て(addressing)などです。対照的に、ワーカ・ノードはよりシンプルな機能を提供します。機能とは、タスクをコンテナを通して実行し、特定のコンテナに対するデータ通信をルーティングします。プロダクション環境で強く推奨するのは、「マネージャ」と「ワーカ」のどちらか1つの役割を持たせることです。swarm モードでは、マネージャはコンテナを実行しません。つまり、負荷と攻撃対象領域(attack surface)を減らします。分けることが swarm ノードのセキュリティ優位点の1つです。ワーカ・ノードはデータベースの情報やサービス API にアクセスできません。ワーカ・ノードができるのは、作業を受け付け、状態を報告するだけです。つまり、問題のあるワーカ・ノードがシステムに与えうる影響を最小限にします。

これらのノード間通信の設計に、私たちのチームはかなり注力しました。マネージャとワーカは一貫性、スピード、ボリュームの各用途ごとに、異なる通信が必要です。そのため、2つの異なった通信手法を使います。Raft (ラフト)はマネージャ間のデータ共有で、強い一貫性を保つために(書き込み速度とボリュームの制限を犠牲にし)使います。一方の gossip (ゴシップ)はワーカとの高速な通信とハイ・ボリューム(albeit で結果の一貫性)のために使います。そして、マネージャとワーカ間の通信には、これだけではまだ条件を満たしません。条件の1つは全てが共通する暗号化通信を行うことであり、デフォルトでは mTLS を使います。

マネージャからワーカへの通信

ワーカ・ノードはマネージャ・ノードとの通信に gRPC を使います。これは高速なプロトコルであり、厳しいネットワーク状況でも良好に機能します。そのため、インターネットでの接続(HTTP/2 上に構築)と、内蔵バージョン管理(各ワーカ・ノードで異なったバージョンの Engine が動いていても、同じマネージャ・ノードが通信できます)をも可能にしました。マネージャはワーカに対して実行するタスク・セットを送ります。ワーカは割り当てられたタスクの状態とハートビートをマネージャに対して報告します。この仕組みにより、マネージャはワーカが動作しているのを把握できるのです。

下図はマネージャ・コードのディスパッチャ(dispatcher;発信者、通信指令、配送係)コンポーネントを図式化したものです。どのようにワーカと通信するかを示します。ディスパッチャは各ワーカにタスクを命令する役割を持ちます。対してワーカの役割は、タスクをコンテナに置き換え、コンテナを作成することです。

上図をもとに、Docker サービスが作成され、最終的にコンテナ群を実行するまで何が起こっているかを簡単にみていきましょう。

  • サービス作成

    • ユーザは API にサービス定義を送信します。API は受信し、補完します。
    • オーケストレータ(orchestrator)は、(ユーザによって定義される)期待状態(desired state)を、実際の状態(swarm 上で何が動いているべきか)になるように調整します。API から指定された新しいサービス作成に応答し、タスクを作成します(今回の例では、ユーザはサービスのために1つのインスタンスをリクエストしたと想定します)。
    • アロケータ(allocator)は、タスク用にリソースを割り当てます。全く新しいサービスを作成(API によって作成)し、全く新しいタスクを作成(オーケストレータによって作成)し、どちらにも IP アドレスを割り当てるのに注目します。
    • スケジューラ(scheduler)には、ワーカ・ノードにタスクを割り当てる役割があります。タスクにはノードが割り当てられていないため、スケジューリングが始まります。最適な条件(コンテナやリソースなどに基づく)を見つけ、最終的にはタスクにノードの1つを割り当てます。
    • ディスパッチャ(dispatcher)は、ワーカが接続する場所です。ワーカがディスパッチャに接続したら、命令を待ちます。この方法により、スケジューラによって割り当てられたタスクは、最終的にワーカに対して流されます。
  • サービスの更新

    • ユーザは API を経由してサービス定義を更新します(例:インスタンスを1つから3つに増やします)。API は受信し、保管します。
    • オーケストレータは期待状態と実際の状態を調整します。ユーザは3つのインスタンスを必要としますが、実施には1つしか動いていないのに注目します。そのため、2つの追加タスク作成という反応をします。
    • アロケータとスケジューラとディスパッチャは、先ほど説明した手順を繰り返し、2つのタスクをワーカ上に配置します。
  • ノード障害

    • ディスパッチャは(ハートビート機能によって)接続に失敗するノードを検出します。そして、ノードに DOWN(ダウン状態)とフラグ付けします。
    • オーケストレータは再調整します。3つのインスタンスが実行されるべきですが、そのうちの1を残して障害が起こりました。新しいタスクを生成するよう反応します。
    • アロケータとスケジューラとディスパッチャは、先ほど説明した手順を繰り返し、2つのタスクを新しいワーカ上に配置します。

  • ワーカはゴシップ・ネットワークを使い、オーバレイ・ネットワーク情報を相互に通信します。ゴシップはハイ・ボリュームで、よりスケールできるようピア・ツー・ピア(P2P)ネットワークで設計されています。ノードはタスクを受信すると、コンテナを開始し、他のノードに状態を伝えます。伝えるのは特定のオーバレイ・ネットワーク上でコンテナが開始したという情報です。ブロードキャスト通信はワーカ層で処理されます。スケールを達成できるのは、情報の伝播先は一定数のランダムなノードだけであり、全てのノードに対してではないためです。それで、swarm (クラスタの)大きさにかかわらず動作します。

どのような意味が?

それで、Docker 1.12 オーケストレーションが開発者やオペレータにとってどのような意味があるのでしょうか。今回のリリースでは実に3つの重要なテーマがあり、以下のようなリッチなアーキテクチャをもたらします。

  • フォールト・トレラントな(耐障害性の)アプリケーション・デプロイ・プラットフォーム 。モダンなアプリケーションで増えているのは、マイクロサービス・アーキテクチャ型の設計です。これは、ユーザが複数の異なるサービスを処理するために必要な、データを戻す処理を提供(process of serving back data)します。現実世界のマシンは常に故障するため、これらのマイクロサービスではランダムな障害発生に絶え間なく直面します。Docker 1.12 はマネージャのクォーラム(quorum)の活用により、SPOF (単一障害点)がゼロになる力を提供します。加えて、サービスの抽象化により、複数のレプリカ実行や、ホストで障害が発生しても迅速な再スケジュールを提供します。

  • スケールとパフォーマンス 。Docker 1.12 の swarm モード・オーケストレーション設計は、スケールとパフォーマンスに対する考慮にもとづいています。たとえば、内部の Raft 分散ストアはインメモリのキャッシュ・レイヤを通して、電光石火の如く素早い読み込みに最適化しています。キャッシュは素早い読み込みをもたらしますが、書き込みはどうでしょう。もちろん、各マシンのキャッシュは無効化や更新されるでしょう。私たちの解決策は、オーケストレーション機構の後で処理する設計です。読み込みが集中しても、Raft ストアへの書き込みを絶対に行う設計です。オーケストレーション・システムに組み合わせの判定を導く設計は、一般的なキーバリュー・ストアをベースとするオーケストレータよりも、優れた性能をもたらします。

  • 安全なネットワーク機能 。多くのシステムではセキュリティを有効化するためには、TLS 証明書の生成、異なるポート上でのシステム実行、暗号化されておらず安全ではないネットワークにパケットが流れ出ないよう、トラフィックの流れを調整する必要があるでしょう。Docker 1.12 ではこれら全てを難しい設定を一切必要とせず[*] 利用できます。システムは「デフォルトで安全」です。つまり、安全なアプリケーション管理プラットフォームを準備するために、セキュリティ専門家を必要としません。

[*] この記述には小さな例外があります。オーバレイ・ネットワークのトラフィックです。現時点の Docker バージョンでは、暗号化を有効化するためにはフラグの手入力 -o encrypted (on docker network create -d overlay が必要です。それ以外のトラフィックは、デフォルトで暗号化されています。

Docker 1.12 Swarm モードのディープ・ダイブを確認しましょう:

参照


【参考訳】Vault 0.6

09.07.2016  in Vault using tags HashiCorp , Vault , translation

概要

6月14日に、HashiCorp の blog にVault 0.6 のリリースに関する解説記事がありました。こちらも例によって訳しましたので、参考程度にどうぞ。

※ 今回は Vault 独特の用語が多く、翻訳内容には通常よりも多くの意訳箇所があります。そのため、普段より “日本語(英語)” のように、原文併記している箇所が多く読みづらい所がありますが、ご容赦願います。 この意図は、HasihCorp の Vault について、話題に上げたり議論できる人を増やしたいなぁという思いからです。そのため、内容について気になる箇所がありましたら、随時ご指摘いただけますと幸いです。

Vault 0.6

私たちは Vault 0.6 のリリースを誇りに思います。Vault はシークレット(secret)管理用のツールです。API 鍵や暗号化された細心の注意を払うべきデータを、完全な内部認証局(CA)を持つ Vault に置けます。つまり、シークレット管理に必要な全ての解決策(solution)を Vault が提供します。

今回のリリースでは、重要な新機能をいくつか追加しました。ほかにも、新しいセキュア・ワークフローの拡張や、多くの改良、バグ修正を行いました。特に集中したのはトークン管理(token management)とトークン/認証ワークフローです。

詳細:

概要

  • Codebase Audit(コードベースの監査)
  • Integrated Consul Health Checks(Consulヘルスチェック統合)
  • Lisner Certificate Reloading(リスナー証明書の再読み込み)
  • MSSQL Credential Generation(MSSQL 証明書生成)
  • Azure Data Store(Azureデータ・ストア)
  • Swift Data Store(Swiftデータ・ストア)

(いくつかの機能は 0.5.1 と 0.5.2 で搭載したものですが、これまでブログに解説を投稿していませんでした。)

変更に関する全ての詳細は Vault 0.6 CHANGELOG をご覧ください。さらに、この投稿の最後に書いた更新に関する情報は必ずお読みください。

いつもの通り、アイディア、バグ報告、プルリクエストをいただいた私たちのコミュニティに対して、大変感謝を申しあげます。

Vault 0.6 の主な新機能について学ぶには、このまま読み進めてください。

Token Accessors

トークンの作成時、2つの値を返します。トークン自身と認証機構(accessor;アクセッサ)です。

$ vault token-create -policy=default
Key             Value
---             -----
token           82c5fb97-da1b-1d2c-cfd5-23fa1dca7c85
token_accessor  dd256e17-b9d9-172d-981b-a70422e12cb8
token_duration  2592000
token_renewable true
token_policies  [default]

トークンに対する知識がなくても、トークンの表示(lookup)や無効化(revocation)の処理を認証機構で行えます。使うには auth/token/lookup-accessor /auth/token/revoke-accessor を通すか、各 CLI コマンドで -accessor フラグを指定します。認証機構で表示機能を使っても、トークン ID を返しません。

認証機構を持つクライアントを識別するための情報を保管するため、他のクライアントが作成したサービス用トークンに関する情報の表示や、必要があれば後でトークンを無効化できます。たとえば、トークンを作成した従業員が会社を辞めたとします。認証機構を使えば、保管されているトークン ID がなくてもトークンを無効化できます。

これを簡単に行えるだけでなく、トークン・ストアを直接使わずに作成したトークンのワークフローにも便利です。また、認証機構(accessor)値の HMAC (ハッシュ・ベースのメッセージ認証符号)化をオプション設定を無効にもできます。(デフォルトの HMAC 化は、認証機構の値にアクセス可能な誰もが、トークンでの認証を無効化するサービス拒否攻撃を行えてしまいます。そして、たいていのログは厳密に管理されていません。) 監査バックエンド(audit backend)を有効にしている場合は、設定オプションで hmac_accessor=false を指定すると、この挙動が有効になります。

Token Authentication Backend Roles

トークン認証バックエンド(Token Authentication Backend) はロール(役割)の概念を取り入れました。ロールが提供するのは管理度(degree of administrative)の柔軟さであり、許可されたユーザがトークンの作成時、ユニークな属性(properties)や他の behalf を含められます。

トークン・アクセス機構と一緒にこれらのロールを有効にすると、直接トークンを作成するよりも優れたワークフローになります。管理者は上限(limit)や機能(capabilities)を指定するためにロールを設定できます。そして、信頼するユーザやサービスに対してはトークンを作成できるロールを割り当て可能です。サービスごとにトークンを指定できるので、認証機構の値(accessor)は監査ログ(audit logs)に文字列(plaintext)で書き込めます。たとえば、無効化(revocation)が必要であれば、認証機構を通して特定のトークンの無効化や、特定のロールが発行したトークンを全て無効化できます。

もう1つ書き加えておきます。 auth/token/create でトークンを直接作成する時、再利用性(renewability)と最大 TTL の明示も制御できます。

Response Wrapping

トークン認証バックエンド・ロールとトークン認証機構は、きめ細かな権限の管理を可能にします。しかし、生成したトークンを安全に配布する問題は解決していません。安全な導入が難しい課題です。その理由の1つは、高度に安全な通信経路の確保が大変だからです。

Vault 0.6 でレスポンス・ラッピング(response wrapping)を導入しました。これはセキュリティ・プリミティブ(訳者注:セキュリティ上の構造、の意味)です。Vault が生成したトークンを配布するだけでなく、簡単かつ安全に行えるようにします。

詳細な仕組みを説明する前に、読者の皆さんには Cubbyhole 認証パラダイム に関する投稿をあらかじめお読みになったほうが良いかもしれません。以降の段落に関する概要を説明していますが、全くのオプションです。ですが、レスポンス・ラッピングはパラダイムの一部を完全に実装したものであり、より優れたセキュリティを提供します。そのためには、スタンドアロンのプロセスが tempperm トークンを管理します。この実装の詳細については先の投稿の通りであり、 /sys のパスを除き、レスポンス・ラッピングは Vault に到達するあらゆる応答に使えます。

レスポンス・ラッピングは以下の通りに動作します。ここで想定するシナリオは、クライアントが Vault からシークレットを取得するにあたり、利用可能なシークレットしか表示できないように制限します。

  1. クライアントのリクエストに、応答をラッピングするためのラッピング・トークン(wrapping token)の適用期間を指定します。CLI 上で使うには、グローバル・クライアント・フラグの -wrap-ttl を指定します。

  2. Vault はリクエストを通常通り処理します。ですが、通常通りに応答するのではなく、JSON シリアル化(JSON-serialize)した応答をします。この応答には、新しいトークンの cubbyhole を含みます。新しいトークンを使うのは、クライアントで指定した TTL の間のみであり、延長できません。

  3. Vault は新しいレスポンスを生成して応答します。ここでラッピングする情報には、ラッピング・トークン ID とラッピング・トークンの有効期間です。

  4. クライアントは対象のターゲットに対し、ラッピング・トークンを渡します。

  5. 対象のターゲットは、トークンを使い unwrap (ラッピングされていない)処理をします。水面下で行っているのは、をトークンの cubbyhole が既知の場所から、オリジナルの応答単に受け取るだけです。そして JSON でパースし、通常通り応答します。API や CLI を透過するだけであり、Vault から直接応答を得るのと、ラッピング・トークンから読み込みパースするのと、両者に差違はありません。

  6. 対象のターゲットが権限がないと拒否された場合、トークンの TTL と作成時間を比較し、有効期間を超えていないか確認します(対象のターゲットから取得するには、おそらく時間がかかるでしょう)。もしも有効期限が切れていなければ、ターゲットはセキュリティ警告をあげます。警告の内容は、応答がラッピングされていない可能性と、シークレットが意図しない第三者に漏洩している可能性です。

この流れを説明するため、以下では CLI コマンド token-create を2回実行します。1つは正常ですが、もう片方はラッピングされていない処理です。

#
# 通常の token-create コマンド
#

$ vault token-create -policy=default
Key             Value
---             -----
token           ff999148-077e-2629-8d9a-cb0a7b97e811
token_accessor  8c243823-5820-ff8f-f641-6999290c60c0
token_duration  2592000
token_renewable true
token_policies  [default]

#
# レスポンス・ラッピングに対応した token-create コマンド
#

$ vault token-create -policy=default -wrap-ttl=60s
Key                             Value
---                             -----
wrapping_token:                 7a39125a-2001-be9b-e363-3ba85a16c311
wrapping_token_ttl:             60
wrapping_token_creation_time:   2016-06-14 06:02:11.171558903 +0000 UTC
wrapped_accessor:               ed96a7ae-dfdb-3c09-0a60-a02b53dfe6b2

#
# ラッピングしていない応答
#

$ vault unwrap 7a39125a-2001-be9b-e363-3ba85a16c311
Key             Value
---             -----
token           d878b2ed-564e-0790-4154-67bcf7386268
token_accessor  ed96a7ae-dfdb-3c09-0a60-a02b53dfe6b2
token_duration  2592000
token_renewable true
token_policies  [default]

#
# 無効なトークン(使用済み)の検出
#

$ vault unwrap 7a39125a-2001-be9b-e363-3ba85a16c311
error reading cubbyhole/response: Error making API request.

URL: GET https://127.0.0.1:8200/v1/cubbyhole/response
Code: 400. Errors:

* permission denied

この例でご覧の通り、ラッピングした応答にトークンを含む場合、トークン認証機構はラッピング情報を提供します。これにより、特権を持つ実行者(privileged caller;訳者注、管理者の意味)が生成したトークンにより、そのクライアントが対象とした認証機構の追跡を簡単にします。これは万が一の時にトークンを無効化するためです。

レスポンス・ラッピングは Vault リクエストのほとんどで利用可能です。そのため、あらゆるシークレットに対し、転送時のセキュリティ拡張をもたらします。

#
# K/V (generic) バックエンド
#

$ vault write secret/foo bar=baz
Success! Data written to: secret/foo

$ vault read -wrap-ttl=60s secret/foo
Key                             Value
---                             -----
wrapping_token:                 3a63ff9f-1c38-af43-0a85-dc1155f2469d
wrapping_token_ttl:             60
wrapping_token_creation_time:   2016-06-10 13:46:14.155857566 -0400 EDT

$ vault unwrap 3a63ff9f-1c38-af43-0a85-dc1155f2469d
Key                     Value
---                     -----
refresh_interval        2592000
bar                     baz

#
# Transit バックエンド
#

$ echo "bar" | base64 | vault write transit/encrypt/foo plaintext=-
Key             Value
---             -----
ciphertext      vault:v1:j4Z1/6WLK+snlhIyooxa1zW0yEmBqFSfZTL88bN/Qt4=


$ vault write -wrap-ttl=60s transit/decrypt/foo ciphertext="vault:v1:j4Z1/6WLK+snlhIyooxa1zW0yEmBqFSfZTL88bN/Qt4="
Key                             Value
---                             -----
wrapping_token:                 e93a78ec-cced-dc94-d1f8-d71e84faddde
wrapping_token_ttl:             60
wrapping_token_creation_time:   2016-06-07 15:59:18.251657838 -0400 EDT

$ vault unwrap -field=plaintext e93a78ec-cced-dc94-d1f8-d71e84faddde | base64 -d
bar

AWS EC2 Authentication Backend

AWS EC2 認証バックエンド は、 EC2 インスタンスの自動的な Vault 認証と Vault トークンの取得を可能にします。対応クライアントでの AMI 操作は、ユーザ側の調整や設定変更を行わずに認証できます。

バックエンドは AWS を信頼できるサード・パーティとして扱います。特に AWS のインスタンスが提供するのは、秘密鍵で署名されたメタデータと、確認可能な公開済みの公開鍵です。ハイレベルでは、バックエンドは与えられたメタデータの整合性を確認します。具体的には、インスタンス ID が過去に使われていないか(TOFU あるいは Trust On First Use =間違いなく初めて使う、の原則として知られています。)と、そのインスタンスが実行中の状態かです。また、バックエンドはクライアントが指定した一時的な値も受け付けます。たとえば、初期のトークンの有効期限が切れたら、新しいトークンの取得に使います。そして、他のクライアントがメタデータを再利用しようと試みても、それを拒否します。

ローレベルでは、セキュリティ・ポリシーと組織における広範囲のワークフローに一致するよう、様々な制限(modification)をサポートしています。詳細についてはドキュメントをご覧ください。

インスタンスを認証するには、インスタンス内で動作するクライアントが Vault と通信し、Vault の API を通して必要な情報を渡す必要があります。Vault Enterprise をご利用のお客さまには、デプロイのワークフローを簡単にするため、HashiCorp が構築したスタンドアロンのバイナリを提供しています。クライアントは与えられたトークンを更新し続けます。トークンの有効期限が切れれば、再認証して新しいトークンを取得します。

Vault Enterprise クライアント・バイナリは単純にバックエンド API を使うだけです。しかし、Vault 内部の挙動はオープンソースで公開されているものとは異なります。Vault Enterprise をお使いではない組織でも、必要があれば自分でクライアントを構築できます。あるいは HashiCorp に Vault Enterprise に関する情報をお訊ねください

他の機能

今回のリリースでは、多くの新機能追加と改良を施しました。その中でも、いくつかの重要な項目を紹介します:

  • Codebase Audit(コードベースの監査) … Vault 0.5 のソースコード群は iSEC パートナによって監査済みです(私たちには監査内容の一般公開が許されていません)。
  • Integrated Consul Health Checks(Consulヘルスチェック統合) … Consul データ・ストア自動的に vaule サービスを登録し、Consul でヘルスチェックを実施します。デフォルトでは、アクティブなノードは active.vault.service.consul から確認できます。また、スタンバイ・ノードは standby.vaule.service.consul から確認できます。デフォルトの Consul のサービス・ディスカバリでは、封印済みの(sealed) vault を critical(クリティカル)と認識するため、一覧に表示しません。詳細は ドキュメントをご覧ください。
  • Lisner Certificate Reloading(リスナー証明書の再読み込み) … Vault の設定リスナーは、Vault が SIGHUP を送ると TLS 証明書を秘密鍵を再読み込みします。これにより、Vault 証明書の再読み込みにあたり、Vault の停止や封印解除(unseal)の作業が不要になります。
  • MSSQL Credential Generation(MSSQL 証明書生成) … Vault が既にサポートしてる Postgres や MySQL と同様、証明書を生成するバックエンドに MSSQL が使えます。
  • Azure Data Store(Azureデータ・ストア) … Vault が既にサポートしている S3 と同様、Vault の物理データ・ストアとして Azure blob オブジェクト・ストレージが使えます。
  • Swift Data Store(Swiftデータ・ストア) … Vault が既にサポートしている S3 と同様、Vault の物理データ・ストアとして Swift オブジェクト・ストレージが使えます。

更新の詳細

Vault 0.6 は大規模な変更を伴うため、更新する前に様々な理解が必要です。一般的な更新手順だけでなく、バージョン固有の手順もご覧ください。ご注意いただきたいのは、扱っているのは 0.5.x からのバージョンアップです。さらに前のバージョンから更新する場合は、それぞれのリリースに関するブログの投稿をご覧ください。

私たちが推奨するのはいつもの通り、独立した環境でテストした後、更新を試みてください。もし何らかの問題があれば、GitHub の Vault の issue トラッカーVault メーリングリスト にお訊ねください。

それでは、Vault 0.6 をお楽しみください!

原文


【参考訳】Nomad 0.4

02.07.2016  in Nomad using tags HashiCorp , Nomad , translation

概要

6月28日に、HashiCorp から Nomad 0.4 バージョン 0.4 がリリースされました。新しい nomad plan コマンドのサポート、リソース調査機能、Consul との一部機能統合が行われています。HashiCorp の blog にリリースに関する解説記事がありましたので、例によって訳してみました。参考程度にどうぞ。

Nomad 0.4

私たちは Nomad 0.4 をリリースしました。Nomad は分散型の高い可用性を持つクラスタ・マネージャとスケジューラであり、マイクロサービスとバッチ作業の両方に対応する設計です。

Nomad 0.4 に備わっている新機能が焦点を当てているのは、ツール運用面での改良です。主な機能は次の項目です。

  • Nomad Plan
  • ライブ・リソース使用量(Live Resource Utilization)
  • クラスタリングを簡単に(Simpler Clustering)

Nomad Plan

nomad plan を実行して表示されるのは、ジョブに対する変更についてと、Nomad がジョブをクラスタ上に割り当て可能かどうかです。これにより、システムに対してどのような変更を行うかと、ジョブが適切に割り当てられるかを確認できるようにします。

Terraform とは異なり、nomad plan は割り当ての成功を保証しません。nomad plan は変更するリソースを予約(reserve)しません。確認するのは、その時点で割り当てが成功するかです。この情報を元に、作業者は対象となる場所でジョブを実行するかどうか、詳細な情報を得た上で決断できます。

Nomad は宣言型システム(declarative system)です。「何」を実行するか宣言したら、Nomad は「どのように」実行するか決めます。どのサーバ上でジョブを実行するか、いつ実行するかなど、Nomad に対して詳細を伝える必要はありません。これがクラスタ・マネージャにとって重要な所です。たとえば、Nomad はリソースを効率的に使えるようにし、障害時には自動的にワークロードの移行などをします。

一方、マイナス面として、ジョブを発行後の挙動については分かりません。作業者であれば、何点か気に掛けることがあるでしょう。ジョブの実行に十分なリソースがあるだろうか? ジョブを更新するには? 既存のジョブのダウンタイムやローリング・アップデートは? などです。

nomad plan は作業を確かなものにするため、その時点において Nomad が何をするか表示します。次の plan は、ジョブを更新する例です:

$ nomad plan example.nomad
+/- Job: "example"
+/- Task Group: "cache" (3 create/destroy update)
  +/- Task: "redis" (forces create/destroy update)
    +/- Config {
        args[0]: "--port ${NOMAD_PORT_db}"
      + args[1]: "--loglevel verbose"
        command: "redis-server"
    }

Scheduler dry-run:
- All tasks successfully allocated.
- Rolling update, next evaluation will be in 10s.

Job Modify Index: 7

出力はジョブに対する変更を表示します(この例では、コマンドに新しい引数を追加します)。ここで出力されるのは、ジョブの作成/破棄、更新といった処理(タスク)で、どのように変わるかです。

あとは、下の方に「scheduler dry-run」(スケジューラ・ドライ・ラン)と表示があります。ここではジョブが割り当て可能であるのと、ローリング・アップデートは 10 秒間隔のポリシーでデプロイできそうです。

新しいジョブや既存のジョブに対し、nomad plan が使えます。クラスタの状態には変更を加えませんので、安全に実行できます。nomad plan の詳細はドキュメントをご覧ください。

ライブ・リソース使用量(Live Resource Utilization)

Nomad はタスクとノードに割り当てられた実際のリソースを報告できるようになりました。

Nomad 上のすべてのジョブは、どれだけのリソースが必要かの宣言が必須です。リソースとは、CPU、メモリ、ネットワーク等です。通常、処理の要求時点で、どれだけのリソースが必要かを知るのは大変です。これまで、実際に必要なリソース使用量を決めるのは困難でした。Nomad 0.4 からは、ジョブ、タスク、ノードのリソース使用量を簡単に調べられます。

次の例はタスクのリソース使用量を表示します。

$ nomad alloc-status abcd1234
Task: "www"
CPU     Memory MB  Disk MB  IOPS  Addresses
100/250   212/256     300      0

Nomad 0.3 までは、CPU とメモリはジョブで指定した要求値を簡単に表示するだけでした。Nomad 0.4 からは、実際に現在割り当て中の値を表示します。

ノードの状態では、より詳細な情報を表示します。

$ nomad node-status -stats abcd1234
...

Detailed CPU Stats
CPU    = cpu0
User   = 1.03%
System = 0.00%
Idle   = 98.97%

CPU    = cpu1
User   = 1.00%
System = 2.00%
Idle   = 93.00%

Detailed Memory Stats
Total     = 2.1 GB
Available = 1.9 GB
Used      = 227 MB
Free      = 1.4 GB

Detailed Disk Stats
Device         = /dev/mapper/ubuntu--1404--vbox--vg-root
MountPoint     = /
Size           = 41 GB
Used           = 3.4 GB
Available      = 36 GB
Used Percent   = 8.14%
Inodes Percent = 4.94%

これらの情報は常に更新されるため、ジョブの調整作業を行いやすくし、適切な挙動をしていないアプリケーションの発見などに使えます。

クラスタリングを簡単に(Simpler Clustering)

Nomad 0.4 は、クラスタの作成と操作を簡単にするため、2つの重要な変更を行いました。 Consul を使えば、クラスタの作成は自動的です。Nomad サーバとクライアントは、Consul のサービスとヘルスチェックに自動登録されます。Consul デプロイとの統合は、Nomad サーバが自動的にリージョン間を統合するのを意味します!

クラスタの安定性だけでなく、サーバの更新もシンプルになります。Nomad サーバには、サーバとクライアント間をハートビート(heartbeats)を通す一式を備えました。ハートビートを約 30 秒ごとに行い、Nomad サーバがリージョン上で現在把握しているノード情報を提供します。これにより、Nomad サーバはクライアント側の設定を変更しなくても、イミュータブル(訳者注:システムの状態を変えずに)に更新を行えるようにします。

これまで Nomad サーバを更新するには、新しいサーバを準備し、Raft 複製が発生する前に古いものを廃止していました。そして、クライアントは新しいサーバを参照するするよう、設定ファイルを書き換える必要があったのです。この更新手順は厄介であり、間違いやすい傾向がありました。

Nomad 0.4 のサーバ、はクライアントに対して利用可能なサーバ一覧を通知します。つまり、クライアント側の設定を変えなくても、Nomad サーバの入れ替えを可能とします。

まとめ

まだ Nomad は非常に若いプロジェクトです。しかし、導入と成長、そして、Nomad がプロダクションのワークロードを実行する様子はエキサイティングです。Nomad 0.3 は 100 万コンテナのスケーラビリティ をもたらしました。Nomad 0.4 で集中するべく選んだ機能は、操作における信頼性の改善でした。

さらに前進するため、私たちは複数の重要な機能を計画しています。ネイティブな Vault 統合、さらなる Consul 統合などです。正確なロードマップを近々リリースする予定です。

Nomad のサイトに移動し、詳細を学びましょう。

原文



概要

 Docker Engine 1.12 RC1 から、Docker Engine に swarm モードが搭載されています。また、機能として Ingress オーバレイ・ネットワークが標準で利用でき、負荷分散機能も使えます。このトピックでは新しい用語や概念の整理をし、実際のクラスタを作成と、nginx サービスとしてのコンテナを実行するまでの手順を整理します。

「swarm」 は「クラスタ」の意味

 Docker Engine に swarm モードは、従来の Docker Engine のクラスタを管理する Docker Swarm が Docker Engine に機能統合されたものです。これまで Docker Engine のクラスタを作るためには、 Swarm コンテナswarm バイナリをセットアップする必要がありました。ですが、今後は SwarmKit という内蔵機能に統合されているため、追加セットアップなしに docker コマンドでクラスタを管理できます。

 そして、Docker Engine でこのバージョンから Docker Engine のクラスタを swarm と呼びます。swarm は「群れ」の意味があります。そして swarm クラスタを扱うには、Docker Engine の swarm モード(swarm mode) を利用します。

Docker 1.12 RC をセットアップ

 現時点で swarm モードを使えるのは RC (リリース候補)版のみです。そのため、通常のセットアップ方法とは異なります。バイナリは GitHub の releases から入手できます。あるいは、次のコマンドを実行し、自動的に RC 版をセットアップすることもできます( Ubuntu 14.04, 16.04, CentOS 7.2 で動作確認)。

$ curl -fsSL https://test.docker.com/ | sh

 CentOS 7.2 では Docker Engine が自動起動しないため、 systemctl で起動する必要があります。

# systemctl start docker

 起動後の動作確認は、 docker version コマンドを実行します。正常に動作していれば、クライアントとサーバの両方のバージョンを表示できます。

# docker version
Client:
 Version:      1.12.0-rc2
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   906eacd-unsupported
 Built:        Fri Jun 17 21:21:56 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.0-rc2
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   906eacd-unsupported
 Built:        Fri Jun 17 21:21:56 2016
 OS/Arch:      linux/amd64

ノード

 ここでは3台の Docker Engine でクラスタを作成します。

  • node-01 192.168.39.1 … マネージャ・ノード兼ワーカ・ノード
  • node-02 192.168.39.2 … ワーカ・ノード
  • node-03 192.168.39.3 … ワーカ・ノード

 3台のサーバで Docker Engine ( dockerd デーモン )を動かします。このクラスタ内の Docker Engine を、それぞれ swarm の ノード(node) と呼びます。そして、このノードには2つの役割があります。

  1つは マネージャ・ノード(manager node) であり、ここで サービス(service) の期待状態(desired state)を定義します。サービスとは「 nginx コンテナを3つ動作する」といった状態を指します。また、swarm クラスタ全体を管理する docker node <命令> コマンドを処理できるのもマネージャ・ノードです。

 もう1つは ワーカ・ノード(worker node) です。マネージャ・ノードで定義されたサービスがこのワーカ・ノードに送られ、コンテナを実行・停止などの処理を行います。また、ワーカ・ノードは自分の状態をマネージャ・ノードに伝える役割もあります。

 なお、デフォルトではマネージャ・ノードはワーカーノードの役割も兼ねます。オプションの設定で、マネージャのみの役割で動作させることもできます。

サービスとタスクについて

 swarm クラスタ上で何らかのコンテナを実行するには、サービスを定義します。このサービス定義に従って実際にコンテナを起動するのが タスク(task) です。タスクはコンテナの最小スケジューリング単位です。スケジューリングとは、どのノードでどのコンテナを実行するのかを検討し、実際に起動する処理を指します。

 そして、サービスには2種類あります。

  • 複製サービス(replicated service) … マネージャが各ノードに対し、指定した数の複製タスクを作成します。
  • グローバル・サービス(global service) … あるタスクをクラスタ内の全ノード上で実行します。

 複製サービスが適しているのは、ウェブなどのスケールさせる必要があるタスクです。グローバル・サービスは全ノード上で実行しますので、監視やログ収集などのタスク実行に適していると考えられます。

swarm の初期化

 ここからは、実際にクラスタを構築します。swarm モードを使うためには、まず、swarm クラスタの初期化をします。初期化のためには docker swarm init コマンドを使います(init = initialize = 初期化)。 --lissten-addr <ホスト>:<ポート> で、swam マネージャが利用するインターフェースとポート番号を指定します。

$ docker swarm init --listen-addr 192.168.39.1:2377

 swarm クラスタ上のノード一覧を確認するには docker node ls コマンドを使います。

$ docker node ls
ID                           NAME     MEMBERSHIP  STATUS  AVAILABILITY  MANAGER STATUS
dhrbvl6o9xqvprsq2uzq8o9ev *  node-01  Accepted    Ready   Active        Leader

 docker swarm init コマンドを実行した node-01 ノードの情報が表示されます。 MANAGER STATUS の部分に何らかの表示があれば、マネージャとして動作しています。ここでは初めて実行したマネージャのため、 Leader (リーダ)の役割です。

swarm クラスタに他のノードを追加

 次は残りの2台をクラスタに追加します。クラスタに追加するには、 node-02 node-03 の各ノード上で docker swarm join <マネージャ> コマンドを実行します。ここでは、次のコマンドを実行します。

$ docker swarm join 192.168.39.1:2377

 それから、 node-01 上で docker node ls コマンドを実行したら、各ノードが swarm に追加されているのが確認できます。

docker@node-01:~$ docker node ls
ID                           NAME     MEMBERSHIP  STATUS  AVAILABILITY  MANAGER STATUS
6puvbl7tgxislfha5iaha40jm    node-03  Accepted    Ready   Active
9zj16or3durdh5i7c6khlench    node-02  Accepted    Ready   Active
dhrbvl6o9xqvprsq2uzq8o9ev *  node-01  Accepted    Ready   Active        Leader

 この情報はとは別に、クラスタの情報は docker info でも確認できます。

$ docker info
(省略)
Swarm: active
 NodeID: dhrbvl6o9xqvprsq2uzq8o9ev
 IsManager: Yes
 Managers: 1
 Nodes: 3

 マネージャは1つ、ノードが3つあることが分かります。

 これでサービスを実行する準備が整いました。

nginx サービスの定義と実行

 次は nginx コンテナを実行するサービスを定義します。サービスの定義は docker service create コマンドを使います。ここでは web という名前のサービスで(--name web )、コンテナを1つ実行( --replicas 1 )します。また、サービス側のポート 80 をコンテナ内のポート 80 に割り当て( -p 80:80 )します。

$ docker service create --replicas 1 –name web -p 80:80 nginx
f218o6xshkyt7zzxujhnz1a2h

 実行後の文字列 f218o6xshkyt7zzxujhnz1a2h はサービス ID と呼ばれるものです。サービス名かサービス ID を使い、サービスの停止・更新・削除などの操作時に使います。

 そして、サービスの状況を確認するには docker service ls コマンドを使います。

docker@node-01:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
13765buws9fr  web   0/1       nginx

 ここでは REPLICAS (レプリカ)の表示が 0/1 になっているのに注目します。先ほど指定した --replicas 1 とは、タスク(コンテナ)の期待数が 1 でした。しかし、実際には 0 、つまり、まだタスク(としてのコンテナ)が起動しちていない状態です。

 この時、スケジューリング処理が行われています。3つのワーカのうち、どこでタスク(としてのコンテナ)を実行するか決め、その後、 nginx イメージのダウンロードと Docker コンテナを起動します。この状態を確認するには docker service tasks <サービス名> コマンドを実行します。

$ docker service tasks web
ID                         NAME   SERVICE  IMAGE  LAST STATE             DESIRED STATE  NODE
emjve46lgwjx22o6pxpbetfed  web.1  web      nginx  Running About an hour  Running        node-02

 ここでは node-02nginx イメージを使ったコマンドが実行中だと分かります。状況はリアルタイムに変わりますので、 watch コマンドを組みあわせると、状況の監視に便利です(例: watch -n 1 'docker service tasks web' )。

 タスク起動後にサービスの一覧を確認したら、今度は 1/1 に切り替わります。

docker@node-01:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
13765buws9fr  web   1/1       nginx

ingress オーバレイ・ネットワークと負荷分散

 インターネット側など、外部のネットワークからコンテナにアクセスするには、ポート 80 に接続します。接続は、 node-02 の IP アドレス 192.168.39.2 でアクセス可能なだけではありません。swarm モードで動作しているノードであれば、どこからでもアクセス可能です。

 これは、各ノード上では ingress という名前のオーバレイ・ネットワーク(overlay network)が作成されているからです。 docker network ls コマンドを実行し、ノード上の Docker ネットワーク一覧を表示します。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
bbb5e37b01e8        bridge              bridge              local
6550c72b075f        docker_gwbridge     bridge              local
84baeb90cbb2        host                host                local
9i5hmgqr20jh        ingress             overlay             swarm
7ab4c321bbe5        none                null                local

 注目すべきは ingress という名前のネットワークです。これは swarm モードで自動作成されるオーバレイ・ネットワークです。これは複数のノード間がつながっている共有ネットワークです。そして SCOPE には localswam があります。 local はノードの中でのみ有効なネットワーク、 swarm は swarm モードのクラスタで有効なネットワークです。

 そして、 ingress ネットワークの特長として、このネットワーク上で公開しているポートは、どのノードへアクセスがあっても、タスクを実行しているノードに自動ルーティングしてくれます。

 さらに Ingress ネットワークには負荷分散機能も入っています。この負荷分散はタスクに応じて自動的に処理されます。つまり、swarm モードではサービスとして公開しているポートが分かれば、どのノードにアクセスしても、自動的に対象となるタスク(コンテナ)に到達可能です。内部では自動的にタスクの監視を行うため、スケールアップ・スケールダウンによりコンテナが増減しても、外部から内部の状況を意識する必要がなくなります。

 これを応用したら、この Ingress Load Balancing の上にロードバランサやプロキシを置くなり、あるいは DNS ラウンドロビンなどで可用性を高めるサービスが作られるかもしれません。実際には性能面での検証は必要と思われますが、Nginx などリバース・プロキシをたてなくても、良い感じで分散してくれる仕組みは、使いどころがありそうだと感じています。

サービスの更新

 次は、サービスの数を3つに増やします。状態を変更するのは docker service update コマンドです。

$ docker service update --replicas 3 web
web

 サービス一覧を確認したら、期待数が 3 になっているのが分かります。

$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
13765buws9fr  web   2/3       nginx

 タスクの一覧で状況を確認してみます。

$ docker service tasks web
ID                         NAME   SERVICE  IMAGE  LAST STATE           DESIRED STATE  NODE
emjve46lgwjx22o6pxpbetfed  web.1  web      nginx  Running 2 hours      Running        node-02
8owd8swtc99coag9evqz4j0dx  web.2  web      nginx  Running 8 seconds    Running        node-01
6z7svrkbpjyfp7gme4r1c2qh4  web.3  web      nginx  Preparing 8 seconds  Running        node-03

 ここでは3台のノードに分散して nginx コンテナを起動しようとしています。 node-01 node-02Running (稼働中)と分かりますが、 node-03Preparing (準備中)です。そのため、 docker service lsREPLICAS2/3 でした。

 もうしばらくしてから docker service ls を実行したら、最終的に3つのタスクが実行中になります。

$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
13765buws9fr  web   3/3       nginx

 なお3つのノードに分散してスケジューリングされたのは、デフォルトでは Spread (スプレッド)というコンテナをノードに分散配置するストラテジが適用されているからです。

 次はまたタスクの数を減らしましょう。

$ docker service update --replicas 1 web
web
$ docker service tasks web
ID                         NAME   SERVICE  IMAGE  LAST STATE         DESIRED STATE  NODE
6z7svrkbpjyfp7gme4r1c2qh4  web.3  web      nginx  Running 4 minutes  Running        node-03

 このように、再び docker service update コマンドを実行するだけで、スケールダウンも可能です。

 最後にサービスを削除するには docker service rm コマンドを使います。

$ docker service rm web
web
$ docker service ls
ID  NAME  REPLICAS  IMAGE  COMMAND

 これでサービスの削除完了です。

 このように、docker service コマンドでサービスを定義したら、 docker コマンドを使わなくても、swarm クラスタ上でコンテナの起動・更新・停止が可能になります。

 なお、この検証を行った Docker 1.12RC2 はリリース候補版のため、実際の Docker 1.12 では仕様が変わる可能性もありますのでご了承ください。現段階では開発中ですが、色々と評価してみる分には、面白いのではないかと思います。

参考



概要

DockerCon 2016 のキーノートで、新しい Docker 1.12 の機能に関する説明がありました。また、その発表に合わせるように blog への投稿 “Docker 1.12: Now with Built-in Orchestration!” もありました。例によって日本語訳を作成しましたので、内容把握の参考程度にどうぞ。

図版は省略しました。原文をおたどりください。なお、自分の整理用に以前のバージョンの比較用画像を作りましたので、こちらも参考程度にどうぞ。

Docker 1.12: ついにオーケストレーションを組み込み!

 3年前、Docker は難解な Linux カーネル技術をコンテナ化(containerization)と呼ぶシンプルで誰もが利用しやすいものにしました。今日、私たちはコンテナのオーケストレーションも同じ様にします。

 単一ホスト上にコンテナを個々にデプロイしている状態から、複雑な複数のコンテナを多くのマシンにデプロイするスタイルに移行するために、コンテナ・オーケストレーション(container orchestration)が求められています。そのためにはインフラから独立した分散プラットフォームを必要とします。つまりアプリケーションのライフタイム(存続期間)全てにわたってオンラインを維持し、ハードウェア障害やソフトウェア更新時も生存し続けるようにします。今日のオーケストレーションは、3年前のコンテナ化と同じステージです。ここには2つの選択肢があります。1つは、あなたが技術の専門部隊と共に、複雑なアドホック・システムを作り上げること。そうでなければ、多くの専門家がいる会社を信頼するかです。専門家は、あなたの代わりに全てのハードウェア、サービス、サポート、ソフトウェアを購入し、全てを管理するのです。この状態を表す言葉があります。ロックイン(lock-in)と呼ばれます。

 Docker ユーザは他のオプションを受け入れ可能かどうか、私たちとずっと共有してきました。皆さんが必要なのは、オーケストレーションを誰もが使えるプラットフォームであり、ロックインがないものです。コンテナ・オーケストレーションは実行が簡単であり、よりポータブルであり、安全、弾力的(resilient)、そしてより速いことです。たとえ、プラットフォームに組み込まれていたとしてもです。

 Docker 1.12 から Docker Engine のコアに機能を追加し始めました。機能とは、マルチ・ホストとマルチ・コンテナのオーケストレーションを簡単にします。私たちは新しい API オブジェクトを追加しました。サービス(Service)とノード(Node)です。これは swarm と呼ばれる Docker Engine のグループ上で、アプリケーションのデプロイと管理に Docker API を使います。Docker 1.12 があれば、Docker をオーケストレートする最も良い方法こそが Docker なのです!

<図>

 Docker 1.2 は4つの原則をベースにしています。

  • シンプルでありながら強力(Simple Yet Powerful) - 最近の分散アプリケーションにおいて、オーケストレーションは中核部分です。そして、その中心にあたるものは、私たちが Docker Engine のコアへシームレスに組み込みました。私たちの手法はオーケストレーションでも私たちのコンテナに対する哲学を適用することです。哲学とは、セットアップ不要であり、シンプルな概念を学ぶのは最小限であり、そして「とにかく動く」(it just work)というユーザ経験です。

  • 弾力性(Resilient) - マシンは常に落ちます。最近のシステムではこれらの障害を予測すべきであり、恒常的に存在し続け、アプリケーションのダウンタイム(停止時間)なしに適用できることです。それが単一障害点(single-point-of-failure)をゼロにする設計が必要な理由です。

  • 安全(Secure) - デフォルトで安全であるべきです。強力なセキュリティの防壁のためには、証明書の生成(certificate generation)、そのために PKI の理解が必要だったのですが、不要になるべきです。しかし、高度なユーザであれば、これまで通り全ての証明書への署名と発行を制御・監査し続けるべきでしょう。

  • オプション機能と後方互換性 - 100 万人ものユーザがいるため、Docker Engine の後方互換性維持は必須です。新しい全ての機能はオプションであり、使わなければオーバヘッド(メモリや CPU に対する)を被る心配はありません。Docker Engine のオーケストレーションは私たちのプラットフォームの内蔵電池(batteries included)ですが、交換可能にしています。そのため、ユーザはサードパーティ製のオーケストレータを Docker Engine 上で使い続けられます。

 それでは Docker 1.12 で動く新しい機能を見ていきましょう。

1つの分散構築ブロックで Swarm を作る

 始めるためには swarm (訳者注:「群れ」の意味で、Docker Engine のクラスタを指す言葉)を作成します。swarm は Engine を自己組織化(self-organizing)でき、自己修復グループ(self-healing group)します。ノードの立ち上げ(bootstrap)は次のようにシンプルです。

docker swarm init

 このフードの下では Raft コンセンサス・グループ(合意グループ)のノードを1つ作成しています。この1つめのノードはマネージャ(manager)の役割(role)を持っています。つまり、コマンドを受け付け、タスクをスケジュールします。swarm にさらにノードを追加したら、デフォルトではワーカ(worker)になります。ワーカとはマネージャが命令したコンテナを単純に実行します。オプションで、他にもマネージャ・ノードを追加可能です。マネージャ・ノードは Raft コンセンサス・グループの一部になり得ます。私たちは最適化した Raft ストアを使います。スケジューリング性能を高速にするため、メモリを直接読み込み処理します。

サービスの作成とスケール

 docker run でコンテナを1つ実行しておけば、 Engine の swarm (クラスタ)上で docker service を使いプロセスの複製、分散、負荷分散を始められます。

docker service create --name frontend --replicas 5 -p 80:80/tcp nginx:latest

 このコマンドは nginx コンテナの期待状態(desired state)が5つであると宣言します。swarm 上のノードのポート 80 へのアクセスは、内部ロード・バランサ・サービスを通して、いずれかのコンテナに到達します。この動作の仕組みは Linux IPVS を使ったカーネル内のレイヤ4マルチ・プロトコル・ロードバランサです。これは Linux カーネルに 15 年以上も前からあるものです。IPVS ルーティング・パケットはカーネル内であり、swarm のルーティングは高性能なコンテナ検出負荷分散(container-aware load-balancing)をもたらします。

 サービスの作成時、オプションで複製サービス(replicated services)かグローバル・サービス(global services)を作成できます。複製サービスとは、利用可能なホスト上に広くコンテナを多く展開する意味です。対照的にグローバル・サービスとは、sawrm 上の各ホストに同じコンテナを1つずつスケジュールします。

 それでは Docker が提供する弾力性について考えて見ましょう。Swarm モードは engine を自己組織化(self organizing)と自己修復(self healing)ができるようにします。つまり、engine は自分が定義した通りにアプリケーションに注意を払います。そのためには、継続的なチェックや、engine がどこかに行った時は調整を担います。たとえば、nginx インスタンスを実行中のマシンの電源コードを抜いても、別のノードで新しいコンテナが復活します。ネットワーク・スイッチから swarm クラスタ上の半分のマシンを引き抜いても、他のノードが引き継ぎ、残ったノードでコンテナを再分配します。更新時には、既存のサービスを変更するため、柔軟に再デプロイ(re-deploy)できます。swarm 上のコンテナはローリング(rolling)もしくは並列に更新できます。

 100 インスタンスにスケールアップしたいですか? 次のように簡単です。

docker service scale frontend=100

 典型的な2ティア(web+db)アプリケーションは次のように作成できます。

docker network create -d overlay mynet
docker service create --name frontend --replicas 5 -p 80:80/tcp \
    --network mynet mywebapp
docker service create --name redis --network mynet redis:latest

 これはこのアプリケーションの基本アーキテクチャです。

<図>

セキュリティ

 Docker 1.12 の中心にある原則は、設定しなくてもデフォルトで安全であり、Docker プラットフォームをすぐに使えるように作ることです。管理者が度々直面する主な課題の1つは、プロダクションで実行中のアプリケーションを安全にデプロイすることです。Docker 1.12 では管理者がデモ用クラスタを確実にセットアップできるようにします。つまり、安全なプロダクションのクラスタをセットアップできるでしょう。

 セキュリティは後から締め直せるようなものではありません。それゆえ、 Docker 1.12 では難しい設定を行わなくても、 swarm 上の全てのノードが相互に TLS 認証が可能であり、認証し、暗号化通信を可能とするのです。

 1つめのマネージャを起動したら、Docker Engine は新しい認証機関(CA; Certificate Authority)を作成し、自分用の初期証明書セットを作成します。この初期ステップ以降は、swarm に参加する各ノードは、ランダムに生成した ID で自動的に新しい証明書を作成し、swarm (マネージャかワーカ)の各ロールに適用します。これらの証明書は swarm 上にノードが参加している間中、ノードを安全に暗号化して認識するために使います。そしてまた、マネージャが安全にタスクやその他の更新を伝えるためにも使います。

<図>

 TLS 採用の最も大きな障壁の1つは、公開鍵基盤(PKI; Public Key Infrastructure)の作成・設定・管理に必要なのが大変な点です。Docker 1.12 では全てが安全にセットアップされているだけでなく、設定済みです。そして、もう1つ TLS 証明書を扱う上で最もつらい証明書の更新も自動化しました。

 フードの下では、swarm に参加する各ノードは定期的に証明書を確実に更新します。そのため、潜在的な流出や、設定の妥協はもうありません。証明証の入れ替え(rotate)設定は、ユーザによって変更できます。最小間隔は30分です。

 自分の認証機関(Certificated Authority)を使いたい場合は、私たちは外部 CA モード(external-CA mode)もサポートしています。これは swarm にノードがリモート URL から参加する時、マネージャはノードの証明書署名要求(CSR; Certificate Signing Request)を単純に信頼しようとします。

Bundle(バンドル)

 Docker 1.12 は Distributed Application Bundle という新しいファイル形式を導入しました( experimental ビルドのみ)。Bundle (荷物のあつまり、束の意味)はフルスタック・アプリケーション上のサービスに集中した新しい抽象化です。

 Docker Bundle ファイルは宣言型のサービス・セットの仕様書です。仕様には次の命令があります。

  • 何のイメージのリビジョンを実行するか
  • 何の名前のネットワークを作成するか
  • どのようにこれらサービスのコンテナを、どのネットワーク上で実行するか

 Bundle ファイルは完全にポータブルであり、ソフトウェア・デリバリのパイプラインにおいて、アーティファクト(訳者注:最終成果物の意味)の完全なデプロイをもたらします。これは、複数コンテナを Docker アプリとして記述した全てを移動し、バージョン化できるからです。

 Bundle ファイルの仕様はシンプルかつオープンです。必要であれば自分が欲しいバンドルを作成できます。使い始めるには、Docker Compose は bundle ファイルの作成に実験的に対応しました。そして Docker 1.12 の swarm モードを有効化したら、bundle ファイルをデプロイできます。

 Bundle は開発者のノート PC から CI を通したプロダクションに、複数サービスのアプリケーションを効率的に移動する仕組みです。実験的機能であり、私たちはコミュニティからのフィードバックをお待ちしています。

Dokcer 1.12 のフードの下

 フードの下を見ますと、Docker 1.12 では他にも多くの面白い技術を使っています。ノード間通信には gRPC を使っており、これにより HTTP/2 の多重接続やヘッダ圧縮のような利点を得られます。私たちのデータ構造は protobufs の効果的な移植です、感謝します。

 Docker 1.12 のリソースについては、他もご覧ください。

原文


open the next

20.06.2016  in site using tags Hugo

Hey world!

Close the world, open the next...

旧サイト の情報整理のため、サイトの移行と情報整理をします。技術系の情報は、今後こちらに集約する予定です。とはいえ、予定は未定。