IBM Developer Blog

IBM Developer サイトで最新の出来事をフォローし、情報を入手しましょう。

Tekton パイプライン・アーキテクチャーの理解を深めるために、Tekton パイプラインに Python サポートを追加する手順を試してください。


私の同僚の Priti DesaiTekton に取り組み始めてからもう 1 年を超えており、すでに素晴らしい貢献をしています。彼女が楽しそうに作業しているのを見た私は、同じ方向に進むことを決めました。Priti はすでに Java と JavaScript アプリケーション用の Tekton パイプラインを構築していたので、彼女のパイプラインに Python のサポートを加える作業に取り組むことが、Tekton の理解を深めるのに効果的な方法だと思い立ちました。

Tekton とは何か?

Tekton は、Kubernetes クラスター内でネイティブに動作できる、継続的インテグレーションおよび継続的デリバリー (CI/CD) パイプラインです。Tekton の Web サイトに、このオープンソース・プロジェクトの詳しい説明に加え、Tekton を知る上でためになる「What is Tekton?」という動画も提供されています。そうはそうとして、ここでは自分の言葉で Tekton パイプライン・アーキテクチャーについて簡単に説明したいと思います。

Tekton の用語には、「タスク」や「ステップ」など、一般的に使われる場合の意味と混同されやすいものがあることにご注意ください。混同しないよう、このブログ記事では Tekton のリソースの場合には、英語表記を使用して一般的な言葉と区別します。例えば、このブログ記事内で Task は Tekton Task を表し、タスク と表記する場合は通常の意味でのタスクです。

Task と Step

Tekton パイプラインを構成する主なコンポーネントは、YAML で記述された Task、Pipeline、PipelineRun です。Task は作業論理単位であり、関数に例えることができます。つまり、Task ではパラメーターを取ることもできます。各 Task は 1 つ以上の Step からなります。Step が処理を行う実際のコンテナーです。Step はスクリプト、特定のコマンドの実行、あるいは適切な他のコンテナー・ベースの処理にすることができます。Task ごとに固有の Kubernetes Pod があり、この Pod 内で Step ごとの個々のコンテナーが実行されます。プログラミングで例えると、Step は関数を構成する個々のステートメントと言えます。

Pipeline

Pipeline は、最終的な目標を達成するために個々の Task をオーケストレーションする手段です。大まかに言うと、Pipeline はプログラム内の main 関数に例えられます。Pipeline は、その Pipeline を機能させるために必要な他のすべてのリソースを宣言する場所です。Pipeline は一般的な Task のオーケストレーションに過ぎず、Pipeline の実際のインスタンス化ではないことに注意してください。

Tekton Workspace の扱いにも注意が必要です。Workspace を使用すると、複数の Task の間で 1 つの永続ボリュームを共有できるため、それぞれの Task が統一された方法で永続ボリュームを参照できます。そのため、ある Task の結果を別の Task 内で簡単に使用できます。さらに、同じ Task に含まれる Step 間で互いの結果を使用することも可能になります。

PipelineRun

PipelineRun は、特定の目標を達成するために、汎用の Pipeline をインスタンス化したものです。引き続き例えを使用すると、ユーザーからの特定の入力を使用して Pipeline を実際に実行するための仕組みです。基本的に、sed コマンドのソース・コードまたは実行可能ファイルと、結果を得るために実際に実行される sed 's/foo/bar/g' との間の違いに例えられます。

これで、これから説明する Tekton パイプラインの概要を理解していただけたはずです。

Knative Tekton パイプラインに Python を追加する

前述のとおり、私が作成したパイプラインは Priti が文書化した作業をベースに拡張したものです。参照先の作業についての詳細は、Priti が書いた Java および JavaScript のパイプラインについて説明しているブログ記事をご覧ください。彼女が言っているように、このパイプラインを拡張して他の OpenWhisk ランタイムと連動させることができます。それがまさに、私が行ったことです。私はさらに、OpenWhisk Python ランタイムとも連動するように、このパイプラインを拡張しました。理論上、この拡張は OpenWhisk Python の Action を Knative 上でシームレスに実行できることを意味します。

この結果を達成するには、Priti がブログで説明しているのと同じ基本的なアーキテクチャーに従います。

アーキテクチャーを示す図

ラベル 1 と 4 は、Pipeline と PipelineRun 内で指定したリソースに基づいて、Tekton 自体が行う処理であり、Pipeline 内の明示的な Task ではないことにご注意ください。

タスク 1

Python Pipeline での最初のタスクは、requirements.txt ファイルで説明されている必要なアプリの依存関係をインストールすることです。それにはまず、app フォルダー内に仮想環境をインストールする必要があります。どのサード・パーティー・ライブラリーであっても取得してアプリケーションと一緒にパッケージ化できるようにするには、仮想環境をインストールしなければなりません。そのために、基本的な以下の 4 つのステップを行います。

  1. アプリのソースを取得する。
  2. 仮想環境をインストールする。
  3. 仮想環境にインストールされているデフォルトのパッケージをメモする。
  4. pip を使用して必要な依存関係をインストールする。

ステップ 3 が必要になるわけは、システム上にすでにインストールされている標準ライブラリーを不必要にアプリケーションと一緒にパッケージ化するのを回避するためです。こうすれば、次のステップで作成するアーカイブのサイズを小さくして、アーカイブ呼び出し時の起動時間を短縮できます。

OpenWhisk 用の Python パッケージについての詳細は、「Python Packages in OpenWhisk」(James Thomas 著) を読むことをお勧めします。

タスク 2

アプリのソース・コードと必要なサード・パーティー・ライブラリーを zip ファイルにパッケージ化した後は、このパッケージを OpenWhisk ランタイム内で使用できます。

  1. zip ファイルに含めない、仮想環境内のパッケージ (上記のステップ 3 でメモしたパッケージ) のリストを作成します。
  2. 仮想環境内にあるすべてのパッケージのリストを作成し、除外するパッケージをフィルタリングして取り除きます。
  3. 残りのパッケージ、アプリのソース・コード、virtualenv/bin/activate_this.py をまとめて圧縮します。こうすることで、Python がサード・パーティー・ライブラリーをどこで見つければよいかわかるようになります。

タスク 3

次は、OpenWhisk ランタイムの Dockerfile に変更を加えて、必要な環境変数を組み込み、そのイメージをビルドしてから Docker リポジトリーにアップロードします。

  1. zip ファイルを Base64 でエンコードして、__OW_ACTION_CODE 環境変数に格納します。OpenWhisk はこの環境変数に格納されている zip ファイルを解凍して、後で実行できるようにアクション・コードを抽出します。このステップには特に注意が必要です。行が長すぎると、Dockerfile が無効になってしまうためです。最小の pip パッケージでさえも、許容される行の長さをすぐに超えてしまいます。この問題を回避するには、fold コマンドを使用して各行の長さを 80 文字に制限した上で、sed を使用してエンコーディングの各行にエスケープ文字を挿入します。こうすることで、サイズの大きい zip ファイルがバッファーを埋めつくすことがなくなります。

  2. Kaniko Executor を使用して、この新しく作成された Dockerfile をビルドしてから、任意の Docker リポジトリーにアップロードします。

告白すると、タスク 3 のステップ 1 の全貌を理解するのにかなりの時間がかかりました。実際のところ、fold コマンドが必要であることがわかるまで、このコマンドの存在さえ知らなかったのです。fold は優れた Unix ツールの一例です。このツールは長い行を改行で折り返して特定の文字数またはバイト数にすること以外の余計な処理を行いません。このツールと、改行をエスケープして末尾の改行を除去する sed スクリプトを組み合わせて使用すれば、まるで魔法のように、特定のバッファー長に縛られなくなります。Dockerfile 内に大規模な環境変数 (または生成されるあらゆる長い行) を保管する場合、行の制限を超えないようにするためには、このコツを知っておくと役立ちます。こうした手法が文書化されているところはどこにも見つからなかったので、皆さんが同じ問題に突き当たった場合に備え、簡単に説明した次第です。

実行例

James Thomas 氏のブログで紹介しているサンプルを使用して、シンプルな冗談出力プログラムを格納するリポジトリーを作成しました。このリポジトリーをアプリのソースとして指定する PipelineRun を以下のように作成しました。

apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  name: build-app-image
spec:
  serviceAccountName: openwhisk-app-builder
  pipelineRef:
    name: build-openwhisk-app
  workspaces:
    - name: openwhisk-workspace
      persistentVolumeClaim:
        claimName: openwhisk-workspace
  params:
    - name: OW_APP_PATH
      value: ""
    - name: DOCKERFILE
      value: "core/python3Action/Dockerfile"
    - name: OW_ACTION_NAME
      value: "openwhisk-padding-app"
  resources:
    - name: app-git
      resourceSpec:
        type: git
        params:
          - name: url
            value: https://github.com/pwplusnick/jokes-test.git
    - name: runtime-git
      resourceSpec:
        type: git
        params:
          - name: url
            value: https://github.com/apache/openwhisk-runtime-python.git
    - name: app-image
      resourceSpec:
        type: image
        params:
          - name: url
            value: docker.io/pwplusni/openwhisk-jokes

この PipelineRun を、Tekton がインストールされた Kubernetes クラスターに適用しました。openwhisk-build リポジトリー内の必要なアセットはすでに適用されている状態です。数分後にビルドが正常に完了し、Docker イメージ・リポジトリー内に新しいイメージが作成されていることを確認できました。その上で適用したのが、以下のシンプルな Knative サービスです。

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: openwhisk-python-app
  namespace: default
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: docker.io/pwplusni/openwhisk-padding-app:latest

このサービスに対して curl を実行すれば、面白おかしい冗談を出力することもできます。お手本を見せましょう。{"joke": "I had a problem so I thought I'd use Java. Now I have a ProblemFactory."} (冗談: ある問題 (Problem) を手にしていたので Java を使えばよいと思った。そして今 ProblemFactory を手にしています)。この冗談に笑っていただければ幸いです!

まとめ

このブログ記事で提供した情報を機に、好奇心が刺激されて Tekton とその機能を詳しく調べようという気になっていただけたことを願います。Tekton には開発者を温かく迎えてくれるコミュニティーがあるので、ぜひ調べてください!このサンプルを試すために Kubernetes クラスターが必要な場合は、IBM Cloud Kubernetes Service から無料のクラスターを入手できます。これを入手するのにクレジット・カード情報は不要です!最後にいつもの台詞ですが、身を守り、楽しみながら、ハッキングにいそしんでください!