Kubernetesを使ったスケーラブルなWordPress環境を構築してみた

#はじめに
IBMのマネージドな[Kubernetes](https://kubernetes.io/)環境である[IBM Cloud Containers Service](https://www.ibm.com/cloud-computing/bluemix/ja/containers)について、スケーラブルなWordPress（ブログ・ソフトウェア）環境の構築手順とともにご紹介します。
<img width="725" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/5b71d3e1-203e-a6d1-4872-e092a05eecb3.png">

※ライト版（無料）で月額$70-80相当の仮想サーバー（2コア/4GB RAM/Ubuntu 16.04 LTS）がユーザー専用のWorker Nodeとして無料提供されますのでぜひこの機会にお試しください（2017年9月現在） Kubernetesって何？という方は[こちら](http://qiita.com/asasaki/items/f0746ca36d0a134e2e2d#%E8%A3%9C%E8%B6%B3kubernetes%E3%81%A8%E3%81%AF)からお読みください。

#なぜIBMはKubernetesにコミットしているのか？
2013年に[オープン・クラウド戦略](https://www.ibm.com/cloud-computing/learn-more/open-cloud/)を発表する以前からLinuxをはじめIBMは長年にわたってOSSを支援しています。特にクラウドの領域では、これまで以上に相互運用性や相互接続性が重要となるため積極的にOSSをIBM Cloudのコア・テクノロジーとして採用しています。Kubernetesへの取り組みもその一環と言えます。

<img width="914" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/f5349aa8-064e-0a2c-b26f-3c9f4403df4e.png">

Kubernetesといえば、[Google Container Engine (GKE)](https://cloud.google.com/container-engine/)で使われているコンテナ管理フレームワークとして有名ですが、現在は、オープンソース・プロジェクトとして[CNCF (Cloud Native Computing Foundation)](https://www.cncf.io/)により運営・管理されています。最近では、[PivotalとVMwareがGoogleと協業](http://www.atmarkit.co.jp/ait/articles/1708/30/news053.html)してKubernetesを採用したプラットフォーム・ソフトウェア製品を発表するなどKubernetesは業界でも大変注目されています。

<img width="797" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/fdc485cf-bb91-93a4-c27e-29188ec0c262.png">

IBMは、オープンソース・プロジェクトとしてKubernetes自体の開発に参加するだけでなく、CNCFのプラチナメンバーとして、理事会の議長を務め、コンテナ運用環境の標準化に取り組んでいます。IBMがKubernetesにコミットしている最大の理由として、Kubernetesのオープン性とデプロイメント・オプションの幅広さがあげられます。KubernetesはオープンソースであるDockerベースのコンテナを管理対象としていますので、ユーザーは、ベアメタル・サーバー、仮想化サーバー、プライベート、パブリック、ハイブリッド・クラウドのいずれのオプションでも選択できます。さらに、従来のハイパーバイザー型の仮想化技術と違いコンテナは軽量・高速であるためインフラをコードベースで制御・管理しやすく、それゆえポータビリティ（移植性）が高いという特徴があります。そのため、IBMが提唱するハイブリッド・クラウドを実現する重要なテクノロジーとして位置付けられています。

もう１つの理由として、Kubernetesには、Linux Foundationによって管理される明確なガバナンス・モデルがあります。さらに、Googleは積極的に製品の機能とロードマップを推進しているので、ベンダーがエコシステムに参加しやすいプロジェクトと言えます。Kubernetesのエコシステムが活性化することで長期的な実行可能性の観点でユーザー企業は安心して採用することができます。IBM以外にもHuawei、Intel、およびRed HatなどがKubernetesの開発において大きく貢献しています。今年に入ってCNCFのPlatinum MembersとしてAWS、Microsoftも加わってきましたので、次世代クラウド・プラットフォームのデファクト・スタンダードになると考えています。

<img width="657" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/c81c32db-c1c7-18e3-4253-e4d8e273d9b0.png">
参考：[CNCF Platinum Members](https://www.cncf.io/about/members/
)

以上のような理由から、現在Kubernetesは、IBMのパブリック・クラウド・サービスである[IBM Cloud Containers Service (Bluemix Containers Service)](https://www.ibm.com/cloud-computing/jp/ja/)や、プライベート・クラウド製品[IBM Cloud private](https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W1559b1be149d_43b0_881e_9783f38faaff)において採用され企業向けに提供しています。IBM Cloud private (ICP)についてはここでは詳しくは触れませんが、9月より、IBM Cloud private-ce v2.1 BETA 1として[DockerHub上](https://hub.docker.com/r/ibmcom/cfc-installer/)に公開されていますのでこちらもぜひお試しください。 

参考：IBM Cloud private画面イメージ
<img width="1274" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/0abb9fdd-6285-cec3-e5fa-669849698704.png">

#IBM Cloud Containers Service（=IBMのマネージドKubernetes環境）
IBM Cloud Containers Serviceでは、KubernetesのMaster Node部分は、IBMによるマネージド・サービスとして提供され、Worker Nodeがユーザーのコンテナ化アプリの可動領域として提供されます。実体として、Kubernetes環境はIBM CloudのIaaS (旧SoftLayer)の仮想サーバー上に展開されます。IBMが運用管理するMaster Nodeとユーザーに提供されるWorker Nodeの各コンポーネントは下図のように配置・展開されます。

<img width="1052" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/d9fc5812-3cba-cba4-1ad4-388ee6827d31.png">

#IBM Cloud Containers Serviceをオーダーしてみる

[Bluemix](https://console.bluemix.net/)のカタログから[コンテナー](https://console.bluemix.net/catalog/&category=containers)のカテゴリーを選択すると下図のようにKubernetes ClsuterとContainer Registryが表示されます。

<img width="1248" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/ca431ceb-a886-ca4a-c1bc-1f905d683d44.png">

Kubernetes Clsuterを選択するとクラスター・タイプの選択画面が表示されます。クラスター名は、ここでは、「mycluster」としてライト版（無料）をオーダーします。ライト版（無料）では１つのクラスターに１つのワーカーノードを利用しています。

<img width="1276" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/bd62013b-7c91-50cc-a603-3ba422f3cf09.png">

ちなみに、標準版では、最低3台以上の複数のワーカー・ノードを作成することができます。ワーカー・ノードをホストするサーバーは4CPU/16GB、16CPU/64GB、32CPU/128GB、56CPU/242GBから選択できるだけでなく、専用ハードウェア（ベアメタル）と共用ハードウェア（仮想サーバー）を選択することができます。

<img width="805" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/4e350d01-b7d4-00f1-8c82-35f5b56c67f7.png">

また、ライト版と標準版のクラスターでは、インターネットからアプリケーションにアクセスさせる方法が異なります。

- ライト版：NodePortのみ
- 標準版：NodePort、ロード・バランサー、Ingressから選択可能

詳細は[こちら](https://console.bluemix.net/docs/containers/cs_apps.html#cs_apps_public)をご確認ください。

また、可用性に応じて以下のような構成を組むことも可能です。

- 複数のワーカー・ノードを配置した 1 つのクラスター
- 同じ地域内の別々のロケーションで実行される 2 つのクラスター (ロケーションごとに複数のワーカー・ノードを配置)
- 別々の地域で実行される 2 つのクラスター (地域ごとに複数のワーカー・ノードを配置)

<img width="773" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/be629e03-f322-528f-dd4a-fbcf01ca7f6f.png">

クラスターをオーダーすると5分程度でWorker Nodeがデプロイされ利用可能な状態になります。

<img width="1243" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/7679cdd9-b7bc-0f1e-f577-ee0b93078688.png">

ダッシュボードから、Worker NodeのIDが割り振られていることが分かります。

<img width="1251" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/122055e5-e0b2-6144-fade-0a48dd857fb5.png">

# Kubernetesクラスターへのアクセス

Kubernetesクラスターにアクセスするには、 Bluemix CLIツールとKubernetes CLIのプラグインをPC端末にダウンロードしてインストールしてください。

```
$ bx plugin install container-service -r Bluemix
```

次に、bxコマンドを使いユーザー自身のBluemixアカウントにログインします。

```
$ bx login -a https://api.ng.bluemix.net
```

※統合 ID を所有している場合には、bx login --sso を使用して Bluemix CLI にログインしてください。

次に、IBM Bluemix Container Service のプラグインを初期化します。

```
$ bx cs init
```

次に、ターミナル・コンテキストをクラスターに設定します。

```
$ bx cs cluster-config mycluster
export KUBECONFIG=/Users/ibm/.bluemix/plugins/container-service/clusters/mycluster/kube-config-prod-hou02-mycluster.yml
```

出力として構成ファイルへのパスが環境変数を設定するコマンドとして表示されます。ターミナルでコマンドをコピーして貼り付け、環境変数として設定してください。kubeconfigファイルを直接ダウンロードして、コンテキストを手動で構成することもできます。

設定が完了するとKubernetesコマンドを実行してワーカー・ノードを利用することができます。

```
$ kubectl get nodes
NAME           STATUS    AGE       VERSION
50.23.39.106   Ready     41d       v1.5.6-4+abe34653415733
```

KubernetesダッシュボードはターミナルからProxy経由でアクセスします。

```
$ kubectl proxy &
```

ブラウザから http://127.0.0.1:8001/ui を使用してKubernetesダッシュボードを表示することができます。

<img width="1276" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/bf1235cc-e76b-39c3-3045-5071ec13f63d.png">

#スケーラブルなWordpress環境を構築してみる
Kubernetesクラスターの機能を確認するためにサンプルとしてWordpress環境を構築してみます。WordPressはLAMP (Linux/Apache/MySQL/PHP)で動くオープンソースのブログソフトウェアです。この例では、フロントエンド層としてWordPressコンテナ、バックエンド層としてMySQLコンテナをKubernetesに展開し、フロントエンド層を不可に応じて柔軟にスケーラブルさせる方法を紹介します。

<img width="755" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/4e586169-80b9-6177-beb6-5d12cfb32baf.png">

環境構築に必要なコンポーネントは以下のとおりです。

- [WordPress (Latest)](https://hub.docker.com/_/wordpress/)
- [MySQL (5.6)](https://hub.docker.com/_/mysql/)
- [Kubernetes Clusters](https://console.bluemix.net/docs/containers/cs_ov.html#cs_ov)
- [Bluemix container service](https://console.bluemix.net/catalog/?taxonomyNavigation=apps&category=containers&env_id=ibm%3Ayp%3Aus-south)

大まかな作業の流れは以下のとおりです。

- 永続ディスクを定義するローカルの永続ボリュームを作成します。
- 機密データを保護する秘密を作成します。
- 1つまたは複数のポッドでWordPressフロントエンドを作成して展開します。
- MySQLデータベースを作成し、展開します（今回はコンテナ内のMySQLを使用）。

#ステップ1. MySQLシークレットの設定

PC端末のターミナル上の適当なディレクトリにpassword.txtという名前の新しいファイルを作成し、password.txt（ASCII文字を含む任意の文字列）に任意のMySQLパスワードを入れます。

`$ vi password.txt`

password.txt内の不要な改行を削除するために次のコマンドを使用します。

```
$ tr -d '\n' <password.txt >.strippedpassword.txt && mv .strippedpassword.txt password.txt
```

#ステップ2. WordPressとMySQLのサービスと展開を作成する

※注意：Bluemix Compose-MySqlをバックエンドのデータベースとして使用する場合は、[Bluemix MySQLをバックエンドとして使用する](https://github.com/IBM/Scalable-WordPress-deployment-on-Kubernetes#22-using-bluemix-mysql-as-backend)を参照してください。

まずは、以下のコマンドでKubernetesクラスターのローカル・ストレージとして永続ボリュームを作成します。

```
$ kubectl create -f local-volumes.yaml
persistentvolume "local-volume-1" created
persistentvolume "local-volume-2" created
```

local-volumes.yamlのファイルの中身は例えば以下のように記述してください。

```local-volumes.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-1
  labels:
    type: local
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/data/lv-1
  persistentVolumeReclaimPolicy: Recycle
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-2
  labels:
    type: local
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/data/lv-2
  persistentVolumeReclaimPolicy: Recycle
```

次に、以下のコマンドでMySQLのシークレットとWordPressのサービスを作成します。

```
$ kubectl create secret generic mysql-pass --from-file=password.txt
secret "mysql-pass" created
```

次に、以下のコマンドでMySQLのPodを作成します。

```
$ kubectl create -f mysql-deployment.yaml
service "wordpress-mysql" created
persistentvolumeclaim "mysql-lv-claim" created
deployment "wordpress-mysql" created
```

ここでは、mysql-deployment.yamlの中身は以下のように記述しています。

```mysql-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-lv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password.txt
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-local-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-local-storage
        persistentVolumeClaim:
          claimName: mysql-lv-claim
```

次に、以下のコマンドでWordpressのPodをデプロイします。

```
$ kubectl create -f wordpress-deployment.yaml
service "wordpress" created
persistentvolumeclaim "wp-lv-claim" created
deployment "wordpress" created
```

今回、wordpress-deployment.yamlの中身は以下のように記述しました。ここで定義するnodePortは、外部からクラスター内のサービスにアクセスするための公開用のポート番号です。

```wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30180
  selector:
    app: wordpress
    tier: frontend
  type: NodePort
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-lv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:latest
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        # - name: WORDPRESS_DB_USER
        #   value: admin
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password.txt
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-local-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-local-storage
        persistentVolumeClaim:
          claimName: wp-lv-claim
```

すべてのPodが実行されたら、次のコマンドを実行してPod名を確認します。kubernetesクラスタからPodのリストが返されます。

```
$ kubectl get pods
NAME                               READY     STATUS    RESTARTS   AGE
wordpress-2140944197-r0rnv         1/1       Running   0          6m
wordpress-mysql-3502574762-fcl7s   1/1       Running   0          6m
```

以上が完了したら今度は、外部リンクにアクセスしてください。

#ステップ3. 外部WordPressリンクへのアクセス

クラスタのIPアドレスを取得するには、次のコマンドを使用します。

```
$ bx cs workers mycluster
OK
ID                                                 Public IP      Private IP     Machine Type   State    Status
kube-hou02-pabb828381ec564eeca73ac80169753db5-w1   50.23.39.106   10.47.122.24   free           normal   Ready
```

また、NodePort番号を取得するために、次のコマンドを実行してください。

```
$ kubectl get svc wordpress
NAME        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
wordpress   10.10.10.152   <nodes>       80:30180/TCP   10m
```

上記よりパブリックIPアドレスと外部公開用のポート番号（NodePort）を取得して、 **http://[IP]:[ポート番号]** を使用してWordPressサイトにアクセスできます。

Kubernetesダッシュボードからもデプロイのステータスを確認できます。 `$kubectl proxy`を実行し、URL 'http://127.0.0.1:8001/ui' にアクセスして、WordPressコンテナがいつ準備完了になったかを確認します。Podが完全に機能するには最大5分かかることがあります。

#ステップ4. WordPressの使用

外部公開用URL（今回は http://50.23.39.106:30180 ） にアクセスしてください。

<img width="1061" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/af1b6e3b-56e9-f0c4-4bec-4afe41ce8717.png">

WordPressが稼動しているので、新しいユーザーを登録すればWordPressをインストールすることができます。

<img width="801" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/6f131107-1ffc-dbc9-e879-caeb81806c2a.png">

WordPressをインストールした後、アップデートや必要な設定をしてください。

<img width="1260" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/a6258155-e153-f30f-f0e1-e060547ff2ac.png">

ブログ・サイトとして、新しい投稿をすることができます。

<img width="1280" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/7b2e5665-afc4-2c45-8e0c-19001630219d.png">

#ステップ5. スケールアウトしてみる

クラスタにリソースがあり、WordPress Webサイトの規模を拡大する場合は、次のコマンドを実行して現在の展開を確認できます。

```
$ kubectl get deployments
NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
wordpress         1         1         1            1           1h
wordpress-mysql   1         1         1            1           1h
```

これで、WordPressのフロントエンドのために以下のコマンドを実行することができます。例えば、Wordpressを10個のPodにスケールさせてみます。

```
$ kubectl scale deployments/wordpress --replicas=10
deployment "wordpress" scaled
```

以下のとおりWordPressのフロントエンドを実行している10個のポッドにスケールしました。

```
$ kubectl get deployments
NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
wordpress         10         10         10            10           1h
wordpress-mysql   1         1         1            1           1h
```

kubectlコマンドでPodの一覧詳細を確認します。10個のポッドにスケールしていることが分かります。

```
$ kubectl get pods -o wide

NAME                               READY     STATUS    RESTARTS   AGE       IP             NODE
wordpress-2140944197-63jwn         1/1       Running   0          1h        172.30.53.88   50.23.39.106
wordpress-2140944197-ckk2m         1/1       Running   0          1h        172.30.53.90   50.23.39.106
wordpress-2140944197-g2f8d         1/1       Running   0          1h        172.30.53.83   50.23.39.106
wordpress-2140944197-khqxv         1/1       Running   0          1h        172.30.53.85   50.23.39.106
wordpress-2140944197-kpv84         1/1       Running   0          1h        172.30.53.82   50.23.39.106
wordpress-2140944197-l621r         1/1       Running   0          1h        172.30.53.84   50.23.39.106
wordpress-2140944197-p8xh2         1/1       Running   0          1h        172.30.53.87   50.23.39.106
wordpress-2140944197-qmgdp         1/1       Running   0          1h        172.30.53.89   50.23.39.106
wordpress-2140944197-r0rnv         1/1       Running   0          2h        172.30.53.81   50.23.39.106
wordpress-2140944197-r1xx0         1/1       Running   0          1h        172.30.53.86   50.23.39.106
wordpress-mysql-3502574762-fcl7s   1/1       Running   0          2h        172.30.53.80   50.23.39.106
```

Kubernetesダッシュボードからも10個のポッドに拡張されたことが確認できます。

<img width="1278" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/276e9100-6b8f-2c74-43ed-96310ef71d9f.png">

※ライト版（無料）の場合、リソースが限られているため、10ポッド程度までの拡張をお勧めします。

#トラブルシューティング

誤って改行でパスワードを作成したのにMySQLサービスを認可できない場合は、以下のコマンドで現在のシークレットを削除することができます。

```
$ kubectl delete secret mysql-pass
```

サービス、デプロイメント、および永続ボリュームのリクエストは、以下のコマンドで削除できます。

```
$ kubectl delete deployment,service,pvc -l app=wordpress
```

作成済みの永続ボリュームを削除するには、次のコマンドを実行します

```
$ kubectl delete -f local-volumes.yaml
```

#【補足】Kubernetesとは
- Google社内のアプリケーション基盤として利用されていた「Borg」にインスパイアされ開発されたコンテナ管理フレームワーク
<img width="432" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/85fe594a-0ae5-7866-5d5f-e083214d8f7c.png">
出典：[Large-scale cluster management at Google with Borg](https://research.google.com/pubs/pub43438.html
)

- 2014年にGoogleがオープン化しCNCF(Cloud Native Computing Foundation)に寄贈。現在はLinux Foundationによってオープンソース・プロジェクトとして管理
- アプリケーションを仮想マシン単位ではなくコンテナ単位に分割
- Webアプリケーション、バッチ・ジョブ、データベースといったコンテナ化アプリをデプロイするための統合的なAPIを提供
- 「宣言的なデプロイ・モデル」という概念を導入。アプリケーションをどのように実行すべきかが記述されたテンプレートにしたがい、Kubernetesがアプリケーションのステータスを制御
- サービス・ディスカバリー（サービスへのルーティングを自動で提供する）によるアプリケーション構成の自動化
- コンテナのスケジューリング、スケーリング、健全性、ライフサイクル、ロード バランシング、データ永続性、ロギング、モニタリングを管理
- [Blue-Greenデプロイメント、ローリング・デプロイメント、カナリア・デプロイメント](https://www.ibm.com/support/knowledgecenter/ja/SS4GSP_6.2.4/com.ibm.udeploy.doc/topics/app_process_advanced_ov.html)といった継続的デリバリー実現

**Kubernetesの基本**
ここではKubernetesを利用する上で最低限抑えておくべき用語、機能について解説します。アーキテクチャ全体像を下図に示します。

<img width="742" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/228e8efb-8eeb-c485-d3b4-dfaf26c80a5e.png">

**Kubernetesの基本用語**

- コンテナ（Container）：同一ホスト上で動作しているプロセスのリソースを隔離することにより、異なる環境のように見せた仮想環境。
- ポッド（Pod）：1つ以上のコンテナを協調動作する単位でまとめたもの。同一ノード（後述）上での動作が前提となる。
- ノード（Node）：Dockerコンテナのホストとなる物理的もしくは仮想的なマシン。
- ミニオン（Minion）：マスター（後述）からの指示でポッドを動作させるノード。
- マスター（Master）：1つ以上のミニオンで動作するポッドを集中管理するためのノード。
- サービス（Service）：ポッドの集合によって実現されるシステムの機能を表す抽象的なもの。ロードバランサ的な役割も果たす。
- レプリケーションコントローラ（Replication Controller）：定義ファイルに指定されている数を保つようポッドを複製し、サービスの実装を行うもの。
- キューブレット（Kubelet）：定義ファイルにしたがってポッドを起動したり、ポッドが起動していない場合は再起動を行ったりするエージェント。
- cAdvisor：Container Advisorの略で、コンテナのリソース監視を行う。Googleが開発しており、ソースコードはhttps://github.com/google/cadvisorにある。
- プロキシ（Proxy）：簡易なL3プロキシ
- APIサーバ（APIs）：kubectlコマンドからの命令を受けて、ポッド、サービス、レプリケーションコントローラを操作する機能を提供する。
- スケジューラ（Schedular）：コンテナをどのミニオン上で動かすかを決定する。

**Kubernetesの基本機能**

- コンテナ操作機能：複数コンテナをPod単位でグルーピングし、配備/削除/起動/停止を行います。
- フェイルオーバー機能：コンテナが異常終了したことを検知し再起動させます。
- スケーリング機能：起動しているコンテナ数を増減させます。
- スケジューリング機能：コンテナを任意のホストに割り振ります。
- ロードバランス機能：複数コンテナにリクエストを振り分けて負荷分散を行います。
- サービスディスカバリ機能：サービスへのルーティングを自動で提供します。
- セキュリティ：「Kubernetes API」の実行に、ユーザ認証/TSL認証を持たせることが可能です。

**Kubernetesで使われている関連製品**

- etcd：分散型設定共有サービス
- Flannel：仮想ネットワーク機構
- OpenVSwitch：仮想ネットワーク機構
- cAdvisor：コンテナリソース監視

**参考文献**

- [kubernetes.io](https://kubernetes.io/)
- [Google Container Engine (GKE) & Kubernetes のアーキテクチャ解説](https://www.slideshare.net/HammoudiSamir/google-container-engine-gke-kubernetes)
- [OSS×Cloud News](https://www.ossnews.jp/oss_info/Kubernetes
)
- [SIOS OSS Blog](https://oss.sios.com/yorozu-blog/yorozu-20151216)