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コントローラーの費用は不要です。
このシナリオとしてのデモでは、OSSバケットへのZIPファイルのアップロードと、RDS MySQLデータベースへのアップロードレコードの追加を行うファイル管理サービスを構築します。
OSS bucket と ApsaraDB for RDS MySQL の作成プロセスはここでは省略します。
サーバーレス k8s cluster を作成
まず最初に、Alibaba Cloudにサーバーレスk8sクラスターを用意して、次のステップに進む準備をします。 サーバーレスk8sクラスターがOSSバケットやMySQLインスタンスと同じネットワーク下にあることを確認します。
ACRでイメージファイルを準備
Alibaba Cloud Container Registry (ACR) を使ってGit
、BitBucket
、GitLab
などから複数のイメージを構築することができます。
ここでは、サーバーレスのk8sクラスタのターゲットイメージを管理するために、Local Repository
を使用します。ACRの他にも、Docker Official イメージ
や Alibaba Public Cloud イメージ
などを利用することもできます。
イメージファイルの管理を行うために、 Alibaba Cloud Container Registry (ACR) でPersonal editionのインスタンスを作成します。
インスタンスが作成されたら、他の操作を行う前に、Docker Login Password
を設定する必要があります。
- RAMアカウントを使用している場合は、メインアカウントがすでにパスワードを設定しており、そうでない場合はパスワードを設定できませんのでご注意ください。
namespaceら名前空間とリポジトリを作成します。
これで、ソースコードに基づいた関連画像を作成することができました。ここでは、ソースコードとして「local repository」を選択しているので、自分でDockerイメージをビルドして、ACRリポジトリにプッシュします。
Gitなどの他のコードソースを使用している場合は、ACR経由で build docker イメージ をすることができます。
ローカルリポジトリについては、詳細ページに以下のような操作ガイドやサンプルスクリプトがあります。
ここでは、ECSインスタンスを使用して、以下のDockerfileに基づいて関連するDockerイメージを構築します。
# 第一段階:ビルド環境の完成FROM maven:3.6.1-jdk-8-alpine AS builder# pom.xmlとソースコードの追加ADD ./pom.xml pom.xmlADD ./src src/# パッケージ jarRUN 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.jarEXPOSE 8080# jarの名前を自分の好きなように変更するCMD ["java", "-jar", "file_upload_serverless_demo-1.0-SNAPSHOT.jar"]
docker serviceがインストールされ、正常に動作していることを確認します。
なお、Dockerfileではマルチステージビルドを採用しているため、dockerのバージョンは17.05以降である必要があります。
関連するソースコードをECSサーバに置き、そのフォルダに入って、コマンド docker build -t bobdemo/bobdemo:v1 .
でイメージをビルドします。
以下のように イメージファイルを確認し、関連する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
イメージにタグを付けて、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
サーバレスのk8sクラスターにデプロイ
docker runコマンドでは、
-e`オプションを使って、RDSやOSSの接続情報など、アプリケーションで使用する環境変数を定義しています。この点については、サーバーレスのk8sクラスターも関連機能を提供しています。
この辺りについては Config map and secretsセクションを使用します。なお、AccessKey/IdやAccessKeySecretなどの機密情報はsecretsに格納することを強く推奨します。
Deployments Page
に移動し、"Create from Image" ボタンをクリックしてデプロイ作業に入ります。
Pod の状態を確認し、「Access Method」の情報をもとにサービス状況を確認します。
Scale Configuration(スケール設定)
を使って常時稼働するPodの数を設定することもできますが、これを「0」に設定するとサービスが停止し、Podが稼働しなくなります。
knativeを使ってサーバーレスのk8sクラスターにデプロイ
サービスへのビジネスリクエストがないときには、ポッドが稼働していないことを意味します。 上記の手順では、ポッドの数を「0」に設定したため、サービスが停止してしまいました。そのため、Knativeの助けを借りて、これを実現することができました。
Open source のKnativeでは、コスト削減のためにscale-to-zeroの仕組みを採用しています。ASKクラスターにポッドを作成すると、コールドスタートが発生します。しかし、コールドスタート中は、セッションのタイムアウトにより、クラスタがリクエストを処理できないことがあります。一方、Knativeコントローラのインストールに使用されるインフラストラクチャ・リソースに対しては課金されます。
ASK Knative は、オフピーク時にインスタンス数を0にスケールしません。代わりに、ASKはリザーブドインスタンスを使用します。リザーブドインスタンス を使用すると、コールドスタートを低コストで回避できます。また、Knativeのコントローラにお金を払う必要はありません。
knativeをデプロイするためには、まずサーバーレスのk8sクラスターにknativeのコンポーネントをデプロイする必要があります。今回はイベントトリガーを使わないので、処理中にサービス機能を選択するだけで済みます。
knativeがクラスタにデプロイされた後、それを使うことで、 サービスの管理 を行うことができました。
参考として、Knativeは上記の手順で2つのデプロイメントを作成しますが、接尾辞が -reserve
のものは予約済みのインスタンスに基づいています。
あとはデフォルトのドメイン情報を使ってサービスを確認します。
最後に
以上で、Container Service for Kubernetes (ACK)に付帯されてるKnativeによるサーバーレスK8Sをデプロイする方法をご紹介しました。 Knative(=サーバレスk8s)があれば、サーバーのプロビジョニングと管理のタスクが不要になるため、k8sに対する労力がかなり減るはずなので、参考に頂ければ幸いです。