概要
Knativeは、Kubernetes上でサーバーレスアプリケーションを構築、デプロイ、そして管理を容易にするためのオープンソースプラットフォームです。GoogleやIBMをはじめとする多くの企業が共同で開発し、現在ではCNCF(Cloud Native Computing Foundation)の傘下でプロジェクトが進行しています。
本記事では、Knativeのトラフィック管理機能を活用して、Blue/Greenデプロイを実現する方法について解説します。環境はMinikube上のKubernetesを使用しました。
- 参考リンク
サンプルアプリケーション
まず、Blue/Greenデプロイ対象のサンプルアプリケーションを作成します。
サンプルアプリケーションにはバージョン1
とバージョン2
が存在し、
バージョン1
をBlue(現在稼働中のもの)、バージョン2
をGreen(新規デプロイ対象)として扱います。
サンプルアプリケーションはDocker Hubで公開しています:
https://hub.docker.com/repository/docker/yoshikit/app/general
以下、サンプルアプリケーションの実装およびビルド方法についての記載です。
サンプルアプリケーションのバージョン1
実装:
from bottle import route, run
import math
@route('/')
def index():
return "sample-app-v1"
if __name__ == '__main__':
run(host='0.0.0.0', port=80)
FROM python:3.12-slim
WORKDIR /app
RUN pip install bottle
COPY app_v1.py /app
ENTRYPOINT python app_v1.py
docker build -t app:v1 -f Dockerfile.v1 .
サンプルアプリケーションのバージョン2
実装:
from bottle import route, run
import math
@route('/')
def index():
return "sample-app-v2"
if __name__ == '__main__':
run(host='0.0.0.0', port=80)
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
RUN pip install bottle
COPY app_v2.py /app
ENTRYPOINT python app_v2.py
docker build -t app:v2 -f Dockerfile.v2 .
バージョン1のデプロイ
まず、バージョン1のイメージをKnativeサービスとしてデプロイします:
kn service create app-v1-service \
--image yoshikit/app:v1 \
--port 80
次にデプロイしたアプリのリビジョンを取得し、Route.yamlのマニフェスト適用します。
$ kubectl get configurations app-v1-service -o=jsonpath='{.status.latestCreatedRevisionName}'
app-v1-service-00001
# Route.yaml
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: app
namespace: default
spec:
traffic:
- revisionName: app-v1-service-00001
percent: 100
この作業により、2つのURLで作成したwebアプリにhttp経由でアクセスすることができます。
$ kubectl get route
NAME URL READY REASON
app http://app.default.127.0.0.1.sslip.io True
app-v1-service http://app-v1-service.default.127.0.0.1.sslip.io True
バージョン2の段階的デプロイ
バージョン1の作業と同様にバージョン2のイメージをKnativeサービスとしてデプロイして、
リビジョンを取得します。
kn service create app-v2-service \
--image yoshikit/app:v2 \
--port 80
$ kubectl get configurations app-v2-service -o=jsonpath='{.status.latestCreatedRevisionName}'
app-v2-service-00001
次にhttp://app.default.127.0.0.1.sslip.io
へのリクエストの内、50%がバージョン1、50%がバージョン2に割り当てられるようにRoute.yamlを改修し、再適用します。
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: app
namespace: default
spec:
traffic:
- revisionName: app-v1-service-00001
percent: 50
- revisionName: app-v2-service-00001
percent: 50
以下はRoute.yaml適用後にhttp://app.default.127.0.0.1.sslip.io
へリクエストを1000回投げた結果です。
$ for i in {1..1000}; do curl -s 'http://app.default.127.0.0.1.sslip.io' && echo ''; done > /tmp/count.txt
$ cat /tmp/count.txt | grep 'sample-app-v1' | wc -l
482
$ cat /tmp/count.txt | grep 'sample-app-v2' | wc -l
518
概ね半々になりました。
完全にバージョン2に移行するには、Route.yamlを編集して、app-v2-service-00001
に100%のトラフィックを割り当てる必要があります。
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: app
namespace: default
spec:
traffic:
- revisionName: app-v2-service-00001
percent: 100
備考
今回の記事ではRoute.yamlを編集することによって、
トラフィックの割り当てを行いましたが、以下のようにコマンドでトラフィック設定を変更することも可能です。
kn service update hello \
--traffic hello-00001=50 \
--traffic @latest=50
おわりに
今回、Knativeを使用したBlue/Greenデプロイの手順を実際に試してみました。
バージョン1からバージョン2への移行を段階的に行い、トラフィックの分割を確認することで、
Blue/Greenデプロイメントを行いました。