Kubernetes によるコンテナのオーケストレーション

更新 -

Kubernetes は、Docker コンテナのオーケストレーションおよび管理を行うツールです。このナレッジでは、Kubernetes サンドボックスを設定する以下の手順を説明します。

  • Kubernetes で、2 つのコンテナと yaml ファイルを使用してコンテナをデプロイする
  • Kubernetes でコンテナを管理する

この手順では、Kubernetes を使用し、その動作方法を学習するためのサンドボックスを提供するための設定を行います。その後、または、最初により拡張性を持たせるように設定したい場合は、以下のナレッジを参照してください。

Kubernetes クラスターを作成して Docker フォーマットのコンテナイメージを実行する

Docker または RHEL Atomic の知識がない場合は、以下のナレッジを参照してください。
Red Hat システムにおける Docker フォーマットのコンテナイメージの使用ガイド

目次

Kubernetes の概要

Docker はコンテナフォーマットを定義し、個々のコンテナをビルドおよび管理しますが、コンテナのセットを配置し管理するにはオーケストレーションツールが必要になります。Kubernetes は、Docker コンテナのオーケストレーションを行うためのツールです。必要なコンテナイメージを構築したら、Kubernetes Master を使用して、1 つまたは複数のコンテナを Pod に配置します。 Master は、コンテナが実行する Kubernetes Node に、その Pod のコンテナをまとめます。

この例では、Kubernetes Master および Node を、RHEL 7 Server または RHEL 7 Atomic ホストとして同じコンピューターに配置します。Kubernetes 自体は、Kubernetes Master および Node の機能を実行する一連のサービスデーモンに依存します。Kubernetes Master および Node は以下のように定義されます。

  • Master: Kubernetes Master では、コンテナを起動および管理する kubectl コマンドを実行します。Node で実行するコンテナを Master から配置します。
  • Node: Node は、コンテナに対してランタイム環境を提供するシステムです。

(yaml または json フォーマットで) Pod の定義を設定ファイルに保存します。以下の手順を使用して、単一の RHEL 7 または RHEL Atomic システムを設定した後そのシステムを Kubernetes Master および Node として設定し、yaml ファイルを使用して Pod に各コンテナを定義し、Kubernetes (kubectl コマンド) を使用してこれらのコンテナをデプロイします。

Kubernetes Pod からコンテナを実行する

Docker コンテナを構築し、Kubernetes を使用してオーケストレーションを行うには RHEL 7 または RHEL Atomic システムが必要です。Kubernetes Master および Node システムには、別のサービスデーモンセットが必要です。この手順では、両方のサービスデーモンセットが同じシステムで実行します。

コンテナ、システム、およびサービスを配置したら、kubectl コマンドを実行してコンテナを配置します。Kubernetes Node (この場合はローカルシステム) で実行できるようになります。以下にその手順を示します。

Kubernetes で Docker コンテナを配置できるように設定する

Kubernetes を準備するには、RHEL 7 または RHEL Atomic をインストールして、firewalld を無効にし、コンテナを 2 つ取得する必要があります。

  1. RHEL 7 または RHEL Atomic システムをインストールします。この Kubernetes サンドボックスシステムに RHEL 7 または RHEL Atomic システムをインストールし、システムをサブスクライブし、optional および extras リポジトリを有効にしたら Docker サービスをインストールし、開始します。基本的な RHEL または RHEL Atomic システムを設定して Kubernetes を使用する方法については、以下のガイドを参照してください。

    Get Started with Docker Containers in RHEL 7 and RHEL Atomic

  2. Kubernetes をインストールします。RHEL 7 システムの場合は、kubernetes および etcd パッケージをインストールしてください。これにより、kubernetes-node および kubernetes-master パッケージも取得します (これらのパッケージは RHEL Atomic にすでにインストールされています)。

    # yum install kubernetes etcd
    
  3. firewalld を無効します。RHEL 7 ホストを使用している場合は firewalld サービスを無効にします (Atomic host に firewalld サービスはインストールされていません)。RHEL 7 では、以下のコマンドを実行して firewalld サービスを無効にして停止します。

    # systemctl disable firewalld
    # systemctl stop firewalld
    
  4. Docker コンテナを取得します。以下の 2 つのコンテナをビルドして、そのコンテナのイメージをローカルシステムで利用できるようにします (つまり、docker images コマンドを実行した時に 2 つのイメージが表示されるようにします)。

    コンテナのビルドとテストが終了したら、停止してください (docker stop mydbforweb および docker stop mywebwithdb を実行)。

Kubernetes を起動する

Kubernetes Master および Node サービスをローカルシステムで実行しているため、Kubernetes 設定ファイルに新たに追加する設定はほとんどありません。Master および Node サービスは、ローカルホストで互いを指定し、 サービスをローカルホストでのみ利用できるようにします。Kubernetes サービスをすべて起動する前に、設定を最低 1 つは変更する必要があります。この変更は kube-apiserver サービスに関する設定です。

  1. 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"
    
  2. 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
    
  3. Kubernetes Node サービスデーモンを開始します。Kubernetes Node に関連するいくつかのサービスを起動する必要があります。

    # for SERVICES in docker kube-proxy.service kubelet.service; do 
        systemctl restart $SERVICES
        systemctl enable $SERVICES
        systemctl status $SERVICES 
    done
    
  4. サービスを確認します。 ss コマンドを実行して、サービスが実行しているポートを確認します。

    # ss -tulnp | grep -E "(kube)|(etcd)"
    
  5. etcd サービスをテストします。以下のように curl コマンドを使用して、etcd サービスを確認します。

    # curl -s -L http://localhost:2379/version
    etcd 2.0.13
    

注意: RHEL Atomic Host 7.1.4 以降では、etcd ユーティリティはポート 2379 を使用します。古いバージョンの RHEL Atomic Host を実行している場合は、上述のコマンドの 2379 を 4001 に置き換えます。

Kubernetes でコンテナ Pod を起動する

ローカルシステムで master および node サービスを実行し、コンテナイメージを 2 つ配置したら、Kubernetes Pod を使用してコンテナを起動できます。以下は注意点です。

  • 複数の Pod: 単一の Pod で複数のコンテナを起動できますが、コンテナを異なる Pod に配置することで、互いのコンテナを起動しなくても、各コンテナが必要に応じて複数のインスタンスを複製できます。

  • Kubernetes サービス: この手順では、コンテナが Kubernetes を調べてデータベースや web サーバーの Pod のサービスを見つけられるように、それらのサービスを定義します。
    この方法では、データベースおよび web サーバーが、IP アドレスやポート番号、そしてサービスを提供している Pod が実行しているノードを知らなくても互いを見つけることができます。

次の手順では、2 つのサービスおよび Pod を起動してテストします。

重要: yaml ファイルのインデントを保持することが重要になります。yaml ファイルの空白はフォーマットを整理するために使用されます (構造を保持するために波括弧などの文字を使用する必要はありません)。

  1. データベースの 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
    
  2. データベースサーバーの複製コントローラファイルを作成します。Database サーバーの pod を配置するために使用する db-rc.yaml ファイルを作成します。db-controller pod のレプリカを 1 つだけ実行するように設定されます。以下を設定します。

    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"
    
  3. Web サーバーの Kubernetes サービスを作成します。 webserver-service.yaml ファイルを作成して、Kubernetes に Web サービスを提供する Pod を指定します。

    Kubernetes:
    apiVersion: v1
    kind:Service
    metadata:
      labels:
        name: webserver
      name: webserver-service
      namespace: default
    spec:
      ports:
      - port:80
      selector:
        name: webserver
    
  4. Web サーバーのレプリケーションコントローラファイルを作成します。Web サーバー Pod を配置するのに使用する webserver-rc.yaml ファイルを作成します。webserver-controller pod の複製を 1 つだけ実行するように設定します。以下を設定します。

    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"
    
  5. kubectl でコンテナのオーケストレーションを行います。現在のディレクトリで 4 つの yaml ファイルを使用し、以下のコマンドを実行して、コンテナの実行を開始するサービスと Pod を起動します。

    # kubectl create -f db-service.yaml
    services/db-service
    # kubectl create -f webserver-service.yaml
    services/webserver-service
    # kubectl create -f db-rc.yaml
    replicationcontrollers/db-controller
    # kubectl create -f webserver-rc.yaml
    replicationcontrollers/webserver-controller
    
  6. 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
    
  7. コンテナが実行してるかどうかテストします。コンテナが適切に実行し、実行しているサービスが、表示された IP アドレスとポートから利用できることを確認します。表示された webserver-service IP アドレスとポートを前提とした場合は、以下のコマンドを実行して、コンテナが動作していることを確認します。

    # curl http://10.254.104.45:80
    The Web Server is Running
    # curl http://10.254.104.45:80/cgi-bin/action
    <html>
    <head>
    <title>My Application</title>
    </head>
    <body>
    <h2>RedHat rocks</h2>
    <h2>Success</h2>
    </body>
    </html>
    

    ローカルホストに Web ブラウザーをインストールしている場合は、Web ブラウザーを開いて、出力がきちんと表示されていることを確認します。ブラウザーで http://10.254.104.45/cgi-bin/action を開きます。

Kubernetes Pod を試す

この方法で問題が発生した場合は、 どんな問題が発生しているかを特定する方法がいくつかあります。たとえば、コンテナ内のサービスを調べることができます。コンテナ内のログで、何が発生したかを確認できます。以下のコマンドを実行してください (最後の引数を、問題が発生している Pod 名に置き換えます)。

# kubectl logs db-controller-tiu56
150828 10:01:57 mysqld_safe Logging to '/var/log/mariadb/mariadb.log'.
150828 10:02:00 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
# kubectl logs webserver-controller-s5b81
AH00558: httpd:Could not reliably determine the server's fully qualified domain name, 
using 172.17.0.6.このメッセージをグローバルに非表示にするには、'ServerName' ディレクティブを設定します。

その他にも、firewalld を無効にしたことを忘れてしまう問題があります。firewalld がアクティブの場合は、コンテナ間でサービスがポートにアクセスしようとするとそのアクセスがブロックされます。先に、ホスト上で systemctl stop firewalld ; systemctl disable firewalld を実行しておいてください。

誤って Pod を 2 つ持つアプリケーションを作成してしまった場合は、レプリケーションコントローラーおよびサービスを削除できます (レプリケーションコントローラーを削除すると 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 を起動する方法です。ただし、同じシステム内でマスターとノードを 1 つずつ使用しているだけなので、拡張性がありません。拡張可能な設定を行う場合は、Kubernetes クラスターを作成して Docker フォーマットのコンテナイメージを実行する に記載される手順に従って設定することが推奨されます。