#はじめに
IBMのマネージドなKubernetes環境であるIBM Cloud Containers Serviceについて、スケーラブルなWordPress(ブログ・ソフトウェア)環境の構築手順とともにご紹介します。
※ライト版(無料)で月額$70-80相当の仮想サーバー(2コア/4GB RAM/Ubuntu 16.04 LTS)がユーザー専用のWorker Nodeとして無料提供されますのでぜひこの機会にお試しください(2017年9月現在) Kubernetesって何?という方はこちらからお読みください。
#なぜIBMはKubernetesにコミットしているのか?
2013年にオープン・クラウド戦略を発表する以前からLinuxをはじめIBMは長年にわたってOSSを支援しています。特にクラウドの領域では、これまで以上に相互運用性や相互接続性が重要となるため積極的にOSSをIBM Cloudのコア・テクノロジーとして採用しています。Kubernetesへの取り組みもその一環と言えます。
Kubernetesといえば、Google Container Engine (GKE)で使われているコンテナ管理フレームワークとして有名ですが、現在は、オープンソース・プロジェクトとしてCNCF (Cloud Native Computing Foundation)により運営・管理されています。最近では、PivotalとVMwareがGoogleと協業してKubernetesを採用したプラットフォーム・ソフトウェア製品を発表するなどKubernetesは業界でも大変注目されています。
IBMは、オープンソース・プロジェクトとしてKubernetes自体の開発に参加するだけでなく、CNCFのプラチナメンバーとして、理事会の議長を務め、コンテナ運用環境の標準化に取り組んでいます。IBMがKubernetesにコミットしている最大の理由として、Kubernetesのオープン性とデプロイメント・オプションの幅広さがあげられます。KubernetesはオープンソースであるDockerベースのコンテナを管理対象としていますので、ユーザーは、ベアメタル・サーバー、仮想化サーバー、プライベート、パブリック、ハイブリッド・クラウドのいずれのオプションでも選択できます。さらに、従来のハイパーバイザー型の仮想化技術と違いコンテナは軽量・高速であるためインフラをコードベースで制御・管理しやすく、それゆえポータビリティ(移植性)が高いという特徴があります。そのため、IBMが提唱するハイブリッド・クラウドを実現する重要なテクノロジーとして位置付けられています。
もう1つの理由として、Kubernetesには、Linux Foundationによって管理される明確なガバナンス・モデルがあります。さらに、Googleは積極的に製品の機能とロードマップを推進しているので、ベンダーがエコシステムに参加しやすいプロジェクトと言えます。Kubernetesのエコシステムが活性化することで長期的な実行可能性の観点でユーザー企業は安心して採用することができます。IBM以外にもHuawei、Intel、およびRed HatなどがKubernetesの開発において大きく貢献しています。今年に入ってCNCFのPlatinum MembersとしてAWS、Microsoftも加わってきましたので、次世代クラウド・プラットフォームのデファクト・スタンダードになると考えています。
参考:[CNCF Platinum Members](https://www.cncf.io/about/members/ )以上のような理由から、現在Kubernetesは、IBMのパブリック・クラウド・サービスであるIBM Cloud Containers Service (Bluemix Containers Service)や、プライベート・クラウド製品IBM Cloud privateにおいて採用され企業向けに提供しています。IBM Cloud private (ICP)についてはここでは詳しくは触れませんが、9月より、IBM Cloud private-ce v2.1 BETA 1としてDockerHub上に公開されていますのでこちらもぜひお試しください。
#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の各コンポーネントは下図のように配置・展開されます。
#IBM Cloud Containers Serviceをオーダーしてみる
Bluemixのカタログからコンテナーのカテゴリーを選択すると下図のようにKubernetes ClsuterとContainer Registryが表示されます。
Kubernetes Clsuterを選択するとクラスター・タイプの選択画面が表示されます。クラスター名は、ここでは、「mycluster」としてライト版(無料)をオーダーします。ライト版(無料)では1つのクラスターに1つのワーカーノードを利用しています。
ちなみに、標準版では、最低3台以上の複数のワーカー・ノードを作成することができます。ワーカー・ノードをホストするサーバーは4CPU/16GB、16CPU/64GB、32CPU/128GB、56CPU/242GBから選択できるだけでなく、専用ハードウェア(ベアメタル)と共用ハードウェア(仮想サーバー)を選択することができます。
また、ライト版と標準版のクラスターでは、インターネットからアプリケーションにアクセスさせる方法が異なります。
- ライト版:NodePortのみ
- 標準版:NodePort、ロード・バランサー、Ingressから選択可能
詳細はこちらをご確認ください。
また、可用性に応じて以下のような構成を組むことも可能です。
- 複数のワーカー・ノードを配置した 1 つのクラスター
- 同じ地域内の別々のロケーションで実行される 2 つのクラスター (ロケーションごとに複数のワーカー・ノードを配置)
- 別々の地域で実行される 2 つのクラスター (地域ごとに複数のワーカー・ノードを配置)
クラスターをオーダーすると5分程度でWorker Nodeがデプロイされ利用可能な状態になります。
ダッシュボードから、Worker NodeのIDが割り振られていることが分かります。
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ダッシュボードを表示することができます。
#スケーラブルなWordpress環境を構築してみる
Kubernetesクラスターの機能を確認するためにサンプルとしてWordpress環境を構築してみます。WordPressはLAMP (Linux/Apache/MySQL/PHP)で動くオープンソースのブログソフトウェアです。この例では、フロントエンド層としてWordPressコンテナ、バックエンド層としてMySQLコンテナをKubernetesに展開し、フロントエンド層を不可に応じて柔軟にスケーラブルさせる方法を紹介します。
環境構築に必要なコンポーネントは以下のとおりです。
大まかな作業の流れは以下のとおりです。
- 永続ディスクを定義するローカルの永続ボリュームを作成します。
- 機密データを保護する秘密を作成します。
- 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をバックエンドとして使用するを参照してください。
まずは、以下のコマンドでKubernetesクラスターのローカル・ストレージとして永続ボリュームを作成します。
$ kubectl create -f local-volumes.yaml
persistentvolume "local-volume-1" created
persistentvolume "local-volume-2" created
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の中身は以下のように記述しています。
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は、外部からクラスター内のサービスにアクセスするための公開用のポート番号です。
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 ) にアクセスしてください。
WordPressが稼動しているので、新しいユーザーを登録すればWordPressをインストールすることができます。
WordPressをインストールした後、アップデートや必要な設定をしてください。
ブログ・サイトとして、新しい投稿をすることができます。
#ステップ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個のポッドに拡張されたことが確認できます。
※ライト版(無料)の場合、リソースが限られているため、10ポッド程度までの拡張をお勧めします。
#トラブルシューティング
誤って改行でパスワードを作成したのにMySQLサービスを認可できない場合は、以下のコマンドで現在のシークレットを削除することができます。
$ kubectl delete secret mysql-pass
サービス、デプロイメント、および永続ボリュームのリクエストは、以下のコマンドで削除できます。
$ kubectl delete deployment,service,pvc -l app=wordpress
作成済みの永続ボリュームを削除するには、次のコマンドを実行します
$ kubectl delete -f local-volumes.yaml
#【補足】Kubernetesとは
- Google社内のアプリケーション基盤として利用されていた「Borg」にインスパイアされ開発されたコンテナ管理フレームワーク
- 2014年にGoogleがオープン化しCNCF(Cloud Native Computing Foundation)に寄贈。現在はLinux Foundationによってオープンソース・プロジェクトとして管理
- アプリケーションを仮想マシン単位ではなくコンテナ単位に分割
- Webアプリケーション、バッチ・ジョブ、データベースといったコンテナ化アプリをデプロイするための統合的なAPIを提供
- 「宣言的なデプロイ・モデル」という概念を導入。アプリケーションをどのように実行すべきかが記述されたテンプレートにしたがい、Kubernetesがアプリケーションのステータスを制御
- サービス・ディスカバリー(サービスへのルーティングを自動で提供する)によるアプリケーション構成の自動化
- コンテナのスケジューリング、スケーリング、健全性、ライフサイクル、ロード バランシング、データ永続性、ロギング、モニタリングを管理
- Blue-Greenデプロイメント、ローリング・デプロイメント、カナリア・デプロイメントといった継続的デリバリー実現
Kubernetesの基本
ここではKubernetesを利用する上で最低限抑えておくべき用語、機能について解説します。アーキテクチャ全体像を下図に示します。
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:コンテナリソース監視
参考文献