現在、コンテナー・ベースのソフトウェア開発が盛んに行われるようになっています。簡単に環境を複製できるため、一般に、開発者はアプリケーションを自分のデスクトップ上で作成し、ローカルでデバッグとテストを行ってから、アプリケーションをビルドして Kubernetes クラスターにデプロイします。
このチュートリアルでは、アプリケーションを IBM Cloud 上の Kubernetes クラスターにデプロイするための以下の 2 つの方法を紹介します。
- DevOps パイプラインを使用せずに、
kubectl
CLI を使ってデプロイする - Tekton Pipelines (Kubernetes スタイルの継続的インテグレーション/継続的デリバリー (CI/CD) パイプライン) を使用してデプロイする
前提条件
このチュートリアルに従うには、あらかじめ以下の作業を行っておく必要があります。
- IBM Cloud アカウントを作成する。
- IBM Cloud 上の Kubernetes サービスのインスタンスを作成する。サービス・インスタンスを作成するには約 20 分かかります。
kubectl
CLI を使用して Kubernetes クラスターにアクセスできるようにする。手順を参照するには、IBM Cloud ダッシュボード > [クラスター名]> 「Access (アクセス)」 の順に選択してください。- IBM Cloud コンテナー・レジストリー上に名前空間を作成する。それには、IBM Cloud ダッシュボードで 「Navigation (ナビゲーション)」 > 「Kubernetes」 > 「Registry (レジストリー)」 > 「Namespaces (名前空間)」 の順にクリックします。
Git CLI を構成する。以下のコマンドを実行して、リポジトリーをワークステーションに複製します。
git clone https://github.com/IBM/deploy-app-using-tekton-on-kubernetes.git
所要時間
前提条件に対応したならば、約 40 分でこのチュートリアルを完了できます。
kubectl を使用してアプリケーションをビルドし、IBM Cloud Kubernetes Service 上にデプロイする
以下の手順に従って、アプリケーションをビルドして Kubernetes クラスター上にデプロイします。
- アプリケーション用の Dockerfile を作成し、その Dockerfile を使用してコンテナー・イメージをビルドします。
- ビルドしたコンテナー・イメージを、アクセス可能なコンテナー・レジストリーにアップロードします。
- コンテナー・イメージを使用して Kubernetes デプロイメントを作成し、構成 (YAML) ファイルを使用してアプリケーションを IBM Cloud Kubernetes Service クラスターにデプロイします。
このチュートリアルでは以下のようにして、シンプルな Hello World! Node.js アプリケーションを Kubernetes 上にデプロイしています。以下のコードはサンプル・アプリから抜粋したものです。複製したリポジトリーに含まれているコードを使用してください。
const app = require('express')()
app.get('/', (req, res) => {
res.send("Hello from Appsody!");
});
var port = 3300;
var server = app.listen(port, function () {
console.log("Server listening on " + port);
})
module.exports.app = app;
Dockerfile
とデプロイメント構成ファイルの deploy.yaml
は、前に複製した GitHub リポジトリー内に用意されています。このセクションで説明する手順に従うと、CLI を使ってアプリケーションをクラスターにデプロイできます。
1. デプロイ・ターゲットをセットアップする
最初のステップとして、アクセス可能なコンテナー・レジストリーにアップロードするコンテナー・イメージに対し、正しいデプロイ・ターゲットを設定する必要があります。クラスターを作成したリージョンに応じて、イメージの URL は以下の形式になります。
<REGION_ABBREVIATION>.icr.io/<YOUR_NAMESPACE>/<YOUR_IMAGE_NAME>:<VERSION>
以下のコマンドで、クラスターのレジストリー API エンドポイントに関する詳細を取得します。このコマンドの出力からリージョンの略語がわかります。
ibmcloud cr api
名前空間を取得するには、以下のコマンドを使用します。
ibmcloud cr namespaces
例えば、US-South リージョンのデプロイメント・ターゲットは以下のようになります。
us.icr.io/test_namespace/sampleapp:1.0
2. アプリケーションをデプロイする
以下のコマンドを実行してアプリケーションを Kubernetes クラスター上にデプロイします。
cd ~/deploy-app-using-tekton-on-kubernetes/src
# Build and push it to IBM Cloud Container registry. Following command takes care of build and push to container registry and eliminates the overhead to run docker commands individually.
ibmcloud cr build -t us.icr.io/test_namespace/sampleapp:1.0 .
# Verify whether the image is uploaded to the container registry
ibmcloud cr images
# Update deploy target in deploy.yaml
sed -i '' s#IMAGE#us.icr.io/test_namespace/sampleapp:1.0# deploy.yaml
# Run deploy configuration
kubectl create -f deploy.yaml
# Verify output - pod and service should be up and running
kubectl get pods
kubectl get service
デプロイが正常に完了した後、デプロイ済みアプリケーションに http://<public-ip-of-kubernetes-cluster>:32426/
でアクセスして、IBM Cloud ダッシュボードから Kubernetes クラスターのパブリック IP を取得できます。ポート 32426 は、deploy.yaml
内で nodePort
として定義されています。
上記の手順では、CLI を使用して Kubernetes クラスター上にデプロイする方法を説明しました。デプロイ後にアプリケーションを変更した場合は、この手順を繰り返す必要があります。
これよりも短時間で確実にアプリケーションをビルド、テスト、デプロイするには、このワークフロー全体を自動化します。CI/CD の手法に従えば、開発と手作業によるデプロイ・プロセスのオーバーヘッドを削減できるため、大幅な時間の節約と作業の軽減につながります。
このチュートリアルの次のセクションでは、Tekton Pipelines を使用したビルドとデプロイ手法を説明します。
Tekton Pipelines を使用してアプリケーションをビルドし、IBM Cloud Kubernetes Service 上にデプロイする
Tekton は、CI/CD システムを作成するための強力かつ柔軟な、Kubernetes ネイティブのオープンソース・フレームワークです。Tekton はそのベース部分の実装の詳細を抽象化するため、特定のクラウド・プロバイダーやオンプレミス・システムに依存しないビルド、テスト、デプロイ・プロセスが可能になります。
Tekton Pipelines の使用方法を説明する前に、理解しておく必要のある大まかなコンセプトを紹介します。
Tekton Pipelines プロジェクトは、パイプラインを定義する CRD (Custom Resource Definition: カスタム・リソース定義) を 5 つ追加して Kubernetes API を拡張しています。
- Task: コードのコンパイル、テストの実行、イメージのビルドとデプロイなどの一連のビルド・ステップを定義する個別のジョブです。
- TaskRun: 定義された Task を実行するための CRD です。Task の入力と出力をバインドする TaskRun を使用して、単一の Task を実行できます。
- Pipeline: パイプラインを構成する Task のリストを記述します。
- PipelineRun: Pipeline の実行を定義します。実行する Pipeline と、入力および出力として使用する 1 つ以上の PipelineResource を参照します。
- PipelineResource: Pipeline の入力 (Git リポジトリーなど) または出力 (Docker イメージなど) であるオブジェクトを定義します。
Tekton Pipelines を使用してアプリケーションのビルドとデプロイのワークフローを自動化するには、以下の手順に従います。
1. Tekton Pipelines のコンポーネントを Kubernetes クラスターに追加する
最初のステップとして、以下のコマンドを使用して Tekton Pipelines を Kubernetes クラスターに追加します。
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
上記のコマンドによって Tekton Pipelines がインストールされると、2 つのポッドが作成されます。作成されたポッドを確認するには、以下のコマンドを使用します。必ず、ポッドが実行状態になるまで待ってください。
kubectl get pods --namespace tekton-pipelines
詳細については、Tekton のドキュメントを参照してください。以上の手順が完了すると、Kubernetes クラスターは Tekton Pipelines を実行できる状態になります。それではまず、カスタム・リソースの定義を作成するところから始めましょう。
2. PipelineResource リソース定義を作成する
このチュートリアルで例として使用するアプリケーションのソース・コード、Dockerfile、デプロイメント構成は、前に複製した GitHub リポジトリー内に用意されています。
Git リポジトリーにアクセスするための入力 PipelineResource を作成するには、以下の手順に従います。
以下のようにして、git.yaml
ファイル内に Git リポジトリーを対象とした PipelineResource
を定義します。
- リソースの
type
として Git を指定します。 url
に、Git リポジトリーの URL を指定します。revision
に、使用する Git リポジトリーのブランチ名を指定します。
完全な YAML ファイルは ~/tekton-pipeline/resources/git.yaml
にあります。以下のコマンドを使用して、このファイルをクラスターに適用します。
cd ~/tekton-pipeline
kubectl apply -f resources/git.yaml
3. Task リソース定義を作成する
Task はパイプラインのステップを定義します。Git リポジトリー内のソース・コードを使用してアプリケーションをクラスターにデプロイするために、build-image-from-source
と deploy-to-cluster
という 2 つの Task を定義します。Task リソース定義内では、引数 (args
) として使用するパラメーターを $(inputs.params.<var_name>)
として指定します。
build-image-from-source を定義する
この Task には以下の 2 つのステップが含まれます。
list-src
ステップで、複製されたリポジトリー内のソース・コードをリストアップします。このステップの目的は、ソース・コードが適切に複製されているかどうかを確認することです。build-and-push
ステップで、Dockerfile を使用してコンテナー・イメージをビルドし、ビルドしたイメージをコンテナー・レジストリーにプッシュします。このチュートリアルの例では、イメージをビルドしてプッシュするために Kaniko を使用します。Kaniko の他に、buildah、podman なども使用できます。Kaniko は引数として、Dockerfile の名前と場所、コンテナー・イメージのアップロード先を使用します。
すべての必須パラメーターを渡します。以下のコマンドを使用して、このファイルをクラスターに適用します。
kubectl apply -f task/build-src-code.yaml
deploy-to-cluster を定義する
次は、ビルドされたコンテナー・イメージを使用してアプリケーションをポッド内にデプロイし、サービスとして公開して、どこからでもアプリケーションにアクセスできるようにします。この Task は、~/src/deploy.yaml
にあるデプロイメント構成を使用します。
この Task には以下の 2 つのステップが含まれます。
update-yaml
ステップで、deploy.yaml 内のIMAGE
をコンテナー・イメージの URL で置き換えます。deploy-app
ステップで、アプリケーションを Kubernetes ポッド内にデプロイし、~/src/deploy.yaml
を使用してアプリケーションをサービスとして公開します。このステップではkubectl
を使用して Kubernetes クラスター上にデプロイメント構成を作成します。
すべての必須パラメーターを渡します。
以下のコマンドを使用して、このファイルをクラスターに適用します。
kubectl apply -f task/deploy-to-cluster.yaml
4. Pipeline リソース定義を作成する
Pipeline では、実行する Task をリストアップし、各 Task に必要な入力リソース、出力リソース、入力パラメーターを指定します。Task 間に依存関係がある場合は、その依存関係にも対処します。
tekton-pipeline/resources/pipeline.yaml
の内容は以下のとおりです。
- Pipeline リソース定義では、上述の 2 つの Task (
build-image-from-source
およびdeploy-to-cluster
) を使用します。 - 2 つの Task を順番に実行する必要があるため、
runAfter
キーを使用しています。 - PipelineResource (Git リポジトリー) を
resources
キーで指定します。
すべての必須パラメーターを渡します。Pipeline リソース定義内ではパラメーター値が $(params.imageUrl)
として定義されています。これは、Task リソース定義内の args
とは異なります。以下のコマンドを使用して、このファイルをクラスターに適用します。
kubectl apply -f pipeline/pipeline.yaml
5. PipelineRun リソース定義を作成する
パイプラインを実行するには、PipelineRun
リソース定義を使用して、すべての必須パラメーターを渡す必要があります。PipelineRun
がパイプラインをトリガーし、トリガーされたパイプラインが TaskRun
を作成するといった流れです。同じようにして、すべてのパラメーターが置換されて Task に渡されます。
PipelineRun
内でパラメーターが定義されていない場合、リソース定義自体に含まれる spec
で定義されている params
からデフォルト値が選出されます。例えば、Task build-image-from-source
内で pathToDockerfile
パラメーターが使用されているものの、その値が pipeline-run.yaml
内で指定されていないとします。その場合、Task の実行時には ~/tekton-pipeline/build-src-code.yaml
内で定義されているデフォルト値が使用されます。
PipelineRun
リソース定義に含まれる tekton-pipeline/pipeline/pipeline-run.yaml
の内容は以下のとおりです。
pipeline.yaml
を使用して作成されたパイプラインapplication-pipeline
を参照します。- 入力として使用する PipelineResource
git
を参照します。 - Pipeline と Task の実行時に必要なパラメーターの値を
params
に指定します。 - サービス・アカウントを指定します。
パイプラインを介してイメージをレジストリーにプッシュし、クラスターにデプロイするには、パイプラインにコンテナー・レジストリーとクラスターにアクセスするのに十分な権限が付与されていなければなりません。レジストリーに対する資格情報はサービス・アカウントによって提供されます。したがって、PipelineRun
を実行する前にサービス・アカウントを定義する必要があります。
注: まだ PipelineRun
ファイルを適用しないでください。適用する前に、このファイルに使用するサービス・アカウントを定義する必要があります。
6. サービス・アカウントを作成する
保護されたリソースにアクセスするには、Kubernetes リソースを作成または変更するためのシークレットを使用するサービス・アカウントをセットアップする必要があります。IBM Cloud Kubernetes Service は、IBM Cloud Identity and Access Management (IAM) のロールを使用するように構成されています。IAM のロールによって、ユーザーが IBM Cloud Kubernetes に対して実行できるアクションが決まります。
API キーを生成する
IBM Cloud ダッシュボードを使用して API キーを生成するには、IBM Cloud のドキュメントで説明している手順に従ってください。あるいは、以下の CLI コマンドを使用して API キーを生成することもできます。
ibmcloud iam api-key-create MyKey -d "this is my API key" --file key_file.json
cat key_file.json | grep apikey
apikey
をコピーします。次のステップで、このキーを使用します。
シークレットを作成する
シークレットを作成するには、以下のコードを使用します。APIKEY
は前の手順で生成した API キー、REGISTRY
はクラスターのレジストリー API エンドポイントです。この例でのエンドポイントは、us.icr.io
となります。
kubectl create secret generic ibm-cr-secret --type="kubernetes.io/basic-auth" --from-literal=username=iamapikey --from-literal=password=<APIKEY>
kubectl annotate secret ibm-cr-secret tekton.dev/docker-0=<REGISTRY>
このコードによって、ibm-cr-secret
という名前のシークレットが作成されます。サービス・アカウントの構成ファイル内で、このシークレットを使用します。
構成ファイル tekton-pipeline/pipeline/service-account.yaml
の内容は以下のとおりです。
ServiceAccount
リソースはシークレットibm-cr-secret
を使用します。- シークレット・リソースの定義に従い、新しく作成されたシークレットがサービス・アカウントの API トークンに取り込まれます。
次のステップは、ロールを定義することです。1 つの名前空間内に限って、ロールを使用してリソースに対するアクセス権限を付与できます。ルール内に適切なリソースと apiGroup を含めておかないと アクセスで問題が発生して失敗します。ロール・バインディングにより、ロール内に定義された権限がユーザーまたはユーザーのグループに付与されます。ロール・バインディングには、対象 (ユーザー、グループ、またはサービス・アカウント) のリストと付与するロールへの参照が保持されます。
以下のコマンドを使用して、このファイルをクラスターに適用します。
kubectl apply -f pipeline/service-account.yaml
7. パイプラインを実行する
PipelineRun
を実行する前に、tekton-pipeline/pipeline/pipelinerun.yaml
内の imageUrl
と imageTag
を更新する必要があります。上記のデプロイ・ターゲットをセットアップするセクションを参照して、イメージの URL とタグを確認してください。イメージの URL が us.icr.io/test_namespace/sampleapp で、イメージのタグが 1.0 の場合、構成ファイルを以下のように更新します。
sed -i '' s#IMAGE_URL#us.icr.io/test_namespace/sampleapp# pipeline/pipelinerun.yaml
sed -i '' s#IMAGE_TAG#1.0# pipeline/pipelinerun.yaml
次は、以下のコマンドを使用して PipelineRun
構成を作成します。
kubectl create -f pipeline/pipeline-run.yaml
これにより、パイプラインが作成されて、ターミナル上に以下のメッセージが表示されます。
pipelinerun.tekton.dev/application-pipeline-run created
新しいパイプラインのステータスを確認します。
kubectl describe pipelinerun application-pipeline-run
ステータスによっては、上記のコマンドを再実行する必要があります。出力には暫定的ステータスが以下のように示されます。
Status:
Conditions:
Last Transition Time: 2020-07-09T08:43:53Z
Message: Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 2, Skipped: 0
Reason: Running
Status: Unknown
Type: Succeeded
...
...
Events:
Type Reason Age From Message
---- ------ --- ---- -------
Normal Started 33s PipelineRun
Normal Running 33s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 2, Skipped: 0
「Tasks Completed: 0」と示しているメッセージに注目してください。
パイプラインの実行が完了すると、describe
コマンドの出力として以下の結果が表示されます。
Events:
Type Reason Age From Message
---- ------ --- ---- -------
Normal Started 2m33s PipelineRun
Normal Running 2m33s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 2, Skipped: 0
Normal Running 57s PipelineRun Tasks Completed: 1 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 0
Normal Succeeded 43s PipelineRun Tasks Completed: 2 (Failed: 0, Cancelled 0), Skipped: 0
失敗した場合は、どの Task が失敗したのかが示されます。また、ログを確認するための追加情報も示されます。リソースの詳細 (パイプラインなど) を確認するには、kubectl describe
コマンドを使用して追加情報を取得します。
kubectl describe <resource> <resource-name>
8. 結果を確認する
ポッドとサービスが正常に実行されているかどうかを確認するには、以下のコマンドを実行して、その出力を調べます。
kubectl get pods
# Output should be something like this
NAME READY STATUS RESTARTS AGE
app-59dff7b655-7ggbt 1/1 Running 0 81s
application-pipeline-run-build-image-from-source-2m62g-pod-f4eb96 0/3 Completed 0 119s
application-pipeline-run-deploy-application-kg2jm-pod-89f884 0/3 Completed 0 89s
kubectl get service
# Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app NodePort xxx.xx.xx.xxx <none> 3300:32426/TCP 4m51s
PipelineRun
の実行が正常に完了した後、アプリケーションに http://<public-ip-of-kubernetes-cluster>:32426/
でアクセスして、IBM Cloud ダッシュボードから Kubernetes クラスターのパブリック IP を取得できます。ポート 32426 は、deploy.yaml
内で nodePort
として定義されています。
お疲れさまでした!Tekton Pipelines を使用してアプリケーションを正常にデプロイできました。この手順を通して、Tekton Pipelines の基礎と独自のパイプラインの構築を開始する方法を理解できたはずです。Webhook や Web ベースのダッシュボードなど、利用できる機能は他にもさまざまにあるので、ぜひ、IBM Cloud Kubernetes Service を試して確認してください。
次のステップ
このチュートリアルでは、アプリケーションを Kubernetes にデプロイする手段として Tekton Pipelines を使用する方法とその理由を説明しました。 Tekton は IBM Cloud Pak for Applications に組み込まれています。このオファリングは、コンテナー対応の環境内にビジネス・アプリケーションを迅速かつセキュアに移行する手段となります。Cloud Pak for Applications は Red Hat OpenShift をベースに構築され、Red Hat OpenShift でサポートされています。この開発者向けガイドを参考に、Cloud Pak for Applications の詳細を探って試してみてください。