Appearance
Infrastructure Adapter をカスタマイズし、機能を追加する
本チュートリアルでは、Qmonus Value Streamを使って、Infrastructure Adapterを編集し、デプロイしたflask-demoアプリケーションの構成を変更し、新たな機能を追加する手順を解説します。
実施する前に、Infrastructure Adapterを作成し、アプリケーションをデプロイするのチュートリアルが完了していることをご確認ください。
以下のステップを通して、Infrastructure Adapterを拡張できることを確認していきます。
- Infrastructure Adapter のComposite機能を用いて、Kubernetes の水平Pod自動スケーリング機能であるHorizontal Pod Autoscaler(HPA)を追加します。
- CI/CDパイプラインを実行して新たにデプロイされるリソースを確認します。
Composite機能について
Composite機能は、既存のInfrastructure Adapterを組み合わせて、新たなInfrastructure Adapterを作成できる機能です。これにより、Infrastructure Adapterの再利用性を向上できます。仕様については、Infrastructure Adapter Specificationを確認ください。
1. Infrastructure Adapterの編集(CLI)
Infrastructure Adapterを作成し、アプリケーションをデプロイするで作成したプライベートリポジトリと、deploy-own-applicationブランチをそのまま利用します。 ここでは、Infrastructure Adapterの特徴の一つである、Composite機能を用いて、Infrastructure AdapterにHPAの機能を追加します。
Metrics Serverの事前準備
HPAを利用するためには、KubernetesクラスタにMetrics Serverがインストールされている必要があります。 以下のコマンドを実行して、Metrics Serverがインストールされていることを確認してください。もしインストールされていない場合は、Metrics Server 公式ドキュメントのREADMEを参照してインストールしてください。
bash
kubectl get deployment -n kube-system | grep -i metrics-server以下のようにInfrastructure Adapterを編集し、アプリケーションの構成を変更します。 まずはComposite元となるhpa.cueを新たに作成します。 ハイライトをしている箇所は、パラメータ化している箇所になります。
bash
# ローカルリポジトリへ移動
cd <repository name>
# deploy-own-applicationブランチに移動
git switch deploy-own-application
# .valuestream ディレクトリに移動
cd .valuestream
# Composite元となるhpa.cueを作成する
vim local/hpa.cuego
package hpa
DesignPattern: {
name: "hpa"
parameters: {
appName: string
minReplicas: int | *1
maxReplicas: int | *3
cpuThreshold: int | *80
}
resources: app: {
hpa: {
apiVersion: "autoscaling/v2"
kind: "HorizontalPodAutoscaler"
metadata: {
name: parameters.appName + "-hpa"
}
spec: {
scaleTargetRef: {
apiVersion: "apps/v1"
kind: "Deployment"
name: parameters.appName
}
minReplicas: parameters.minReplicas
maxReplicas: parameters.maxReplicas
metrics: [{
type: "Resource"
resource: {
name: "cpu"
target: {
type: "Utilization"
averageUtilization: parameters.cpuThreshold
}
}
}]
}
}
}
}前回チュートリアルで作成したflask-app.cueを編集して、作成したhpa.cueをCompositeします。 変更箇所はDIFF、正式なコードはCODEブロックを確認ください。
flask-app.cue内で定義しているmaxReplicasとcpuThresholdはそれぞれ3と50の値が使用されます。flask-app.cue内でminReplicasは未定義のため、hpa.cueで設定したデフォルト値の1が使用されます。hpaStatusパラメータは、HPAを有効にするかどうかを制御するためのフラグであり、trueの場合にのみCompositeされるようにしています。
bash
# Composite機能を使ってInfrastructure Adapterを編集する
vim local/flask-app.cuego
package flaskapp
import (
"github.com/qmonus/sample/local:hpa"
)
DesignPattern: {
name: "flaskapp"
description: "Flask application deployment with Infrastructure Adapter."
parameters: {
k8sNamespace: string
imageName: string
hpaStatus: "true" | *"false"
}
_const: {
#name : "flask-demo"
#port : 80
#targetPort: 5000
}
resources: {
app: {
resource0: {
apiVersion: "apps/v1"
kind: "Deployment"
[...]
}
resource1: {
[...]
}
resource2: {
[...]
}
}
}
composites: [
if parameters.hpaStatus == "true" { // hpaStatusがtrueのときのみCompositeする
{
pattern: hpa.DesignPattern
params: {
appName: _const.#name
maxReplicas: 3
cpuThreshold: 50
}
}
},
]
}go
package flaskapp
import (
"github.com/qmonus/sample/local:hpa"
)
DesignPattern: {
name: "flaskapp"
description: "Flask application deployment with Infrastructure Adapter."
parameters: {
k8sNamespace: string
imageName: string
hpaStatus: "true" | *"false"
}
_const: {
#name : "flask-demo"
#port : 80
#targetPort: 5000
}
resources: {
app: {
resource0: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: _const.#name
namespace: parameters.k8sNamespace
}
spec: {
replicas: 1
selector: {
matchLabels: {
app: _const.#name
}
}
template: {
metadata: {
labels: {
app: _const.#name
}
}
spec: {
containers: [{
name: _const.#name
image: parameters.imageName
ports: [{
containerPort: _const.#targetPort
}]
resources: {
requests: {
cpu: "5m"
memory: "32Mi"
}
limits: {
cpu: "100m"
memory: "128Mi"
}
}
}]
}
}
}
}
resource1: {
apiVersion: "v1"
kind: "Service"
metadata: {
name: _const.#name
namespace: parameters.k8sNamespace
}
spec: {
type: "ClusterIP"
ports: [{
name: "http"
port: 80
protocol: "TCP"
targetPort: _const.#targetPort
}]
selector: {
app: _const.#name
}
}
}
resource2: {
apiVersion: "networking.k8s.io/v1"
kind: "Ingress"
metadata: {
name: _const.#name
namespace: parameters.k8sNamespace
}
spec: {
rules: [{
http: {
paths: [{
path: "/"
pathType: "Prefix"
backend: {
service: {
name: _const.#name
port: {
name: "http"
}
}
}
}]
}
}]
}
}
}
}
composites: [
if parameters.hpaStatus == "true" { // hpaStatusがtrueのときのみCompositeする
{
pattern: hpa.DesignPattern
params: {
appName: _const.#name
maxReplicas: 3
cpuThreshold: 50
}
}
},
]
}この時点でのフォルダ構成は以下のようになります。
<repository name>/
├── .valuestream/
│ ├── cue.mod/
│ │ └── module.cue
│ ├── local/
│ │ ├── flask-app.cue
│ │ └── hpa.cue
│ ├── output/
│ │ ├── manifest.yaml
│ │ └── pipeline.yaml
│ ├── assemblyline-dev.yaml
│ ├── params.json
│ ├── qvs.yaml
│ └── sample-manifests.yaml
├── app.py
├── Dockerfile
└── requirements.txt2. QVS Configの編集 (CLI)
AssemblyLineのDeployment ConfigでHPAの有効/無効を制御するため、qvs.yamlにflask-app.cueで定義したhpaStatusをparams・designPatternsに追加します。
bash
vim qvs.yamlyaml
params:
- name: k8sNamespace
type: string
- name: imageName
type: string
- name: hpaStatus
type: string
modules:
- name: github.com/qmonus/sample
local:
path: .
- name: qmonus.net/adapter/official
designPatterns:
# Infrastructure Adapter
- pattern: github.com/qmonus/sample/local:flaskapp
params:
k8sNamespace: $(params.k8sNamespace)
imageName: $(params.imageName)
hpaStatus: $(params.hpaStatus)
# CI/CD Adapter
- pattern: qmonus.net/adapter/official/pipeline/build:buildkitGcp
- pattern: qmonus.net/adapter/official/pipeline/deploy:simpleyaml
params:
- name: k8sNamespace
type: string
- name: imageName
type: string
- name: hpaStatus
type: string
modules:
- name: github.com/qmonus/sample
local:
path: .
- name: qmonus.net/adapter/official
designPatterns:
# Infrastructure Adapter
- pattern: github.com/qmonus/sample/local:flaskapp
params:
k8sNamespace: $(params.k8sNamespace)
imageName: $(params.imageName)
hpaStatus: $(params.hpaStatus)
# CI/CD Adapter
- pattern: qmonus.net/adapter/official/pipeline/build:buildkitGcp
- pattern: qmonus.net/adapter/official/pipeline/deploy:simple3. Infrastructure Adapterの動作確認(CLI)
本手順では、qvsctl manifest compileコマンドとparams.jsonのパラメータファイルを用いて、Infrastructure Adapterが正しく動作するかどうかを確認します。
params.jsonにhpaStatusパラメータを追加し、値をtrueに設定します。
bash
# params.jsonを作成する(実際にはQmonus Value Streamの中で自動的に作成される)
vim params.jsonjson
{
"params": [
{
"name": "k8sNamespace",
"value": "flask-demo"
},
{
"name": "imageName",
"value": "dummyimage"
},
{
"name": "hpaStatus",
"value": "true"
}
]
}Infrastructure Adapterが正しくコンパイルできるかどうかを確認します。
bash
# qvsctlでKubernetes Manifestにコンパイル
qvsctl manifest compile -m . -c qvs.yaml -p params.json -o output/manifest.yaml
less output/manifest.yaml以下のように、HorizontalPodAutoscalerリソースが追加されていることを確認してください。
yaml
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: flask-demo-hpa
spec:
maxReplicas: 3
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: flask-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-demo
namespace: flask-demo
spec:
replicas: 1
selector:
matchLabels:
app: flask-demo
template:
metadata:
labels:
app: flask-demo
spec:
containers:
- name: flask-demo
image: dummyimage
ports:
- containerPort: 5000
resources:
requests:
cpu: 5m
memory: 32Mi
limits:
cpu: 100m
memory: 128Mi
---
[...]4. Pipeline Manifestの生成および登録 (CLI)
qvs.yamlで定義したhpaStatusパラメータをpipelineに反映させるため、qvsctl pipeline compileコマンドを用いてPipeline ManifestをQmonus Value Streamへ登録します。
bash
# コンパイルする (prefixはApplication名と同一にしてください)
qvsctl pipeline compile -c qvs.yaml --prefix flask-demo -o output/pipeline.yaml
# qvsctl auth コマンド使用して認証する(出力されたurlへアクセスしてください)
qvsctl auth
# Project Nameを取得する
qvsctl project list
# 取得したProject Nameを環境変数に設定する
export projectName=<PROJECT NAME>
# Pipeline Manifestを登録する
qvsctl pipeline apply -p ${projectName} -f output/pipeline.yamlgit add、 git commit、 git pushを行い、リモートリポジトリに変更を反映します。
bash
# リモートリポジトリにpushする
git add --all
git commit -m "Infrastructure Adapter Extension QVS Tutorial"
git push origin deploy-own-application
# コミットIDを控える
git log -15. Deployment Configの設定 (GUI)
AssemblyLine詳細画面より、不足している下記のパラメータを入力します。
- QVS Configのパラメータで定義した
hpaStatus
- 左メニューより、AssemblyLineを選択します。
- 画面中央に表示される
flask-demo-devを選択します。 - Pipeline Stagesに表示されている
deployカードを選択します。 - 画面右に表示される
Edit Deployment Configボタンをクリックします。 - YAMLモードのEditorが表示されますので、Dockerイメージの格納先をYAML形式で入力します。必要なパラメータ一覧は以下の通りです。
- hpaStatus: "true" (これを設定することで、HPAが有効になります)
以下は入力例です。
yaml
hpaStatus: "true"
k8sNamespace: flask-demo
imageRegistryPath: asia-northeast1-docker.pkg.dev/gcp-project/qmonus
imageShortName: flask-demo
imageTag: v0.0.1
pathToContext: .Saveボタンを押下し、deployのInput Parameterが全て緑で表示されていることを確認します。
6. AssemblyLineの実行 (GUI)
Infrastructure Adapterを作成し、アプリケーションをデプロイするで実施したのと同様に、登録したAssemblyLineを実行し、再度、flask-demoアプリケーションをKubernetesにデプロイします。
- 左メニューより、AssemblyLineを選択します。
- 画面中央に表示される
flask-demo-devを選択します。 - Pipelines (Stages) に表示されている
deployカードを選択し、全てのパラメータが埋まっていることを確認します。 - 以下のInput Parameterを入力し、
RUNボタンを押下してAssemblyLineを実行します。- gitRevision: (手順4でのgit commit時のコミットID)
7. デプロイされたアプリケーションの確認 (CLI)
Kubernetesにアクセスして、デプロイに成功したアプリケーションを確認します。
- Podを確認することで、サンプルアプリケーションが正常に動作していることを確認できます。
- HPAリソースを確認することで、追加したHorizontalPodAutoscalerを確認できます。
bash
# GKEクラスタへ接続する
gcloud container clusters get-credentials <クラスタ名> --zone <ノードゾーン名> --project <GCPプロジェクトID>
# Podの確認 (Podが3台でRunningになっていることを確認)
kubectl get pod -n flask-demo
NAME READY STATUS RESTARTS AGE
flask-demo-xxxxxxxxxx-aaaaa 1/1 Running 0 10m
flask-demo-xxxxxxxxxx-bbbbb 1/1 Running 0 30s
flask-demo-xxxxxxxxxx-ccccc 1/1 Running 0 30s
# 新たにCompositeされたHPAを確認する
kubectl get hpa -n flask-demo
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
flask-demo-hpa Deployment/flask-demo 60%/50% 1 3 3 30sIngressに割り当てられたIPアドレスへアクセスし、アプリケーションが正常に動作していることを確認します。
bash
# IngressのEXTERNAL-IPを確認
kubectl get ingress -n flask-demo
# 確認したIPアドレスへアクセス
curl http://${external_ip}; echo
Hello from Qmonus Value StreamCPU使用率について
kubectl get hpa -n flask-demoコマンドで取得したHPAのTARGETSの値がcpuThresholdで設定した閾値(50%)以下となっている場合は、Podがオートスケーリングしません。 その場合は、flask-demo.cueのcomposites内にcpuThresholdをTARGETSの値以下に変更して、再度手順4のPipeline Manifestの生成からやり直してください。
yaml
composites: [
if parameters.hpaStatus == "true" { // hpaStatusがtrueのときのみCompositeする
{
pattern: hpa.DesignPattern
params: {
appName: _const.#name
maxReplicas: 3
cpuThreshold: "<TARGETS以下の値>"
}
}
},
]8. ブランチをマージする
動作確認が完了したら、作業ブランチをmainブランチにマージします。 GitHub の対象リポジトリからマージを実施してください。
- GitHubの対象リポジトリにアクセスします。
- 画面上部の
Pull requestsタブをクリックします。 - deploy-own-applicationブランチのPull Request画面を開きます。
- Pull Request画面で変更内容を確認し、問題がなければ
Merge pull requestボタンをクリックします。 Confirm mergeボタンをクリックしてマージを完了します。- マージ完了後、
Delete branchボタンをクリックして作業ブランチを削除します(任意)。
解説
本チュートリアルではInfrastructure Adapterを作成し、アプリケーションをデプロイするで使用したInfrastructure Adapterを拡張して新たにHorizontalPodAutoscaler(HPA)による水平Pod自動スケーリング機能を追加しました。 このように、Qmonus Value Streamでは、Infrastructure AdapterのComposite機能を用いて、異なるInfrastructure Adapterを再利用できます。
次のステップ
次は以下のチュートリアルに進んで、CI/CD Adapterを作成してみましょう。