第2章 Kubernetes によるコンテナーのオーケストレーション
2.1. 概要
Kubernetes は、Docker コンテナーのオーケストレーションおよび管理を行うためのツールです。以下の手順では、単一システムの Kubernetes サンドボックスをセットアップします。
- Kubernetes で、2 つのコンテナーおよび yaml ファイルを使用し、コンテナーをデプロイする。
- Kubernetes でコンテナーを管理する。
この手順では、Kubernetes を実際に使用し、その機能を学習するためのサンドボックスをセットアップします。この手順では、通常は別々の Kubernetes Master システムや複数の Kubernetes Node システムにあるサービスが単一システムで実行されます。
2.2. Kubernetes について
Docker はコンテナーフォーマットを定義し、個々のコンテナーを構築し、管理しますが、オーケストレーションツールは一連のコンテナーをデプロイし、管理するために必要です。Kubernetes は Docker コンテナーのオーケストレーションを行うためのツールです。必要なコンテナーイメージを構築した後に、Kubernetes Master を使用して Pod に 1 つ以上のコンテナーをデプロイすることができます。Master はその Pod のコンテナーを、コンテナーが実行される Kubernetes Node にプッシュします。
たとえば、Kubernetes Master および Node はどちらも同じコンピューターにあり、そのコンピューターは RHEL 7 Server または RHEL 7 Atomic Host のいずれかであるとします。Kubernetes は Kubenetes Master および Node の機能を実装するために一連サービスデーモンに依存します。Kubernetes Master および Node については以下を理解しておく必要があります。
- Master: Kubernetes Master では、API 呼び出しを Kubernets クラスターの Pod、レプリケーションコントローラー、サービス、ノードその他のコンポーネントを制御するサービスに指定します。通常これらの呼び出しは、kubectl コマンドを実行して行われます。コンテナーは Master から Node 上で実行されるようにデプロイされます。
- Node: Node はコンテナーのランタイム環境を提供するシステムです。
Pod の定義は設定ファイル (yaml または json 形式) に保存されます。以下の手順を使用して、単一の RHEL 7 または RHEL Atomic システムをセットアップし、これを Kubernetes Master および Node として設定し、yaml ファイルを使用して Pod に各コンテナーを定義し、それらのコンテナーを Kubernetes を使用してデプロイします (kubectl コマンド)。
2.3. Kubernetes Pod からのコンテナーの実行
Docker コンテナーを構築し、Kubernetes を使用してオーケストレーションを行うには RHEL 7 または RHEL Atomic システムが必要です。Kubernetes Master および Node システムには、異なるサービスデーモンのセットが必要です。以下の手順では、両方のサービスデーモンのセットが同じシステムで実行されます。
コンテナー、システムおよびサービスを配置したら、kubectl コマンドを使用し、それらのコンテナーが Kubernetes Node (この場合はローカルシステム) で実行されるようにデプロイします。
以下にその手順を示します。
2.3.1. Kubernetes で Docker コンテナーをデプロイするためのセットアップ
Kubernetes を準備するには、RHEL 7 または RHEL Atomic をインストールし、firewalld を無効にしてから 2 つのコンテナーを取得する必要があります。
RHEL 7 または RHEL Atomic システムのインストール: この Kubernetes サンドボックスシステムについては、まず RHEL 7 または RHEL Atomic システムをインストールし、システムのサブスクライブを実行してから、Docker サービスのインストールおよび起動を行います。基本的な RHEL または RHEL Atomic システムをセットアップして Kubernetes で使用する方法の詳細は、以下を参照してください。
Get Started with Docker Formatted Container Images on Red Hat Systems (Docker フォーマットのコンテナーイメージの使用方法)
Kubernetes のインストール: RHEL 7 システムの場合は、kubernetes および etcd パッケージをインストールします。これにより、kubernetes-node および kubernetes-master パッケージも取得できます (これらのパッケージは RHEL Atomic にすでにインストールされています)。
# yum install kubernetes etcd
firewalld の無効化: RHEL 7 ホストを使用している場合は firewalld サービスが無効にされていることを確認します (firewalld サービスは Atomic Host にはインストールされていません)。RHEL 7 では以下を入力して firewalld サービスを無効にし、これを停止します。
# systemctl disable firewalld # systemctl stop firewalld
Docker コンテナーの取得: RHEL Atomic Host のスタートガイドの指示に従って以下の 2 つのコンテナーを構築し、それらのコンテナーのイメージを両方のノードで利用できるようにします (つまり、いずれかのノードで docker images コマンドを入力する際に 2 つのイメージが表示されるようにします)。
コンテナーの構築およびテストを実行した後は、停止します (docker stop mydbforweb および docker stop mywebwithdb を実行)。
2.3.2. Kubernetes の起動
Kubernetes Master および Node サービスはどちらもローカルシステム上で実行されるため、Kubernetes 設定ファイルを変更する必要はありません。Master および Node サービスはローカルホストで相互を参照し、サービスはローカルホストでのみ利用可能になります。
apiserver ファイルの設定: デフォルトで kube-apiserver サービスの許可制御機能を使用するには、Pod を起動するすべてのユーザー用にアカウントをセットアップする必要があります。これにより、Kubernetes プロバイダーは、ユーザーアカウント別に使用を追跡し、制限することができます。この一体型の例では、/etc/kubernetes/apiserver ファイルを開き、KUBE_ADMISSION_CONTROL 値を変更して --admission_control オプションから "ServiceAccount" を削除することでこの機能を無効にすることができます。以下の行は、元の行 (コメントアウトされた行) および ServiceAccount が削除された新規の行を示しています (これらの 2 つの行は折り返されますが、2 行に分割されているように表示される場合もあります)。
# KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota" KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
Kubernetes Master サービスデーモンの起動: Kubernetes Master に関連付けられたいくつかのサービスを起動する必要があります。
# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done
Kubernetes Node サービスデーモンの起動: Kubernetes Node に関連付けられたいくつかのサービスを起動する必要があります。
# for SERVICES in docker kube-proxy.service kubelet.service; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done
サービスの確認: ss コマンドを実行して、サービスが実行されているポートを確認します。
# ss -tulnp | grep -E "(kube)|(etcd)"
etcd サービスのテスト: 以下のように curl コマンドを使用して etcd サービスを確認します。
# curl -s -L http://localhost:2379/version {"etcdserver":"2.1.1","etcdcluster":"2.1.0"}
注意: RHEL Atomic Host 7.1.4 以降では、etcd ユーティリティーはポート 2379 を使用します。古いバージョンの RHEL Atomic Host を実行している場合は、上記のコマンドの 2379 を 4001 に置き換えます。
2.3.3. Kubernetes によるコンテナー Pod の起動
ローカルシステムで Master および Node サービスを実行し、2 つのコンテナーイメージを配置したら、Kubernetes Pod を使用してコンテナーを起動できます。以下はいくつかの注意点です。
- 複数の Pod: 単一の Pod で複数のコンテナーを起動できますが、それらのコンテナーを別々の Pod に配置すると、各コンテナーは他のコンテナーを起動することなく、複数のインスタンスを必要に応じて複製できます。
- Kubernetes サービス: この手順では、データベースおよび Web サーバーの Pod 用に Kubernetes サービスを定義し、コンテナーが Kubernetes からそれらのサービスを見つけられるようにします。データベースおよび Web サーバーは、ターゲット Pod が実行されている IP アドレス、ポート番号、またはノードを認識しない場合でも相互を識別できます。
以下の手順は、2 つの Pod を起動し、テストする方法について説明しています。
重要: yaml ファイルのインデントを維持することは重要です。yaml ファイルのスペースは、フォーマットを整理された状態に保つために使用されます (構造を維持するための波括弧などの文字は不要です)。
データベース Kubernetes サービスの作成: db-service.yaml ファイルを作成して、データベースサービスを Kubernetes に提供する Pod を特定します。
Kubernetes: apiVersion: v1 kind: Service metadata: labels: name: db name: db-service namespace: default spec: ports: - port: 3306 selector: name: db
データベースサーバーのレプリケーションコントローラーファイルの作成: データベースサーバーの Pod をデプロイするために使用する db-rc.yaml ファイルを作成します。以下を設定します。
kind: "ReplicationController" apiVersion: "v1" metadata: name: "db-controller" spec: replicas: 1 selector: name: "db" template: spec: containers: - name: "db" image: "dbforweb" ports: - containerPort: 3306 metadata: labels: name: "db" selectorname: "db" labels: name: "db"
Web サーバーの Kubernetes サービスファイルの作成: Web サーバーの Pod をデプロイするために使用する webserver-service.yaml ファイルを作成します。以下を設定します。
Kubernetes: apiVersion: v1 kind: Service metadata: labels: name: webserver name: webserver-service namespace: default spec: ports: - port: 80 selector: name: webserver
Web サーバーのレプリケーションコントローラーファイルの作成: Web サーバーの Pod をデプロイするために使用する webserver-rc.yaml ファイルを作成します。以下を設定します。
kind: "ReplicationController" apiVersion: "v1" metadata: name: "webserver-controller" spec: replicas: 1 selector: name: "webserver" template: spec: containers: - name: "apache-frontend" image: "webwithdb" ports: - containerPort: 80 metadata: labels: name: "webserver" uses: db labels: name: "webserver"
kubectl を使用したコンテナーのオーケストレーション: 現在のディレクトリーにある 2 つの yaml ファイルを使用して以下のコマンドを実行し、コンテナーの実行を開始するために Pod を起動します。
# kubectl create -f db-service.yaml services/db-service # kubectl create -f db-rc.yaml replicationcontrollers/db-controller # kubectl create -f webserver-service.yaml services/webserver-service # kubectl create -f webserver-rc.yaml replicationcontrollers/webserver-controller
rc、pod、およびサービスの確認: 以下のコマンドを実行し、レプリケーションコントローラー、Pod、およびサービスがすべて実行されていることを確認します。
# kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS db-controller db dbforweb name=db 1 webserver-controller apache-frontend webwithdb name=webserver 1 # kubectl get pod NAME READY STATUS RESTARTS AGE db-controller-tiu56 1/1 Running 0 48m webserver-controller-s5b81 1/1 Running 0 33m # kubectl get service NAME LABELS SELECTOR IP(S) PORT(S) db-service name=db name=db 10.254.232.194 3306/TCP kubernetes component=... <none> 10.254.0.1 443/TCP webserver-service name=webserver name=webserver 10.254.104.45 80/TCP
コンテナーの確認: 2 つのコンテナーがどちらも実行中で、Web サーバーコンテナーがデータベースサーバーを認識する場合、以下のように kubectl コマンドを使って Pod を確認し、curl コマンドを実行してすべてが機能していることを確認できます。
# kubectl get pods # curl http://localhost:80/cgi-bin/action <html> <head> <title>My Application</title> </head> <body> <h2>RedHat rocks</h2> <h2>Success</h2> </body> </html>
ローカルホストに Web ブラウザーをインストールしている場合は、Web ブラウザーを開いて、出力の行がきちんと表示されていることを確認します。ブラウザーで URL の http://localhost/cgi-bin/action を開きます。
2.4. Kubernetes Pod の確認
問題が発生した場合には、原因を判別するためのいくつかの方法があります。たとえば、コンテナー内のサービスを調べることができます。これを実行するには、コンテナー内のログを調べて原因を確認できます。以下のコマンドを実行します (最後の引数を、確認する Pod の名前に置き換えます)。
そのほかにも、firewalld を無効にしなかったことが問題の原因となることがあります。firewalld がアクティブな場合は、サービスがコンテナー間でのポートへのアクセスを試行する際にポートへのアクセスがブロックされる可能性があります。ホスト上で必ず systemctl stop firewalld ; systemctl disable firewalld を実行してください。
2 つの Pod を持つアプリケーションの作成時に間違いがあった場合、レプリケーションコントローラーとサービスを削除することができます (Pod はレプリケーションコントローラーが削除されるとなくなります)。その後に、yaml ファイルを修正し、それらを作成し直すことができます。以下に、レプリケーションコントローラーおよびサービスを削除する方法を示します。
# kubectl delete rc webserver-controller replicationcontrollers/webserver-controller # kubectl delete rc db-controller replicationcontrollers/db-controller # kubectl delete service webserver-service services/webserver-service # kubectl delete service db-service
Pod だけ削除することがないようにしてください。レプリケーションコントローラーを削除せずに Pod を削除すると、レプリケーションコントローラーは新規の Pod を起動して削除した Pod の置き換えを行います。
上記の例は、簡単に Kubernetes を起動する方法です。ただし、同じシステムで Master と Node を 1 つずつ使用しているだけなので、拡張性がありません。拡張性のある設定をするには、Kubernetes クラスターを作成して Docker フォーマットのコンテナーイメージを実行する に記載の手順に従って設定することが推奨されます。