KNativeによるサーバーレスk8s

作成日:2021-06-09

KnativeによるサーバーレスK8Sデプロイメント

本記事では、Container Service for Kubernetes (ACK)に付帯されてるKnativeによるサーバーレスK8Sをデプロイする方法をご紹介します。

今回は Container Service for Kubernetes (ACK) クラスターを使用します。Container Service for Kubernetes (ACK) クラスターは、ノードの購入、運用・保守(O&M)、キャパシティプランニングの手間をかけずに、コンテナ化されたアプリケーションを展開することができます。
ASKはまた、サーバーレスアプリケーションのためのクラウドネイティブでクロスプラットフォームなオーケストレーションエンジンとして利用可能な Knative とも統合されています。Knative APIを呼び出してクラウドリソースを利用するには、ASKクラスタを作成し、クラスタに対してKnativeを有効にするだけで済みます。ちなみにKnativeコントローラーの費用は不要です。

Use Knative in ASK Cluster

このシナリオとしてのデモでは、OSSバケットへのZIPファイルのアップロードと、RDS MySQLデータベースへのアップロードレコードの追加を行うファイル管理サービスを構築します。
OSS bucketApsaraDB for RDS MySQL の作成プロセスはここでは省略します。

サーバーレス k8s cluster を作成

まず最初に、Alibaba Cloudにサーバーレスk8sクラスターを用意して、次のステップに進む準備をします。 サーバーレスk8sクラスターがOSSバケットやMySQLインスタンスと同じネットワーク下にあることを確認します。

Enter Common Buy Page by Create Button
Config Serverless K8S Cluster Confirm Serverless K8S Cluster Configurations 作成プロセスとログの確認 作成プロセスの完了 Create Target Serverless K8S Cluster Successfully

ACRでイメージファイルを準備

Alibaba Cloud Container Registry (ACR) を使ってGitBitBucketGitLabなどから複数のイメージを構築することができます。
ここでは、サーバーレスのk8sクラスタのターゲットイメージを管理するために、Local Repository を使用します。ACRの他にも、Docker Official イメージAlibaba Public Cloud イメージ などを利用することもできます。

サーバーレスK8Sクラスターでサポートされるイメージ

イメージファイルの管理を行うために、 Alibaba Cloud Container Registry (ACR) でPersonal editionのインスタンスを作成します。

パーソナルエディションのインスタンス追加 機能情報の確認と注文の確定

インスタンスが作成されたら、他の操作を行う前に、Docker Login Password を設定する必要があります。

  • RAMアカウントを使用している場合は、メインアカウントがすでにパスワードを設定しており、そうでない場合はパスワードを設定できませんのでご注意ください。

Docker Login Password - Note for RAM Account Docker Login Password - Set Password

namespaceら名前空間とリポジトリを作成します。

Create Namespace Create Namespace Successfully Create Repository - Repository Info Create Repository - Code Source Create Repository Successfully

これで、ソースコードに基づいた関連画像を作成することができました。ここでは、ソースコードとして「local repository」を選択しているので、自分でDockerイメージをビルドして、ACRリポジトリにプッシュします。
Gitなどの他のコードソースを使用している場合は、ACR経由で build docker イメージ をすることができます。
ローカルリポジトリについては、詳細ページに以下のような操作ガイドやサンプルスクリプトがあります。

Operation Guide and Sample Scripts

ここでは、ECSインスタンスを使用して、以下のDockerfileに基づいて関連するDockerイメージを構築します。

# 第一段階:ビルド環境の完成
FROM maven:3.6.1-jdk-8-alpine AS builder
# pom.xmlとソースコードの追加
ADD ./pom.xml pom.xml
ADD ./src src/
# パッケージ jar
RUN mvn clean package
# 第二段階:最小限のランタイム環境
FROM openjdk:8-jre-alpine
# 第一段階のjarをコピーして、jar名を自分のものに変更する
COPY --from=builder target/file_upload_serverless_demo-1.0-SNAPSHOT.jar file_upload_serverless_demo-1.0-SNAPSHOT.jar
EXPOSE 8080
# jarの名前を自分の好きなように変更する
CMD ["java", "-jar", "file_upload_serverless_demo-1.0-SNAPSHOT.jar"]

docker serviceがインストールされ、正常に動作していることを確認します。
なお、Dockerfileではマルチステージビルドを採用しているため、dockerのバージョンは17.05以降である必要があります。

Error Message with Lower Docker Version Using Docker 20.10.7

関連するソースコードをECSサーバに置き、そのフォルダに入って、コマンド docker build -t bobdemo/bobdemo:v1 . でイメージをビルドします。

Put Source Code Folder in Server Build Related Docker Image Build Related Docker Image Successfully

以下のように イメージファイルを確認し、関連するenvパラメータがあれば設定します。

docker run -p 8080:8080 -e MYSQL_HOST=xxx -e MYSQL_USER=xxx -e MYSQL_PASSWORD=xxx -e OSS_ENDPOINT=xxx -e OSS_ACCESSKEYID=xxx -e OSS_ACCESSKEYSECRET=xxx -e OSS_BUCKET=xxx -e OSS_LOCATION=xxx bobdemo/bobdemo:v1

関連Dockerイメージの検証

イメージにタグを付けて、ACRのローカルリポジトリに入れます。

// ACRにログイン
docker login --username=bob@5171341380549220 registry-intl.ap-northeast-1.aliyuncs.com
// タグの追加
docker tag bobdemo/bobdemo:v1 registry-intl.ap-northeast-1.aliyuncs.com/bobdemo/bobdemo:v1
// イメージのプッシュ
docker push registry-intl.ap-northeast-1.aliyuncs.com/bobdemo/bobdemo:v1

Push Related Docker Image Check Related Docker Image in ACR

サーバレスのk8sクラスターにデプロイ

docker runコマンドでは、-e`オプションを使って、RDSやOSSの接続情報など、アプリケーションで使用する環境変数を定義しています。この点については、サーバーレスのk8sクラスターも関連機能を提供しています。
この辺りについては Config map and secretsセクションを使用します。なお、AccessKey/IdやAccessKeySecretなどの機密情報はsecretsに格納することを強く推奨します。

Create Config Map
Create Config Map Successfully
Create Secrets
Create Secrets Successfully

Deployments Page に移動し、"Create from Image" ボタンをクリックしてデプロイ作業に入ります。

デプロイメント - 作成プロセスに入る デプロイメント - 基本情報の設定 デプロイメント - ターゲット画像の選択 デプロイメント - ターゲットタグの選択 デプロイメント - コンテナポートの設定 デプロイメント - 環境変数の設定 デプロイメント - サービスの作成 デプロイメント - サービスの作成に成功 Deployments - Complete Successfully

Pod の状態を確認し、「Access Method」の情報をもとにサービス状況を確認します。

Check Pod Status Access Methodの確認 Access Service by Python Verify Service - OSS Bucket サービスの検証 - RDS MySQL

Scale Configuration(スケール設定) を使って常時稼働するPodの数を設定することもできますが、これを「0」に設定するとサービスが停止し、Podが稼働しなくなります。

希望するポッドの数を0にする Terminate Existing Pod Automatically None Running Pod Service Is Down

knativeを使ってサーバーレスのk8sクラスターにデプロイ

サービスへのビジネスリクエストがないときには、ポッドが稼働していないことを意味します。 上記の手順では、ポッドの数を「0」に設定したため、サービスが停止してしまいました。そのため、Knativeの助けを借りて、これを実現することができました。
Open source のKnativeでは、コスト削減のためにscale-to-zeroの仕組みを採用しています。ASKクラスターにポッドを作成すると、コールドスタートが発生します。しかし、コールドスタート中は、セッションのタイムアウトにより、クラスタがリクエストを処理できないことがあります。一方、Knativeコントローラのインストールに使用されるインフラストラクチャ・リソースに対しては課金されます。
ASK Knative は、オフピーク時にインスタンス数を0にスケールしません。代わりに、ASKはリザーブドインスタンスを使用します。リザーブドインスタンス を使用すると、コールドスタートを低コストで回避できます。また、Knativeのコントローラにお金を払う必要はありません。
knativeをデプロイするためには、まずサーバーレスのk8sクラスターにknativeのコンポーネントをデプロイする必要があります。今回はイベントトリガーを使わないので、処理中にサービス機能を選択するだけで済みます。

Deploy Knative Components Select Serving Features Warning Message During Deployment Process Complete Deployment Process Successfully Check Knative Status

knativeがクラスタにデプロイされた後、それを使うことで、 サービスの管理 を行うことができました。

Knative Service - Enter Creation Processを実行します。 Knative Service - Set Basic Information Knative Service - Set Environment Variables Knative Service - Complete Successfully

参考として、Knativeは上記の手順で2つのデプロイメントを作成しますが、接尾辞が -reserve のものは予約済みのインスタンスに基づいています。

Knative Service - Check Deployments

あとはデフォルトのドメイン情報を使ってサービスを確認します。

Knative Service - Access by Python Knative Service - OSS Bucket Knative Service - RDS MySQL

最後に

以上で、Container Service for Kubernetes (ACK)に付帯されてるKnativeによるサーバーレスK8Sをデプロイする方法をご紹介しました。 Knative(=サーバレスk8s)があれば、サーバーのプロビジョニングと管理のタスクが不要になるため、k8sに対する労力がかなり減るはずなので、参考に頂ければ幸いです。

Bob Bao
この記事を書いた人
Bob Bao
Github Icon
2017年よりAlibaba Cloudサービスに携わる。ETL、ビッグデータ、サーバーレスが得意。PythonやJavaでのプログラミング経験豊富。AlibabaCloud Expert
Close

Alibaba Cloudを始めてみましょう

ソフトバンクは、Alibaba Cloudのアカウント開設から、サービス展開までをお手伝いします。
Hatena