目次


Hyperledger Fabric サンプル・アプリのセキュリティーをカスタム CA で保護し、Kubernetes クラスターにデプロイする

Red Hat Enterprise Linux プラットフォーム入門ガイド

Comments

このチュートリアルでは、Red Hat Enterprise Linux (RHEL) 上の Kubernetes クラスターに Hyperledger Fabric ネットワークをデプロイし、ネットワーク・ノード間の重要な通信に対して Transport Layer Security (TLS) を有効にする方法を説明します。RHEL をターゲット・ディストリビューションとして選んだわけは、RHEL はエンタープライズ・クラスの Linux ディストビューションであり、さまざまなサポート・サービスを利用できることから、企業の環境内で本番システムを実行するためによく使われているためです。

このチュートリアルの手順に従うと、スケールダウンしたバージョンの本番ネットワークをローカルの開発環境内でシミュレーションできます。そのために必須となるのは、クラスター内での通信を、実際の公開鍵基盤 (PKI) で署名された証明書によって保護することです。また、データと情報の転送は TLS の暗号化を使用して保護します。このチュートリアルでは TLS の構成方法に加え、PKI から取得した各種のデジタル証明書を Fabric ブロックチェーン・ネットワークに組み込む方法も説明します。

学習の目的

  • 単一ノードの Kubernetes クラスターを Red Hat Enterprise Linux 上にセットアップし、マスター・ノートとワーカー・ノードを同じ 1 つの物理サーバー・ノード上で実行する
  • Hyperledger Fabric ブロックチェーン・ネットワークをデプロイする
  • デフォルトのクラスター構成を変更し、Fabric ネットワーク・コンポーネント間の通信用のカスタム TLS を統合する
  • 単純なアプリケーションをデプロイしてネットワークと TSL が適切に構成されていることをテストする
  • Kubernetes 上で実行されている Hyperledger Fabric アプリケーションに対して実際の公開鍵基盤 (PKI) から発行されたデジタル証明書を使って構成手順を再現する

前提条件

以下のソフトウェアがインストールされている必要があります。このチュートリアルで、インストール手順を説明します。

以下のトピックに関する基本的知識があると、このチュートリアルを最大限活用できます。

  • Linux (できれば Red Hat Enterprise Linux) の管理
  • 公開鍵暗号方式
  • Hyperledger Fabric および関連するツール (crypto-gen、configtxgen、configtxlator など)

慌てないでください!これらのトピックの専門家である必要はありません。このチュートリアルではテクノロジーを理解していることが重要となるステップに進む場合、その前に、該当するテクノロジーのさまざまな側面について情報を提供します。準備ができたら、さっそく手順に取り掛かってください!

所要時間

このチュートリアルの所要時間は約 4 時間です。

はじめに

最新式のマイクロサービス・アプリケーションを本番環境で実行するには、Kubernetes などのコンテナー・オーケストレーション・テクノロジーが不可欠です。コンテナー・オーケストレーション・テクノロジーを使用すれば、コンテナー化されたアプリケーションのデプロイ、接続、スケーリング、そして本番ネットワーク内での有効化といった力仕事の部分を任せることができます。

アプリケーションを一連の個別のサービスに分解し、それらのサービスを相互運用する場合、外部のクライアントやサービスからのアクセスだけでなく、サービス間の通信もセキュリティーで保護することが重要となります。ソリューションの内部関係者であろうが外部関係者であろうが、あらゆる関係者間の通信をセキュリティーで保護する一般的な手法は、周知の認証局 (CA) によって署名された証明書を導入することです。

多くの場合、概念検証アプリケーションやパイロット・アプリケーションに、始めからビジネス対応の Blockchain-as-a-Service プラットフォームを使用することはありません。こうしたアプリケーションは、開発環境用のサンプル構成を使用して、最初は独立した Fabric ネットワーク・デプロイメントとして実行します。このようなソリューションを本番環境に移行する際は、選択したコンテナー・オーケストレーション・プラットフォーム上で、Fabric ネットワークの実装をセキュアに運用することが第一の懸念事項となります。

インターネット上では Kubernetes に関する豊富なドキュメントが見つかります。Transport Layer Security に関しては、それ以上に豊富なドキュメントが見つかりますが、Kubernetes クラスターに Hyperledger Fabric ブロックチェーン・アプリケーション用のカスタム TLS を構成する方法についての情報はほとんど見当たりません。この問題に直面したのは、最近、ローカル用に設計したありきたりな Hyperledger デプロイメントを本番対応の QoS 環境に移植しようとしたときのことです。この場合の移行方法をステップ・バイ・ステップで説明するレシピが見つからなかったことが、私たちがこのチュートリアルを作成する動機となりました。私たちが行った移行プロセスでの経験とそこから学んだ教訓を、皆さんにシェアしたいと思います。

チュートリアルで使用するファイル

このチュートリアルでは手順を説明するだけでなく、この手順を再現するために必要なすべてのファイルをリポジトリー https://github.com/hyp0th3rmi4/hlf-k8s-custom-crypto に用意してあります。

このリポジトリーには、Kubernetes マニフェストと、サンプル Fabric ネットワーク (2 つの組織と組織ごとの 2 つの CA と 2 つのピアからなるネットワーク) をセットアップするために必要な構成ファイルが格納されています。これらのファイルがあれば、クラスター化された Kafka ベースの発注者ノードを使用して、ネットワーク・ノード間の通信にトランスポート層セキュリティーを適用するサンプル・ネットワークを再現できます。

一般に、非本番 Fabric ネットワークではノード・アイデンティーとトランスポート層セキュリティーに、組織 CA が発行したデジタル証明書を使用します。組織 CA 自体が使用するのは自己署名ルート証明書です。いずれの証明書にしても、通常は Fabric で提供している暗号化ツールによって生成されたものを使用します。けれども本番のシナリオでは、周知の PKI によって直接署名された証明書、あるいは PKI の信頼連鎖で署名された証明書を使用することになります。このチュートリアルでは、Fabric ネットワークの組織 CA によって発行され署名された証明書ではなく、本番環境で使用する実際の証明書を統合する方法も説明します。

サンプル・アプリケーション

このチュートリアルでは、ネットワーク構成を検証するためのテスト・アプリケーションとして、完全なコマンド・ライン・アプリケーション (e2e_cli) を使用します。このチュートリアルで明かにするのは、Kubernetes のセットアップに関する課題と、本番デプロイメントと同じような環境内で Fabric アプリケーションを実行する際の課題です。Fabric のあらゆる基礎を説明しながらも、複雑すぎることのないこのサンプル・アプリケーションは、皆さんが独自のアプリケーションをセットアップする際のテストとして役立ちます。

チュートリアルで説明するサンプル・アプリケーションのセットアップ方法は、皆さん独自のアプリケーションに適用できます。

「オズの魔法使い」と Kubernetes の救いの手

「トト、私たちはもうカンサスにはいないという気がするの」。

映画「オズの魔法使い」でのこの有名な台詞は、多くの人々がいつもと異なる場所や状況に置かれているときの戸惑いを説明するための例えとして用いられることがよくあります。映画の中のドロシーと同じように、開発環境を後にして本番環境に足を踏み入れると戸惑いを感じる開発者は少なくないでしょう。本番環境では、スケーラビリティー、可用性、アプリケーションのモニタリング、追跡可能性、そしてセキュリティーに関してまったく異なる一連の要件に対処しなければなりません。マイクロサービスの時代となっている今、この問題をさらに悪化させるのは、調整して接続し、連動させなければならないコンポーネントの数が増えるという点です。この点は、ほとんどのアプリケーションに当てはまりますが、Hyperledger をベースに構築されるアプリケーションには間違いなく当てはまります。テスト用のネットワークを用意するだけでも、デプロイしなければならない必要最小限のコンテナーは 1 つだけではないからです。

通常の単一ファイルからなる Docker Compose ベースのデプロイメント (例えば、Yeasy で提供しているデプロイメント) では、もはや必要を満たさないため、本番環境でも通用する手法が必要となります。そこで救いの手を差し伸べるのが、Kubernetes です。

Kubernetes は、異種混合のインフラストラクチャーから構成されたクラスター上でもコンテナー化されたアプリケーションを実行できるようにするためのプラットフォームです。Kubernetes では追加の設定なしでローリング・アップデート・サービスとスケールアップ/ダウン・サービスをサポートするだけでなく、トラフィックを制御してさまざまなバージョンのサービスにルーティングできます。さらに、高可用性対応のセットアップもサポートしています。Kubernetes ではユーザーがデプロイメントをきめ細かく制御できるよう、コンテナー・エンジン (Docker、rkt、その他) の動作を補完してサポートする一連のシステム・コンポーネントを揃えています。この複雑さがユーザーに強力な制御力と柔軟性を与えるものの、基本概念を知らなければ圧倒されてしまうでしょう。l図 1 に、Kubernetes クラスターのアーキテクチャー概要を示します。このチュートリアルでは、皆さんが次のステップを理解できるよう、重要な概念を簡単に説明します。

図 1. Kubernetes のアーキテクチャー

Kubernetes で採用しているのは、マスター・スレーブ/ワーカー・アーキテクチャーです。このアーキテクチャーでは、マスターがクラスターのアクティビティーを調整してその状態を管理し、ユーザー定義の要件とクラスターの内部状態に基づいてスレーブ/ワーカー・ノード全体でワークロードをスケジューリングします。マスターの機能は、さまざまなノードに分散可能な一連のサービスによって実装されます。マスターと同じく、スレーブ/ワーカー・ノードも一連のサービスで構成されます (図 1 を参照)。

上述の主要なコンポーネントに加え、Kubernetes がクラスター内のコンテナーの実行をオーケストレーションするために使用する抽象概念もあります。このチュートリアルで特に関係してくる抽象概念について、以下に説明します。

  • ポッド: ポッドは、Kubernetes が使用する最小単位のデプロイメントであり、密接に結合された (1 つ以上の) コンテナーをホストするように意図されています。メイン・コンテナーはアプリケーション・サービスを表します。サポート・コンテナーはメイン・コンテナーのライフサイクルおよび他のサービスへの接続をモニタリングするために使用されます。ポッドはステートレスなデプロイメント単位として意図されているため、ポッドを終了した後は、クラスターの任意のノード上での実行を再スケジューリングできます。
  • サービス: 通常、サービスはデプロイされたアプリケーションにとって意味のあるエンティティーです。このことから、サービスのスコープは同じ機能を実行する複数のノードにまたがる場合があります。Kubernetes の世界でのサービスは、ポッド内にデプロイされた対応する機能へのエントリー・ポイントです。サービスは、そのマッピング先デプロイメント全体でロード・バランサーの役割を果たします。
  • デプロイメント: ポッドと Kubernetes サービスのマッピングは、デプロイメントによって指定されます。サービスはノード・ポートへのマッピングを定義する一方、そのサービスで必要となるコンテナーに関する情報とデプロイするレプリカの数は、対応するデプロイメントに格納されます。
  • ラベル: ラベルは、Kubernetes が追加の情報をクラスター内で使用する任意のエンティティーに付加するために使用するメカニズムです。ラベルはクラスターの機能を実装するために使用されることから、エンド・ユーザーに公開されます。エンド・ユーザーはラベルを使用して、サービス、デプロイメント、またはその他のエンティティーに関連付けられたメタデータをエンリッチします。例えば、サービス定義と、対応するデプロイメントと組み合わせるには、ラベルを使用します。
  • プロキシー: ポッド内にデプロイされたサービスをアーキテクチャーの他のコンポーネントに使用可能にする上で、プロキシーは基本的な役割を果たします。プロキシーの機能は、図 1 に示されている kube-proxy コンポーネントによって実装されます。このコンポーネントはネットワークをホスト・レベルでサブネット化し、サービスを定義するマニフェストに従ってノード外部にサービスを公開します。
  • 名前空間: 名前空間は、1 つの物理クラスター内で複数の仮想クラスターを作成するためのメカニズムです。この抽象概念は、サービスのスコープと可視性に関する境界にもなります。具体的には、ある名前空間内にデプロイされているすべてのサービスは、その名前空間内の他のすべてのサービスにアクセスできます。Kubernetes にはデフォルトで、defaultkube-systemkube-public という 3 つの名前空間を使用できるようになっています。1 つ目はデフォルトの名前空間です。2 つ目は、システム・サービスをデプロイするために使用します。3 つ目は、すべてのクラスターから可視でアクセス可能であるようにするリソースをデプロイするために使用する特殊な名前空間です。
  • ドメイン・ネーム・サービス (DNS): クラスター・ベースの基本的な名前解決機能の他に、Kubernates では DNS による名前解決も統合できるようになっています。DNS は基本的に、他のアプリケーション・レベルのサービスと同じようにクラスターにデプロイされるサービスです。他のサービスとの唯一の違いは、DNS はシステム名前空間にデプロイされて、Kubernetes システム・コンポーネントの一部に特権的にアクセスできることです。

アーキテクチャーのすべてのコンポーネントについて説明することは、このチュートリアルの目的ではありません。包括的な Kubernetes の概要については、このリンク先の Kubernetes のドキュメントまたは Digital Ocean でホストされているチュートリアルをご覧ください。

1. Kubernetes を RHEL 上で稼働させる

最初に必要となる作業は、Kubernetes ベースのアプリケーションを実行する環境を準備することです。私たちはターゲット・ディストリビューションとして RHEL を選びました。そのわけは、Linux ディストビューションの中で、企業の環境内で本番システムを実行するのに最もよく使われているディストビューションだからです。このチュートリアルでは、Red Hat Enterprise Linux をベースに、単一ノードの Kubernetes クラスターを完全に機能させることを目標とします。

Red Hat Enterprise Linux には、コンテナー・オーケストレーションのデフォルト・ソリューションとして OpenShift が用意されています。OpenShift は、Red Hat Enterprise Linux フレームワークのコア機能に、ネットワーク、マルチテナンシー、イメージ・レジストリー、ロギング、モニタリングに関するサービスを追加する、Kubernetes ベースのソリューションです。したがって、OpenShift プラットフォームは Kubernetes との完全な互換性を備えており、Kubernetes クラスター用に定義されたサービスとデプロイメントはいずれも透過的に OpenShift 上にデプロイできます。OpenShift はオープンソース・プラットフォームとしても、年中無休のサポートを利用できるエンタープライズ・オファリングとしても利用できます。OpenShift が用意されていることから、RHEL ディストリビューションには Kubernetes と Docker が用意されていません。この 2 つは手作業でインストールする必要があります。

Kubernetes クラスターを完全に機能させるためにインストールしなければならない必須のコンポーネントは、Docker Enterprise Edition と Kubernetes の 2 つです。

a. Docker Enterprise Edition をインストールする

  1. システム上に以前の Docker バージョンがインストールされている場合は、すべて削除します。
    sudo yum remove docker \
                     docker-client \
                     docker-client-latest \
                     docker-common \
                     docker-latest \
                     docker-latest-logrotate \
                     docker-logrotate \
                     docker-selinux \
                     docker-engine-selinux \
                     docker-engine \
                     docker-ce
  2. インストールに使用する Docker EE リポジトリーの場所を特定します。 それには、Docker Store のオンライン・プロファイルにアクセスして、利用可能なすべてのトライアルとサブスクリプションのリストを表示します。
    • https://store.docker.com/my-content にログインします。
    • 「Docker Enterprise Edition for Red Hat Enterprise Linux」「Setup (セットアップ)」をクリックします。
    • 「Copy and paste this URL to download your edition (この URL をコピー・アンド・ペーストしてエディションをダウンロードする)」を使用して URL をコピーします。
    次のコードでは、この URL を <DOCKER_REPO_URL> として表しています。以下の手順に従って、上記のリポジトリーから Docker EE をダウンロードする環境を構成します。
    # remove existing docker repositories
    sudo rm /etc/yum.repos.d/docker*.repo
    
    # store the url to the docker repository as a YUM variable
    export DOCKER_URL="<DOCKER_REPO_URL>"
    sudo -E sh -c 'echo "$DOCKER_URL/rhel" > /etc/yum/vars/dockerurl'
    
    # store the OS version string as a YUM variable. We assume here that RHEL
    # version is 7. You can also use a more specific version.
    sudo -E sh -c 'echo "7" > /etc/yum/vars/dockerosversion'
    
    # install the additional packages required by the devicemapper storage driver
    sudo yum install yum-utils \
                     device-mapper-persistent-data \
                     lvm2
    
    # enable the extras RHEL repository. This provides access to the
    # container-selinux package required by docker-ee
    sudo yum-config-manager --enable rhel-7-server-extras-rpms
    
    # add the Docker EE stable repository
    sudo -E yum-config-manager --add-repo "$DOCKER_URL/rhel/docker-ee.repo"
  3. Docker Enterprise Edition をインストールします。
    sudo yum install docker-ee
    sudo systemctl start docker

    GPG 鍵を受け入れるよう求めるプロンプトが出される場合があります。そのフィンガープリントが以下に示す値と一致することを確認してください。一致する場合は、GPG 鍵を受け入れます。これで、Docker EE のインストールが完了します。

    フィンガープリント: 77FE DA13 1A83 1D29 A418 D3E8 99E5 FF2E 7668 2BC9

  4. Docker インストールが機能しているかどうかテストします。これは、hello-world コンテナーを実行することで確認できます。
    sudo docker run hello-world

    Docker ランタイムが正常にインストールされていれば、次の出力が表示されます。

    Pulling from library/hello-world
    9bb5a5d4561a: Pull complete
    Digest:sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d59bde73361e77
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64).
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/engine/userguide/

Docker EE を Red Hat Enterprise Linux 上にインストールする方法について詳しくは、このリンク先の Docker のドキュメントをご覧ください。

b. Kubernetes をインストールする

注: Kubernetes のリリースは頻繁に行われるため、以下の手順が無効になるのは時間の問題です。この手順で問題が発生した場合は、以下に示すリンク先にある公式の Kubernetes ドキュメントでインストール手順を確認してください。

  1. Kubernetes の次のベース・パッケージをインストールします。
    • kubelet: ポッドとコンテナー・デプロイメントの作成などといったノード管理の基本的な機能を実行する、必須の Kubernetes サービスです。
    • kubeadm: このパッケージは、Kubernetes 適合性テストを通じて確立されたベスト・プラクティスに従って、単一ノードの Kubernetes クラスターをブートします。
    • kubectl: このパッケージは、Kubernetes クラスターとのやり取りに使用するコマンド・ライン・ツールをインストールします。
    以下のスクリプトは、YUM に Kubernetes リポジトリーを構成して、必須のパッケージをインストールします。
    # configure YUM to access the Kubernetes repository
    sudo cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    EOF
    
    # disable SELinux, you need to do this in order to allow containers to access
    # the file system, this is needed for instance by pod networks
    sudo setenforce 0
    
    # install the packages
    sudo yum install -y kubelet kubeadm kubectl
    
    # enable the kubelet service
    sudo systemctl enable kubelet
    sudo systemctl start kubelet
  2. Docker の cgroup ドライバーを構成します。コンテナー・ランタイムとして Docker EE を使用していることから、kubelet が Docker と同じ cgroup ドライバーを使用するようにしなければなりません。次のコマンドを使用すると、kubelet と Docker が使用しているドライバーが同じであるかどうかを確認できます。
    docker info | grep -i cgroup
    cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    cgroup ドライバーが一致していない場合、Docker で使用するドライバーと一致するように kubelet の構成を変更します。変更する必要があるフラグは、--cgroup-driver です。このフラグがすでに設定されている場合は、次のように変更します。
    sudo sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    構成を更新した後、kubelet を再起動する必要があります。
    sudo systemctl daemon-reload
    sudo systemctl restart kubelet
  3. クラスターをブートして、単一ノード内で実行するように構成します。ここで活躍するのが、kubeadm です。次のコマンドを実行するだけで、クラスターをブートできます。
    sudo kubeadm init --pod-network-cidr=192.168.0.16

    このコマンドに追加されているフラグ --pod-network-cidr は、後で追加するネットワーク・プラグインに必要なものです。このフラグの値は、インストールする特定のネットワーク・プラグインによって異なります。このチュートリアルでは、Calico CNI をインストールします。
  4. Kubernetes の構成をホーム・ディレクトリーにコピーします。この手順により、root 以外のユーザー (現在のユーザー) がクラスター上にサービスをデプロイできるようになります。
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  5. ネットワーク・アドオンをインストールします。Kubernetes では複数のネットワーキング・プラグインをサポートしています。このチュートリアルでは Calico CNI プラグインを使用します。このプラグインの説明については、このリンク先のクイックスタート・ガイドをご覧ください。
    # install the etcd service...
    kubectl apply -f https://docs.projectcalico.org/v3.2/getting-started/kubernetes/installation/hosted/etcd.yaml
    
    # install the role-based access control (RBAC) roles...
    kubectl apply -f https://docs.projectcalico.org/v3.2/getting-started/kubernetes/installation/rbac.yaml
    
    # install the role-based access control (RBAC) roles...
    kubectl apply -f https://docs.projectcalico.org/v3.2/getting-started/kubernetes/installation/hosted/calico.yaml

    インストールが正常に完了したことを確認するには、次のコマンドを入力します。
    kubectl get pods --all-namespaces

    -- インストールが正常に完了していれば、次のような出力が表示されます。
    NAMESPACE    NAME                                READY  STATUS   RESTARTS  AGE
    kube-system  calico-etcd-x2482                   1/1    Running  0         2m
    kube-system  calico-kube-controllers-6f8d4-tgb   1/1    Running  0         2m
    kube-system  calico-node-24h85                   2/2    Running  0         2m
    kube-system  etcd-jbaker-virtualbox              1/1    Running  0         6m
    kube-system  kube-apiserver                      1/1    Running  0         6m
    kube-system  kube-controller-manager             1/1    Running  0         6m
    kube-system  kube-dns-545bc4bfd4-67qqp           3/3    Running  0         5m
    kube-system  kube-proxy-8fzp2                    1/1    Running  0         5m
    kube-system  kube-scheduler                      1/1    Running  0         5m
  6. マスター・ノードに適用される制限を削除します。デフォルトでは、Kubernetes はマスター・ノード上でポッドをスケジューリングすることを許可しません。単一ノードのクラスターを実行するには、この制限を削除する必要があります。それには、次のコマンドを実行してマスター・ノードからテイントを削除します。
    kubectl taint nodes –all node-role.kubernetes.io/master-

    このコマンドが正常に実行されると、次のメッセージが表示されます。
    node “<your-hostname>” untainted

    クラスターにノードがあることを確認するには、次のコマンドを実行します。
    kubectl get nodes

    このコマンドから返されるテーブルには、1 つのエンティティーが示されていなければなりません。
  7. Kubernetes インストールをテストします。
    kubectl run my-nginx --image=nginx --replicas=2 --port=80

    上記のコマンドにより、2 つのポッド上で NginX Web サーバーを実行するデプロイメントが作成され、ポート 80 上でサービスが公開されます。コマンドが正常に実行されると、以下のように 1 つのデプロイメントと実行中の 2 つのポッドが示されます。
    $ kubectl get deployments
    NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    my-nginx   2         2         2            2           15s
    $ kubectl get pods
    NAME                       READY     STATUS        RESTARTS   AGE
    my-nginx-568fcc5c7-2p22n   1/1       Running       0          20s
    my-nginx-568fcc5c7-d6j6x   1/1       Running       0          20s

    テスト・デプロイメントを削除するには、次のコマンドを実行します。
    kubectl delete deployment my-nginx

kubeadm を使用して Kubernetes クラスターをセットアップする方法について詳しくは、このリンク先の Kubernetes のドキュメントをご覧ください。

2. Hyperledger Fabric をインストールし、Kubernetes 用に構成する

このチュートリアルを作成している時点で Hyperledger Fabric バージョン 1.1.0 が一般公開されていることから、このバージョンを使用することにしましたが、今後のリリースにも、ここで説明する手法を適用することで Kubernetes 用に構成できます。

a. チュートリアルで使用するファイルと Hyperledger Fabric をダウンロードする

「チュートリアルで使用するファイル」のセクションで特定した Git リポジトリーをダウンロードすると、Fabric ネットワークを実行するために必要なすべてのコード・オブジェクトが揃います。以下の一連のコマンドを実行して、リポジトリーを複製し、作業ディレクトリーを設定し、Fabric 1.1.0 Docker イメージを取得してください。

git clone https://github.com/hyp0th3rmi4/hlf-k8s-custom-crypto
cp -r hlf-k8s-custom-crypto/* /home/hlbcadmin/Downloads/mysolution/fabric-e2e-custom/
cd /home/hlbcadmin/Downloads/mysolution/fabric-e2e-custom/
./download-dockerimages.sh -c x86_64-1.1.0 -f x86_64-1.1.0

b. Kubernetes 用の Hyperledger Fabric マニフェストを作成する

Hyperledger Fabric には、事前構成された Docker Compose ファイルが同梱されています。これらのファイルは、Docker を実行中のローカル・マシン上でブロックチェーン・ネットワークを起動するために使用できます。同じネットワークを Kubernetes 上で実行するには、Docker Compose ファイルに対応する Kubernetes マニフェストを生成する必要があります。このチュートリアルでは、Hyperledger Fabric ディストリビューションでサンプルとして用意されている、完全なコマンド・ライン・インターフェース構成を使用しました。

kompose コマンド・ライン・ツールを使用してマニフェストを生成すると、自動的に変換が適用されます。あるいは、このプロセスを手作業で行うこともできます。Docker Compose ファイル内で記述されているサービスのそれぞれについて、サービスデプロイメントの 2 つを作成する必要があります。この 2 つの成果物は、selector ラベルによって関連付けられます。以下のコード・リストに、fabric-zookeeper0 コンポーネントを、Kubernetes で必要となる、対応するサービスおよびデプロイメント・マニフェストに変換する例が示されています。

# fabric-zookeeper0-service.yaml

apiVersion: v1
kind: Service
metadata:
  annotations:
    kompose.cmd: ./kompose convert -f docker-compose-e2e.yaml
    kompose.version: 1.12.0 (0ab07be)
  creationTimestamp: null
  labels:
    io.kompose.service: fabric-zookeeper0
  name: fabric-zookeeper0
spec:
  ports:
  - name: "2181"
    port: 2181
    targetPort: 2181
  - name: "2888"
    port: 2888
    targetPort: 2888
  - name: "3888"
    port: 3888
    targetPort: 3888
  selector:
    io.kompose.service: fabric-zookeeper0
status:
  loadBalancer: {}


# fabric-zookeeper0-deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: ./kompose convert -f docker-compose-e2e.yaml
    kompose.version: 1.12.0 (0ab07be)
  creationTimestamp: null
  labels:
    io.kompose.service: fabric-zookeeper0
  name: fabric-zookeeper0
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        io.kompose.service: fabric-zookeeper0
    spec:
      containers:
      - env:
        - name: ZOO_MY_ID
          value: "1"
        - name: ZOO_SERVERS
          value: server.1=0.0.0.0:2888:3888 server.2=zookeeper1.kopernik.ibm.org:2888:3888 server.3=zookeeper2.kopernik.ibm.org:2888:3888
        image: hyperledger/fabric-zookeeper
        name: zookeeper0
        ports:
        - containerPort: 2181
        - containerPort: 2888
        - containerPort: 3888
        resources: {}
      dnsConfig:
        options:
          - name: ndots

変換に使用する Docker Compose ファイルは、docker-compose-e2e.yaml です。このファイルは、チュートリアルに付属のものとして、ダウンロードできるよう用意しておきました。このファイル内で定義されているネットワークは、次の要素からなります。

  • 2 つの組織と、組織ごとの 2 つのピア
  • 2 つの MSP (組織ごとに 1 つ)
  • 1 つの発注者
  • レジャーを格納する、CouchDb ベースの 1 つのパーシスタンス層 (ピアごとに 1 つ、合計 4 つのサーバー)
  • 4 ノードからなる 1 つの Kafka クラスター
  • 3 ノードからなる 1 つの ZooKeeper クラスター

リファレンス構成を完全に変換すると、次の成果物が生成されます。これらの成果物は git リポジトリー内に格納されています。

  • ZooKeeper クラスター・コンポーネント用の fabric-zookeeper<N>-service.yamlfabric-zookeeper<N>-deployment.yaml
  • Kafka クラスター・コンポーネント用の fabric-kafka<N>-service.yamlfabric-kafka<N>-deployment.yaml
  • MSP 用の fabric-ca1.yamlfabric-ca2.yaml (サービスとデプロイメント)
  • 発注者用の fabric-orderer.yaml (サービスとデプロイメント)
  • ピア用の fabric-peer<N>-org<M>.yaml (サービスとデプロイメント)
  • ピアのレジャー・データベース用の fabric-couchdb.yaml (サービスとデプロイメント)
  • fabric CLI 用の fabric-cli-job.yamlfabric-cli-deployment.yaml

利便性を図るため、Kubernetes では複数のマニフェストを 1 つのファイルにまとめることも、個別に維持することもできるようになっています。このチュートリアルでは、ブロックチェーン・ネットワークのコア・コンポーネント (MSP、発注者、ピア) 用のサービス・マニフェストとデプロイメント・マニフェストをグループ化する一方、ZooKeeper コンポーネントと Kafka コンポーネント用の対応するマニフェストを個別に維持します。また、パーシスタンス層 (CouchDb サーバー) のすべてのマニフェストも 1 つに結合します。

c. Docker ネットワークと Kubernetes ネットワークを接続する

Docker とネイティブに連動するように意図されたセットアップから Kubernetes マニフェストを生成したので、これらのマニフェストは Docker ネットワークに依存してホストを解決します。このセットアップを Kubernetes 内で実行するとなると、同じコンテナーを別のネットワーク上で実行する際の問題に突き当たります。つまり、ホスト名解決の手順は、そのままの状態では機能しません。このことが問題になるのは、ピアが実行するチェーンコード・コンテナーの場合です。チェーンコード・コンテナーは (Kubernetes ではなく) 引き続き Docker エンジンを使用して作成されますが、ネットワーク内の他のすべてのコンテナーは Kubernetes によってデプロイされているためです。

Fabric アーキテクチャーにおいては、ピアは隔離されたコンテナー環境内でスマート・コントラクトを実行します。ピアはそのために、Docker デーモンの Unix ソケット・インターフェースを使用して直接コンテナーをデプロイします。このチェーンコード・コンテナーをピアが管理できるようにするためには、ピアにアクセスするための手段がコンテナーに必要となります。けれども、Kubernetes 上で実行されているピアを Docker ネットワークに対して DNS クエリーで照会しても、そのクエリーを解決することはできません。したがって、チェーンコード・コンテナーに Kubernetes クラスターの DNS サーバーの IP アドレスを構成し、コンテナーがピアを呼び出せるようにする必要があります。それには、ネットワーク内のすべてのピアについて、環境変数 CORE_VM_DOCKER_HOSTCONFIG_DNS を指定し、チェーンコード・コンテナーの起動時に、この環境変数によって DNS サーバーの IP アドレスをコンテナーに注入できるようにします。以下のコード・スニペットに、ネットワーク内にあるピアのうちの 1 つの構成を示します (参照先: fabric-peer0-org1.yaml)。

    …
      - env:
        - name: CORE_VM_DOCKER_HOSTCONFIG_DNS
          value: "10.96.0.10" # this must be replaced with actual IP of the
                              # Kubernetes DNS service
    …

以下のコードには、Kubernetes DNS サーバーの IP アドレスを抽出する方法が示されています。

$ kubectl get svc kube-dns -n kube-system

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP   18d

上述の手法は、ネットワーク内の対応するコンポーネントを確実に検出してコンポーネント間の名前を解決できるように Docker コンテナーの仮想オーバーレイ・ネットワークと Kubernetes ネットワークの間でトラフィックをブリッジする貴重な方法となります。この方法では、ピアおよびチェーンコード・コンポーネントは隔離された状態を維持しながらも、コンテナー・オーケストレーション手法やランタイム環境に依存しないネットワーク接続で互いにつなげることができます。ピアとチェーンコード間のアプリケーション通信プロトコルの特性を踏まえると、それぞれのライフサイクルは緊密に連動します。例えば、サーバー・サイドのコンポーネントが停止されると、そのコンポーネントに接続または関連付けられているクライアント・サイドのコンポーネントが適切にシャットダウンされ、孤立することはありません。このようなネットワーク間のブリッジは、チェーンコード・コンテナーをピアから起動する Docker-in-Docker 手法の脆弱性を軽減することにもなります。

3. カスタム・トランスポート層セキュリティーを有効にする

このセクションでは、Fabric ネットワークを構成するさまざまなコンポーネント間の通信に対してトランスポート層セキュリティーを有効にする方法に焦点を当てます。前述のとおり、このチュートリアルを作成しようと決めたきっかけは、スケールダウンしたバージョンの本番環境をローカルの開発環境に再現しなければならなかったためです。そのためには、クラスター内の通信を実際の PKI でセキュリティー保護することが不可欠のステップとなります。

a. Hyperledger Fabric TLS の基本的なセットアップ

Hyperledger Fabric には、Fabric を構成するサービス (発注者、ピア、認証局) の一部として TLS を有効にする機能が組みこまれています。デフォルトでは、これらのコンポーネントはそれぞれの TLS 設定を、対応するイメージ内に組み込まれた構成ファイルから取得します。ピアと発注者のデフォルト構成の設定は、Hyperledger Fabric リポジトリーの sampleconfig フォルダーに格納されているファイル内で確認できます。

  • ピア・ノード (hyperledger/fabric-peer) のデフォルト構成は、core.yaml ファイル内で設定されています。
  • ピア・ノード (hyperledger/fabric-orderer) のデフォルト構成は、orderer.yaml ファイル内で設定されています。

これらの設定をオーバーライドするには、変更する構成設定に環境変数をマッピングし、その環境変数をコンテナーの起動時に渡します。例えばピア・コンテナーには、次の環境変数を定義できます。

  • CORE_PEER_TLS_ENABLED (=true|false)
  • CORE_PEER_TLS_CERT_FILE: ピアに使用する証明書ファイルのパス
  • CORE_PEER_TLS_KEY_FILE: 証明書に関連付けられている鍵ファイルのパス
  • CORE_PEER_TLS_ROOTCERT_FILE: ルート CA 証明書ファイルのパス

同様に、発注者の TLS 設定も、次の環境変数によって制御できます。

  • ORDERER_GENERAL_TLS_ENABLED (=true|false)
  • ORDERER_GENERAL_TLS_CERTIFICATE: 発注者に使用する証明書ファイルのパス
  • ORDERER_GENERAL_TLS_PRIVATEKEY: 証明書に関連付けられている鍵ファイルのパス
  • ORDERER_GENERAL_TLS_ROOTCAS: ルート CA 証明書ファイルのパス

認証局については、デフォルトの設定を格納した静的ファイルが使用されるのではなく、CA コンテナーの起動時に動的に構成が生成されます。これらの設定は、次の環境変数によって変更できます。

  • FABRIC_CA_TLS_ENABLED (=true|false)
  • FABRIC_CA_TLS_CERTFILE: CA に使用する証明書ファイルのパス
  • FABRIC_CA_TLS_KEYFILE: 証明書に関連付けられている鍵ファイルのパス

以上の設定を使用して、対応する証明書内で使用されている完全修飾ドメイン名にコンテナー名を適切にマッピングすれば、TLS でセキュリティー保護された Fabric コンポーネントを完全に構成できます。トランスポート層セキュリティーを使用するように構成済みのネットワーク・ファイルは、作業ディレクトリー fabric-e2e-custom 内にあります。

b. PKI 証明書を入手する

Hyperledger Fabric には、cryptogen というデフォルトのユーティリティーが同梱されています。このユーティリティーを使用して、Fabric ネットワークに必要となるすべての証明書を作成できます。このユーティリティーで作成される自己署名証明書は、実際の PLI によって署名されたカスタム証明書で置き換えることができます。このチュートリアルでは IBM 内部の認証局によってプロビジョニングされた証明書を使用しますが、Digital Ocean、Verisign、Symantec などの PKI で取得した証明書を使用する場合も、基本的に手順は同じです。

カスタム TLS を使用するには、その前に、必要な証明書の数と証明書を保管する場所を把握しておく必要があります。これは突き詰めると、cryptogen ツールの動作を理解すること、そして (cryptogen によって生成される暗号ファイルの構成をプロビジョニング済みカスタム暗号ファイルの構成と一貫させる場合は) その動作を対応する実際の PKI 証明書のプロビジョニングと一致させることを意味します。cryptogen ツールは、ネットワーク内のすべてのアイデンティティーの暗号ファイルを作成します。必要になる証明書の数と証明書に関連付ける秘密鍵は、このツールを制御する crypto-config.yaml によって決定されます。サンプル・アプリケーションの crypto-config.yaml ファイルは、fabric-e2e-custom 作業ディレクトリーのルートにあります。

OrdererOrgs:
  - Name: Orderer
    Domain: kopernik.ibm.org
    CA:
         Country: US
         Province: California
         Locality: San Francisco
    Specs:
      - Hostname: orderer

PeerOrgs:
  - Name: Org1
    Domain: org1.kopernik.ibm.org
    EnableNodeOUs: true
    CA:
         Country: US
         Province: California
         Locality: San Francisco
    Template:
      Count: 2
    Users:
      Count: 1

  - Name: Org2
    Domain: org2.kopernik.ibm.org
    EnableNodeOUs: true
    CA:
         Country: US
         Province: California
         Locality: San Francisco
    Template:
      Count: 2
    Users:
      Count: 1

ここで使用する構成は、Hyperledger Fabric のデフォルト・セットアップに少々変更を加えたものです。デフォルトの動作に合わせて、2 つの組織と、それとは別に発注者ノードの組織を 1 つ作成します。これらの組織のそれぞれに個別の認証局 (CA) があり、各 CA が、その組織内のユーザーとシステムのアイデンティティーを表す証明書を管理します。組織の名前を変更するだけで、組織とプロビジョニングする証明書とを対応させることができます。

crypto-config.yaml ファイルでは、各組織内に作成するピア・ノードの数も指定しています。数を変更するには、組織内に作成するピアの最大数を定義する Template.Count パラメーターを使用します。ホスト名テンプレートの仕様を変更しなければ、名前は fabric-peer<N>-<org> の形式で作成されます。ここで、N0 から、Template.Count パラメーターの値 - 1 までの範囲となります。Template セクションと同様に、User セクションは各組織に作成するアイデンティティーの数を制御します。このセットアップでは、次のアイデンティティーが作成されます。

  • 発注者ノード
  • 発注者組織の CA と管理者
  • ピア組織ごとに 2 つのピア・ノード、1 つの CA、1 つの管理者、1 つのユーザー

組織レベルで使用されるアイデンティティーの他に、Hyperledger Fabric には x509 証明書の形式でのアイデンティティーも必要です。これは、TLS を実装するネットワーク接続を管理するために使用されます。

上記の一連の暗号アイデンティティーは、メンバーシップ・サービス・プロバイダー (MSP) 構成の一部です。MSP は Fabric コンポーネントとして、署名の生成および検証ステップが伴なう、ネットワーク参加メンバーのアイデンティティーの定義、検証、認証に対処します。MSP の情報は、図 2 に示すフォルダー構造でわかりやすく整理されています。

図 2. 基本的な MSP フォルダー構造

このフォルダー構造からわかるように、組織レベルのアイデンティティーとネットワーク・レベルのアイデンティティーの両方に中間証明書が存在します。ルート証明書に直接依存するのではなく、使用される証明書には中間証明書によって署名が付けられるという仕組みです。

図 3. 署名ファイルが格納された MSP フォルダー

署名ファイル内の情報は Hyperledger Fabric ネットワークを構成するさまざまなコンポーネントによって使用されるため、これらのファイル内に機密情報 (つまり、秘密鍵) は一切含まれません。トランザクションの署名または承認を担当するエンティティーには、さらに keystoresignercerts という 2 つのフォルダーが追加で生成されます。これらのフォルダーには、秘密鍵と、関連する署名用の証明書が格納されます。この 2 つのフォルダーはノード (発注者またはピア) とユーザーにとって重要です。図 3 に、これらのエンティティーに応じて更新されたフォルダー構造を示します。

図 4. cryptogen で生成されたフォルダー構造

cryptogen は Hyperledger Fabric ネットワークで使用する証明書を自動的にセットアップする際に、これらすべての情報を生成します。cryptogen は図 4 に示されているフォルダー構造を生成するために、前に記載した crypto-config.yaml ファイルを参照します。msp フォルダーに、前述の構造が反映されています。太字で示されているフォルダーには、keystore フォルダーと signercerts フォルダーも含まれています。これらのフォルダーに格納される情報は、トランザクションを承認するノード、そして送信されたトランザクションに署名するユーザーが使用します。

図 4 には、ノードごと、およびユーザーごとに tls フォルダーが存在することも示されています。このフォルダーに、さまざまなエンティティーが TLS 接続を確立するために使用する暗号ファイルが格納されます。

要約すると、crypto-config.yaml 内で指定された構成に従って、cryptogen は表 1 に記載する証明書を作成します。

表 1. cryptogen によって生成される暗号ファイル

この表には、あらゆる Hyperledger Fabric ネットワークが動作するために必要な一連の証明書 (「Blockchain」行) と、TLS で通信をセキュリティー保護するために必要な証明書 (「TLS」行) が記載されています。

実際の PKI を使用してネットワーク通信のセキュリティーを確保することにした場合、組織、組織のコンポーネント、ユーザーそれぞれの証明書を、同じ PKI を使用してプロビジョニングできます。ネットワーク通信を保護するために使用する証明書そのものを、アプリケーション層でもそのまま使用できるため、プロビジョニングする必要がある証明書の合計数が減ることになります。表 2 に、プロビジョニングする必要がある証明書と、各証明書とフォルダー構造内での証明書のマッピングを記載します。

表 2. 証明書と cryptogen によって生成されるフォルダー構造との主要なマッピング

このマッピング・プロセスは scripts/script.sh フォルダー内にあるスクリプトによって自動化できます。このスクリプトは、ibm-files ソース・ディレクトリー内に格納されているすべての証明書を、crypto-config ディレクトリー・ツリー内の該当するパスにコピーします。

c. TLS を Kubernetes 上で機能させる

前に説明した構成設定だけでは、Kubernetes セットアップを機能させることはできません。Docker Compose ネットワークと Kubernetes ネットワークのそれぞれに実装されているサービスの名前解決には、根本的な違いがいくつかあるためです。

デフォルトでは、Kubernetes はサービス・ディスカバリー機能をアドオンに任せます。したがって、Kubernetes のベース・インストールにはサービスが互いを検索してやり取りする機能が備わっていませんが、これは大きな問題ではありません。この機能を提供するいくつかのアドオンを使用できるためです。そのうち、最もよく使われているのは、KubeDNS という DNS アドオンです。アドオンをクラスター内にデプロイするには、アドオン・マネージャ―を使用できます。あるいは、以下のように手作業でサービスをデプロイすることもできます。

sudo kubectl create -f <pointer-to-kube-dns.yaml>

KubeDNS は、kube-system 名前空間内にデプロイされ、クラスター全体のサービスの名前解決を担当するとともに、アップストリームのネーム・サーバーを介して外部 DNS 名を解決します。サービス・マニフェストがデプロイされると、Kubernetes は <service-name>.<namespace>.cluster.local 形式の完全修飾名を持つクラスター内に、サービスに対応する DNS エントリーを作成します。したがって、同じ名前空間内にデプロイされているどのサービスからでも、そのサービスを <service-name> として参照できます。また、同じクラスターに含まれる別の名前空間内にデプロイされているサービスからは、この完全修飾名を使用して該当するサービスを参照できます。サービスの完全修飾名は自動的に導出されるため、Kubernetes ではサービス名にドットを含めることはできません。

KubeDNS をインストールすると、これがサービスを検索するメカニズムとなりますが、使用する証明書の完全修飾名に対応する「ドット付き名前」をサービスに割り当てるまでの自由は与えられません。これが原因で、極めて単純な Fabric ネットワークでさえも、追加の設定を行わなければ機能させることができません。example.org ドメイン内のさまざまなサービスは完全修飾名を使用しているため、コンポーネント間で相互接続を確立しようとすると、サービス名とサービスに対応する証明書の名前が一致しないことから、接続は失敗します。

この問題に対処するには、次の手法を試すことができます。

  • サービス名と一致する名前の証明書を使用する
  • 証明書の Subject Alternative Name (SAN) フィールドを使用して、サービスの名前を格納する

いずれにしても、とりわけ魅力的な手法というわけではありません。最初の手法を用いると、適切なドメイン名で実際の PKI を使用することができなくなります。一方、2 番目の手法では、クラスター内のサービスのデプロイメントに関する詳細を証明書に追加することになってしまいます。

d. CoreDNS による解決策

上述の手法よりも強力なサービス名の解決手法となるのは、CoreDNS を統合するアドオンです。この非常に柔軟なドメイン・ネーム・サーバーの実装をいくつかのプラグインで拡張すれば、DNS 管理者はドメイン名の解決とその管理に関するあらゆる操作を行えるようになります。

CoreDNS を構成するには、Corefile を使用します。Corefile では複数の DNS サーバーを定義して、そのそれぞれに対応するプラグインを有効化して構成することができます。以下に、構成ファイルの一例を示します。

.:53 {
   log
   errors
   health
   rewrite {
      …
   }
   kubernetes … {
      …
   }
   prometheus :9153
   proxy . /etc/resolv.conf
   cache 30
}

上記のリストに示されている DNS サーバーは、ポート 53 に応答するあらゆるドメインの名前解決を管理します。このサーバー構成ブロックによって有効化されるプラグインには、logerrorshealthprometheusproxycacherewritekubernetes があります。このうち、log、errors、health は名前からその機能が明らかにわかりますが、他のプラグインについては、多少説明するほうがよさそうです。prometheus は、指標を公開するためのプラグインです。このプラグインを構成して、CoreDNS の指標と、/metrics エンドポイントを介してこのプロトコルをサポートする他のすべてのプラグインの指標を同じノード上のポート 9153 で公開できるようにします。proxy プラグインは、ローカル・ファイル /etc/resolv.conf を使用して DNS 名を解決するように構成されます。cache プラグインは、DNS エントリーを 30 秒間保持するように構成されます。

rewrite は、ここで役立つ興味深い CoreDNS 機能を提供するプラグインです。このプラグインを使用してドメイン名の変換マッピングを作成すれば、KubeDNS で発生する名前不一致の問題を解決することができます。ドメイン名を作成し直すことで、サービスを証明書と一致する完全修飾名で参照し、そのサービスの名前をクラスターで使用する完全修飾名に変換することができます。例えば、サービスに期待される名前を次のように作成し直すとします。

rewrite name peer0.org1.kopernik.ibm.org fabric-peer0-org1.default.svc.cluster.local

この構成により、クエリーの変換が可能になりますが、レスポンスは相変わらずサービスの元の名前に基づいています。そのため、サービス名とサービスに関連付けられている証明書の名前との競合が発生します。完全な透明性を確保するためには、返された DNS 名を変換し、元のサービス名の IP にマッピングされている名前に戻す必要があります。それには、DNS レスポンスを変換してグループ化するディレクティブを追加します。

rewrite {
  name peer0.org1.kopernik.ibm.org fabric-peer0-org1.default.svc.cluster.local
  answer fabric-peer0-org1.default.svc.cluster.local peer0.org1.kopernik.ibm.org
}

CoreDNS が Kubernetes Kubernetes プラグインを構成する必要もあります。このプラグインで、クラスター内での DNS 解決リクエストの処理方法を CoreDNS に指示します。この使用ケースに必要なセットアップは以下のとおりです。

 kubernetes kopernik.ibm.org in-addr.arpa ip6.arpa {
    pods insecure
    upstream
    fallthrough in-addr.arpa ip6.arpa
 }

CoreDNS のアドオンは、Kubernetes ディストリビューション内の「dns」カテゴリーに含まれる一連のアドオンの中にあります。CoreDNS をインストールするには、次のコマンドを使用できます。

# only needed if kube-dns was previously installed
sudo kubectl remove kube-dns

sudo kubectl create -f <pointer-to-coredns.yaml>

注: Kubernetes リリース 1.11 以降、kubeadm で作成されるクラスターはサービス・ディスカバリーにデフォルトで CoreDNS を使用するようになっています。したがって、リリース 1.11 以降を使用する場合、上記の構成は必要ありません。

CoreDNS を構成するには、デプロイしたサービスに Corefile を渡す必要があります。それには、サービスの ConfigMap を定義してクラスターにデプロイします。ConfigMap は基本的に Key-Value 型ストアであり、Kubernetes が使用するあらゆる抽象概念に関連付けることができます。

ConfigMap に Corefile 構成を含め、その構成で、デプロイ済み Fabric ネットワークを接続可能にするために必要な名前変換テーブルを指定します。この ConfigMap は、fabric-e2e-custom フォルダー内の coredns-config.yaml ファイルを見ると確認できます。CoreDNS の構成をデプロイするには、次のコマンドを実行します。

sudo kubectl create -f coredns-config.yaml

このコマンドは、前にデプロイされていた構成マッピングをサービスで置き換え、CoreDNS が透過的にドメイン名を変換できるようにします。

4. ネットワークとサンプル・アプリケーションを起動する

作業フォルダー内にある次のスクリプトを実行してください。このスクリプトでネットワークをデプロイして一連のテストを実行することにより、ネットワークが機能しているかどうかを確認できます。

./start-fabric.sh

このスクリプトによって、次のものが作成されます。

  • Kafka クラスター用のサービスとデプロイメント
  • ZooKeeper クラスター用のサービスとデプロイメント
  • ピアの CouchDb データベース用のサービスとデプロイメント
  • 発注者サービス用の 1 つのサービスと 1 つのデプロイメント
  • すべてのピア用のサービスとデプロイメント
  • CLI コンテナー用の 1 つのサービスと 1 つのデプロイメント

CLI コンテナーは一連のテストを実行し、Hyperledger Fabric ネットワークが正常に機能していることを検証します。具体的には、このコンテナーは次の処理を試みます。

  • 発注者サービスにアクセスする
  • mychannel という名前のチャネルを作成する
  • すべてのピアをチャネルに参加させる
  • テスト・チェーンコードをインストールしてインスタンス化する
  • クエリーを実行してトランザクションを呼び出す

テストが正常に実行されると、スクリプトの実行終了時に次のメッセージが出力されます。

================== All GOOD, End-2-End execution completed ===================

これらのテストの詳細については、fabric-e2e-custom/scripts フォルダー内にある script.sh bash ファイルを参照してください。このファイルは、CLI コンテナーのメイン・エントリー・ポイントです。

これで、Hyperledger Fabric を Kubernetes クラスター上にデプロイし、ネットワークが正常に構成されていることを確認できました。

まとめ

このチュートリアルでは、Red Hat Linux Enterprise 上に単一ノードの Kubernetes クラスターをセットアップし、そのクラスターに Hyperledger Fabric をデプロイする方法を説明しました。また、デフォルトのクラスター構成 (具体的にはネットワーク層と DNS 構成) を変更してカスタム TLS を統合する方法も説明しました。クラスターで実際の PKI を使用できるようにするためには、この構成変更が必須の要件となります。完全に機能するセットアップのデモンストレーションとして、Hyperledger Fabric で提供される完全なコマンド・ライン・アプリケーションをデプロイしました。かなり単純なものとは言え、このアプリケーションは TLS 構成をテストする基本的な機能のすべてを備えています。

このチュートリアルで説明した構成手順を繰り返せば、Kubernetes 上で実行される Hyperledger Fabric アプリケーション用の実際の PKI をサポートすることができます。


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing
ArticleID=1066213
ArticleTitle=Hyperledger Fabric サンプル・アプリのセキュリティーをカスタム CA で保護し、Kubernetes クラスターにデプロイする
publish-date=07042019