はじめに
kubernetes関連の業務を担当していると時折聞いていたknativeについて今回調べて検証してみました。
knativeの検証はサーバレスの部分のみとし、最近はやっているChatGPT (GPT 4o)を利用してできるだけ楽をします。
Knativeとは
Kubernetes上でのサーバーレス環境を実現するためのソフトウェアです。
主なコンポーネントは以下2つ。 (場合によってはFunctionsが含まれて3つとしていることもあるが、ここでは2つとしている)
- Serving
- サーバレスアプリケーションのデプロイを可能にする
- Servingには主に4つのリソースがある
- Services
- Routes
- Configurations
- Revisions
- Eventing
- イベント駆動型のアーキテクチャを構築する際に利用
- 今回は検証の対象外
- Servingの機能を補強するイメージ
- (イベント駆動型のアーキテクチャとサーバレスの相性がいいためKnativeの主なコンポーネントになっている認識です)
- イベント駆動型のアーキテクチャを構築する際に利用
Serving 4つのリソース
- Services
- アプリケーションのデプロイと管理のためのリソース
- Routes, Configurationsを管理する
- Routes
- アプリの異なるバージョン(リビジョン)へのトラフィックを制御
- Configurations
- アプリのデプロイ設定を保持し、更新時に新しいリビジョンを作成
- Revisionsを管理する
- Revisions
- デプロイされた設定を保持
- このリソースは不変
図. Knative Servingコンポーネント
出典:https://knative.dev/docs/concepts/#what-is-knative
上記リソースの関係を文字だけでまとめると以下になります。
Services (管理)-> Routes
Services (管理)-> Configurations
Configurations (管理)-> Revisions
検証準備
ということでKnativeのServingを検証するための環境を構築していきます。
Kubernetes環境を構築するところから始めますが、インストール自体は省略します。具体的なインストール方法については適宜記載するURLを参照ください。
実行環境とソフトウェア
検証に利用したソフトウェアとバージョンを以下に列挙します。また、Container RegistoryにはDocker Hubを使用しました。
実行環境
- Windows 11
- wsl ubuntu
利用ソフトウェア
- knative 1.14.0
- kubernetes v1.30.0
- kubectl v1.29.2
- Docker Desktop 4.30.0
- docker 26.1.1
- kind v0.17.0
- Python 3.11.9
- Flask 2.2.5 (Pythonのweb framework)
GitHub
今回使う資材は以下に置いてあります。
kindを利用してkubernetesクラスタを構築
kindを使ってkubernetesクラスタを構築します。configファイルを準備すればすぐに作成できます。
kindインストールはこちら:https://kind.sigs.k8s.io/docs/user/quick-start/
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: my-cluster
nodes:
- role: control-plane
image: kindest/node:v1.30.0
- role: worker
image: kindest/node:v1.30.0
実行します。
kind create cluster --config .\config.yaml
アプリの作成
ChatGPTに「postメソッドで加算する」、「Flaskを使ったPython」を指定してプログラムを出力し、細かいところを修正しただけです。
最終的に以下のようになりました。(ブラウザからの確認用にhello関数を追加してます)
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/add', methods=['POST'])
def add():
data = request.get_json()
num1 = data.get('num1')
num2 = data.get('num2')
if num1 is None or num2 is None:
return jsonify({"error": "Please provide num1 and num2"}), 400
try:
sum = float(num1) + float(num2)
except ValueError:
return jsonify({"error": "Invalid numbers"}), 400
return jsonify({"sum": sum})
@app.route('/hello', methods=['GET'])
def hello():
return "hello!"
if __name__ == '__main__':
app.run(host='::', port=8080)
動作確認です。想定通り動いていることを確認できました。
python add.py
* Serving Flask app 'add'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (::)
* Running on http://[::1]:8080
Press CTRL+C to quit
curl localhost:8080/hello
hello!
curl -H "Content-Type: application/json" -d '{"num1":"4","num2":"5"}' localhost:8080/add
{"sum":9.0}
Knative検証
Knative インストール
まずはKnativeをインストールするところからやります。
今回はKnative-Operatorを使います。
https://knative.dev/docs/install/operator/knative-with-operators/#install-the-knative-operator
kubectl apply -f https://github.com/knative/operator/releases/download/knative-v1.14.2/operator.yaml
# "knative-operator" があるかを確認
kubectl get deployment -A
Serving リソースを使えるように以下のファイルを適用します。
# knativeserving.yaml
apiVersion: v1
kind: Namespace
metadata:
name: knative-serving
---
apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
name: knative-serving
namespace: knative-serving
kubectl apply -f knativeserving.yaml
コンポーネントがデプロイされるまでに少し時間がかかるので待機。各コンポーネントは以下で確認可能
kubectl get deployment -n knative-serving
NAME READY UP-TO-DATE AVAILABLE AGE
activator 1/1 1 1 7d
autoscaler 1/1 1 1 7d
autoscaler-hpa 1/1 1 1 7d
controller 1/1 1 1 7d
net-contour-controller 1/1 1 1 7d
webhook 1/1 1 1 7d
アプリのデプロイ
Knativeのインストールができたらアプリをデプロイして疎通確認します。
アプリをKubernetes上にデプロイするためにはDocker Image化とそのImageをContainer Registryに格納必要があります。
まずはDockerfileを作成します。
ChatGPTにDockerfileを出力してもらいました。
Flask==2.2.5
FROM python:3.11-slim
# Set the working directory
WORKDIR /app
# Copy the requirements file to the working directory
COPY requirements.txt .
# Install the dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY ./src .
# Expose the port the app runs on
EXPOSE 8080
# Define the command to run the app
CMD ["python", "add.py"]
Imageのビルドをします。今回はDocker Hubを利用するので以下のような形式になります。
docker build -t <username>/web-app:v1
docker push <username>/web-app:v1
※DockerHubの補足。docker imageをアップロードする際にログインが必要な場合は以下の手順でアクセストークンを取得してからdocker imageをアップロードする。
「My Account」 -> 「Security」 -> 「Access Tokens」
# 以下は
docker login -u <username>
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Knativeのマニフェストファイルを作成してアプリをデプロイします。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: test-web-app-serverless
namespace: webapp
spec:
template:
spec:
containers:
- image: <username>/web-app:v1.0.1
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /hello
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
kubectl apply -f add.yaml
これでKnative上にデプロイされたアプリにアクセスできるようになりました。
kubernetes上に疎通確認用のPodを作成します。
kubectl --rm -it run conn-test --image=nginx -- bash
# 疎通確認
curl http://test-web-app-serverless.webapp.svc.cluster.local/hello
hello!
root@nginx:/# curl -H "Content-Type: application/json" -d '{"num1":"4","num2":"5"}' test-web-app-serverless.webapp.svc.cluster.local/add
{"sum":9.0}
検証は以上になります。
今回はネットワークの設定をしていないので、外部からのアクセスができませんが、Ingressを設定することで外からの疎通も可能です。
まとめと余談
knativeの概要を説明し、実際にkubernetes環境の構築からアプリケーションの作成を含め準備しました。
その後、knativeを使って実際にアプリケーションをデプロイし、疎通確認まで行いました。
余談ですが、当初は一言で言えば「knative with wasmをChatGPTに質問するだけで作ってみた」のような記事を書きたかったです。
しかし、Axumを使ってRustのwebappを作成するところは簡単にできたのですが、それをwasmにコンパイルするのがChatGPTに質問するだけでは難しく、またトラブルシュートもRustの知識がかなりないと厳しかったです。Rust on Wasmはあきらめ、Python on Wasmをpy2wasmを使って実装を試みました。
https://wasmer.io/posts/py2wasm-a-python-to-wasm-compiler
余談の余談になってしまうのですが、pythonの場合はwasmを使うよりもpythonを実行した方がはやいんですかね。上記ページではCpython (Native)がwasmを使った実装よりもパフォーマンスがよい。wasm周りに詳しい方いらっしゃいましたら教えてください。。。
py2wasmでのwasm実装は実行時にエラーが出てしまい、デバッグ方法が全く分からなかったのであきらめました。ChatGPTに聞いてもよい返事を得られませんでした。
$ pip install py2wasm
$ py2wasm <myflaskapp>.py -o <myflaskapp>.wasm # <-ここまではうまくいく
$ wasmer run <myflaskapp>.wasm # <- ここで失敗する
という感じでwasmをあきらめて結局knativeの検証となりました。
検証後、knativeについて体系的に理解したいと思い以下の書籍を読みましたが、非常に良かったです。執筆時一部参考にさせていただいてます。
- Knative実践ガイド (impress top gear)
https://www.amazon.co.jp/Knative%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E5%B0%8F%E9%87%8E/dp/4295016357
以上です。最後までお読みいただきありがとうございました。
参考
-
書籍
- Knative実践ガイド (impress top gear)
https://www.amazon.co.jp/Knative%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E5%B0%8F%E9%87%8E/dp/4295016357
- Knative実践ガイド (impress top gear)
-
リンク
- Knative Concepts
https://knative.dev/docs/concepts/ - Knative Operator install
https://knative.dev/docs/install/operator/knative-with-operators/#install-the-networking-layer
- Knative Concepts