Tanzu Application Platform (1.4時点)では、こちらのドキュメントに記載されているように、Out of the Box (OOTB) Supply Chainsにて以下のWorkload Typeがサポートサポートされています。
type=web
... スケーラブルなWebアプリケーションを想定したもの。KnativeのServiceリソースをが作成される。Scale to Zero、Zero to Nがサポートされる。type=server
... トラディショナルなWebアプリケーションを想定したもの。K8s標準のDeployment、Serviceリソースが作成される。type=worker
... キューを処理するバックグラウンドアプリケーションを想定したもの。K8s標準のDeploymentが作成される。
今回はここにtype=cronjob
を追加して、K8s標準のCronJobリソースを作成できるようにします。
TAPのWorkloadはCartographerによって管理されています。 Workloadによって作成されるリソースをカスタマイズは、通常はClusterSupplyChainリソースを追加することで行えます。 ただし、1からSupply Chainを作る場合は、
- ソースコードの取得
- ソースコードの脆弱性スキャン
- ソースコードのテスト
- コンテナイメージの取得
- コンテナイメージの脆弱性スキャン
- マニフェストの作成
- マニフェストのパッケージング
などなど、Supply Chainを構成するコンポーネントを定義していく必要があります。(チュートリアルはこちら) TAPのOOTB Supply Chainで定義されているものを再度定義するのは面倒くさいですね。
TAPではOOTB Supply Chainのうち、"マニフェストの作成"の部分だけをカスタマイズできるようになっています。
ドキュメントはこちらです。
ドキュメントではtype=server
のリソースに加えてIngressリソースを作る例を説明しています。
Supply Chainによって生成させたいマニフェストのテンプレートをCartographerのClusterConfigTemplateで定義すれば良いです。
こちらの記事で作成した環境で試します。
目次
ClusterConfigTemplateの定義
CronJobのテンプレートを次のようにClusterConfigTemplateに定義します。
cat <<EOF > cronjob-template.yaml
apiVersion: carto.run/v1alpha1
kind: ClusterConfigTemplate
metadata:
name: cronjob-template
spec:
configPath: .data
lifecycle: mutable
ytt: |
#@ load("@ytt:data", "data")
#@ load("@ytt:yaml", "yaml")
#@ def merge_labels(fixed_values):
#@ labels = {}
#@ if hasattr(data.values.workload.metadata, "labels"):
#@ labels.update(data.values.workload.metadata.labels)
#@ end
#@ labels.update(fixed_values)
#@ return labels
#@ end
#@ def update_config(config):
#@ values = {}
#@ values.update(config)
#@ spec = dict(values["spec"])
#@ spec.update({"restartPolicy": data.values.params.restartPolicy if hasattr(data.values.params, "restartPolicy") else "Never"})
#@ workload = dict(spec["containers"][0])
#@ if hasattr(data.values.params, "command"):
#@ workload.update({"command": data.values.params.command})
#@ end
#@ if hasattr(data.values.params, "args"):
#@ workload.update({"args": data.values.params.args})
#@ end
#@ spec["containers"][0] = workload
#@ values["spec"] = spec
#@ return values
#@ end
#@ def delivery():
apiVersion: batch/v1
kind: CronJob
metadata:
name: #@ data.values.workload.metadata.name
annotations:
kapp.k14s.io/update-strategy: "fallback-on-replace"
ootb.apps.tanzu.vmware.com/servicebinding-workload: "true"
kapp.k14s.io/change-rule: "upsert after upserting servicebinding.io/ServiceBindings"
labels: #@ merge_labels({ "app.kubernetes.io/component": "run", "carto.run/workload-name": data.values.workload.metadata.name })
spec:
schedule: #@ data.values.params.schedule if hasattr(data.values.params, "schedule") else "0 15 * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
metadata:
labels: #@ data.values.config.metadata.labels
spec:
backoffLimit: 0
template: #@ update_config(data.values.config)
#@ end
---
apiVersion: v1
kind: ConfigMap
metadata:
name: #@ data.values.workload.metadata.name + "-cronjob"
labels: #@ merge_labels({ "app.kubernetes.io/component": "config" })
data:
delivery.yml: #@ yaml.encode(delivery())
EOF
K8s標準のCronJobではなく、Argo WorkflowsやFurikoのような拡張スケジューラを使いたい場合もこのClusterConfigTemplateを変更すれば良いです。
このCronJobのmanifestは最終的にDeliverableによってデプロイされるので、Deliverableを管理するService AccountがCronJobを作成する権限を持つ必要があります。
apps.tanzu.vmware.com/aggregate-to-deliverable: "true"
というラベルをClusterRoleにつければ、Deliverableを管理するService Accountにバインドされます。
cat <<EOF > deliverable-with-cronjob.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deliverable-with-cronjob
labels:
apps.tanzu.vmware.com/aggregate-to-deliverable: "true"
rules:
- apiGroups:
- batch
resources:
- cronjobs
verbs:
- get
- list
- watch
- create
- patch
- update
- delete
- deletecollection
EOF
これらをapplyします。
# Muti Cluster構成の場合はBuild Clusterにて
kubectl apply -f cronjob-template.yaml
# Muti Cluster構成の場合はRun Clusterにて
kubectl apply -f deliverable-with-cronjob.yml
最後にWorkload Typeを追加するための設定をtap-values.yaml
に追加します。
ootb_supply_chain_basic: # supply_chainの値がbasicの場合
# or ootb_supply_chain_testing: supply_chainの値がtestingの場合
# or ootb_supply_chain_testing_scanning: supply_chainの値がtesting_scanningの場合
supported_workloads:
- type: web
cluster_config_template_name: config-template
- type: server
cluster_config_template_name: server-template
- type: worker
cluster_config_template_name: worker-template
- type: cronjob
cluster_config_template_name: cronjob-template # <---
tap-values.yaml
の変更を反映させます。
tanzu package installed update -n tap-install tap --values-file tap-values.yaml
更新が完了すると、source-to-url Supply Chainにtype=cronjob
が追加されていることがわかります。
$ tanzu apps cluster-supply-chain get source-to-url
---
# source-to-url: Ready
---
Supply Chain Selectors
TYPE KEY OPERATOR VALUE
expressions apps.tanzu.vmware.com/workload-type In web
expressions apps.tanzu.vmware.com/workload-type In server
expressions apps.tanzu.vmware.com/workload-type In worker
expressions apps.tanzu.vmware.com/workload-type In cronjob
現状はService Bindingの機能が使えません。CronJobへのBindに対応していません。
(Optional) Overlaysによる設定変更
TAPをインストールした後に
kubectl apply -f cronjob-template.yaml
kubectl apply -f deliverable-with-cronjob.yml
を実行してTAPをアップデートするという手順が、宣言的でなくて好みでない場合は、overlay fileとしてClusterConfigTemplateとClusterRoleを追加すれば、
tanzu package install
あるいはtanzu package installed update
でTAPをインストール/更新する際に同時にClusterConfigTemplateとClusterRoleも作成されます。
この場合は、次のようにoverlayとしてClusterConfigTemplateとClusterRoleを作成します。
# Muti Cluster構成の場合はBuild Clusterにて
kubectl -n tap-install create secret generic ootb-templates-cronjob-template \
-o yaml \
--dry-run=client \
--from-file=cronjob-template.yaml \
| kubectl apply -f-
# Muti Cluster構成の場合はRun Clusterにて
kubectl -n tap-install create secret generic tap-auth-deliverable-with-cronjob \
-o yaml \
--dry-run=client \
--from-file=deliverable-with-cronjob.yml \
| kubectl apply -f-
tap-values.yaml
に以下の設定を追加。
package_overlays:
- name: ootb-templates
secrets:
- name: ootb-templates-cronjob-template # Muti Cluster構成の場合はBuild Clusterにて
- name: tap-auth
secrets:
- name: tap-auth-deliverable-with-cronjob # Muti Cluster構成の場合はRun Clusterにて
初回インストールの場合、
tanzu package install tap -p tap.tanzu.vmware.com -v 1.4.2 --values-file tap-values.yaml -n tap-install
更新の場合
tanzu package installed update -n tap-install tap --values-file tap-values.yaml
でtype=cronjob
が使えるようになります。
CronJob Workloadの作成
いろいろなCronJobを作成してみます。
シンプルなCronJob
Kubernetesの公式ドキュメントに載っているサンプルを作成しいてみます。
次のコマンドでCronJobを作るためのWorkloadを作成します。今回は --image
でCronJobで実行するコンテナイメージを指定します。
tanzu apps workload apply \
-n demo \
--type cronjob \
--image ghcr.io/making/busybox \
--param-yaml 'command=["/bin/sh", "-c", "date; echo Hello from TAP"]' \
--param schedule="* * * * *" \
--app cronjob-demo \
cronjob-demo
公式ドキュメントと同じように
--image busybox:1.28
で実行するとImageRepositoryリソースで次のようなエラーが発生しました。unable to pull image "busybox:1.28": Expected an Image but got: application/vnd.docker.distribution.manifest.list.v2+json
次のようなRelocationが必要でした。docker pull busybox docker tag busybox ghcr.io/making/busybox docker push busybox
しばらくするとCronJobが作成され、さらにJobが実行されます。
$ tanzu apps workload get cronjob-demo --namespace demo
📡 Overview
name: cronjob-demo
type: cronjob
namespace: demo
💾 Source
type: image
image: ghcr.io/making/busybox
📦 Supply Chain
name: basic-image-to-url
NAME READY HEALTHY UPDATED RESOURCE
image-provider True True 10m imagerepositories.source.apps.tanzu.vmware.com/cronjob-demo
config-provider True True 10m podintents.conventions.carto.run/cronjob-demo
app-config True True 10m configmaps/cronjob-demo-cronjob
service-bindings True True 10m configmaps/cronjob-demo-with-claims
api-descriptors True True 10m configmaps/cronjob-demo-with-api-descriptors
config-writer True True 10m runnables.carto.run/cronjob-demo-config-writer
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 9m34s imagerepositories.source.apps.tanzu.vmware.com/cronjob-demo-delivery
deployer True True 60s apps.kappctrl.k14s.io/cronjob-demo
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
cronjob-demo-28018560-zdp85 0/1 Completed 0 4s
cronjob-demo-config-writer-l68rw-pod 0/1 Completed 0 10m
To see logs: "tanzu apps workload tail cronjob-demo --namespace demo --timestamp --since 1h"
作成されたCronJobとJobを確認します。
$ kubectl get cronjob,job -n demo
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/cronjob-demo * * * * * False 0 23s 81s
NAME COMPLETIONS DURATION AGE
job.batch/cronjob-demo-28018560 1/1 7s 23s
ログを確認します。時刻が表示されています。
$ kubectl logs -n demo cronjob-demo-28018560-zdp85
Mon Apr 10 08:00:04 UTC 2023
Hello from TAP
schedule
が* * * * *
なので、このJobは毎分実行されます。
確認できたらworkloadを削除します。
tanzu apps workload delete -n demo cronjob-demo
curlを実行するだけのCronJob
次のコマンドでCronJobを作るためのWorkloadを作成します。
tanzu apps workload apply \
-n demo \
--type cronjob \
--image ghcr.io/making/curl \
--param-yaml 'command=["curl"]' \
--param-yaml 'args=["-s", "https://httpbin.org/get"]' \
--param schedule="* * * * *" \
--app hello-curl \
hello-curl
しばらくするとCronJobが作成され、さらにJobが実行されます。
$ tanzu apps workload get hello-curl --namespace demo
📡 Overview
name: hello-curl
type: cronjob
namespace: demo
💾 Source
type: image
image: ghcr.io/making/curl
📦 Supply Chain
name: basic-image-to-url
NAME READY HEALTHY UPDATED RESOURCE
image-provider True True 106s imagerepositories.source.apps.tanzu.vmware.com/hello-curl
config-provider True True 102s podintents.conventions.carto.run/hello-curl
app-config True True 102s configmaps/hello-curl-cronjob
service-bindings True True 102s configmaps/hello-curl-with-claims
api-descriptors True True 102s configmaps/hello-curl-with-api-descriptors
config-writer True True 91s runnables.carto.run/hello-curl-config-writer
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 44s imagerepositories.source.apps.tanzu.vmware.com/hello-curl-delivery
deployer True True 42s apps.kappctrl.k14s.io/hello-curl
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
hello-curl-28018564-2rlgc 0/1 Completed 0 11s
hello-curl-config-writer-k76bd-pod 0/1 Completed 0 101s
To see logs: "tanzu apps workload tail hello-curl --namespace demo --timestamp --since 1h"
作成されたCronJobとJobを確認します。
$ kubectl get cronjob,job -n demo
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/hello-curl * * * * * False 0 42s 76s
NAME COMPLETIONS DURATION AGE
job.batch/hello-curl-28018564 1/1 8s 42s
ログを確認します。curlの実行結果が出力されています。
$ kubectl logs -n demo hello-curl-28018564-2rlgc
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.0.1-DEV",
"X-Amzn-Trace-Id": "Root=1-6433c2f5-5f649b191de9f1ea4e83fb8f"
},
"origin": "220.242.176.124",
"url": "https://httpbin.org/get"
}
確認できたらworkloadを削除します。
tanzu apps workload delete -n demo hello-curl
PythonのScriptを実行するCronJob
次はCronJobで実行するコンテナイメージをソースコードから作成します。 https://github.com/making/hello-python のPythonコードをCloud Native Buildpacksでコンテナイメージ化してCronJob実行します。
次のコマンドでCronJobを作るためのWorkloadを作成します。今回は--git-repo
でソースコードのURLを指定します。
tanzu apps workload apply \
-n demo \
--type cronjob \
--git-repo https://github.com/making/hello-python \
--git-branch main \
--param schedule="* * * * *" \
--app hello-python \
--label apps.tanzu.vmware.com/has-tests=true \
hello-python
しばらくするとCronJobが作成され、さらにJobが実行されます。
$ tanzu apps workload get hello-python --namespace demo
📡 Overview
name: hello-python
type: cronjob
namespace: demo
💾 Source
type: git
url: https://github.com/making/hello-python
branch: main
📦 Supply Chain
name: source-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 4m58s gitrepositories.source.toolkit.fluxcd.io/hello-python
image-provider True True 3m58s images.kpack.io/hello-python
config-provider True True 3m52s podintents.conventions.carto.run/hello-python
app-config True True 3m52s configmaps/hello-python-cronjob
service-bindings True True 3m52s configmaps/hello-python-with-claims
api-descriptors True True 3m52s configmaps/hello-python-with-api-descriptors
config-writer True True 3m38s runnables.carto.run/hello-python-config-writer
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 2m54s imagerepositories.source.apps.tanzu.vmware.com/hello-python-delivery
deployer True True 2m52s apps.kappctrl.k14s.io/hello-python
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
hello-python-28018837-25db8 0/1 Completed 0 32s
hello-python-build-1-build-pod 0/1 Completed 0 4m57s
hello-python-config-writer-ch8z4-pod 0/1 Completed 0 3m50s
作成されたCronJobとJobを確認します。
$ kubectl get cronjob,job -n demo
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/hello-python * * * * * False 0 45s 3m6s
NAME COMPLETIONS DURATION AGE
job.batch/hello-python-28018837 1/1 5s 45s
ログを確認します。
$ kubectl logs -n demo hello-python-28018837-25db8
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.28.2",
"X-Amzn-Trace-Id": "Root=1-643402ed-0e6ea59220b36d3636bd2a41"
},
"origin": "220.242.176.124",
"url": "https://httpbin.org/get"
}
確認できたらworkloadを削除します。
tanzu apps workload delete -n demo hello-python
Spring BatchのJobを実行するCronJob
今後はSpring Batchで実装されたバッチ処理のソースコード https://github.com/making/billing-job をCloud Native Buildpacksでコンテナイメージ化してCronJob実行します。
次のコマンドでCronJobを作るためのWorkloadを作成します。
tanzu apps workload apply \
-n demo \
--type cronjob \
--git-repo https://github.com/making/billing-job \
--git-branch master \
--param schedule="0 15 * * *" \
--app billing-job \
--label apps.tanzu.vmware.com/has-tests=true \
--build-env BP_JVM_VERSION=17 \
--env BPL_JVM_THREAD_COUNT=8 \
--env JAVA_TOOL_OPTIONS=-Dmanagement.health.probes.enabled=false \
billing-job
--env JAVA_TOOL_OPTIONS=-Dmanagement.health.probes.enabled=false
はSpring Boot Actuatorを使った場合に自動で追加されるProbeの設定を向こうにするために追加しています。
ドキュメントはこちら
しばらくするとCronJobが作成されます。00:00 JSTに実行されるようにScheduleしたのでまだJobは作成されません。
$ tanzu apps workload get billing-job --namespace demo
📡 Overview
name: billing-job
type: cronjob
namespace: demo
💾 Source
type: git
url: https://github.com/making/billing-job
branch: master
📦 Supply Chain
name: source-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 4m51s gitrepositories.source.toolkit.fluxcd.io/billing-job
image-provider True True 3m39s images.kpack.io/billing-job
config-provider True True 3m34s podintents.conventions.carto.run/billing-job
app-config True True 3m34s configmaps/billing-job-cronjob
service-bindings True True 3m33s configmaps/billing-job-with-claims
api-descriptors True True 3m33s configmaps/billing-job-with-api-descriptors
config-writer True True 3m17s runnables.carto.run/billing-job-config-writer
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 2m48s imagerepositories.source.apps.tanzu.vmware.com/billing-job-delivery
deployer True True 2m46s apps.kappctrl.k14s.io/billing-job
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
billing-job-build-1-build-pod 0/1 Completed 0 4m52s
billing-job-config-writer-mlhff-pod 0/1 Completed 0 3m33s
To see logs: "tanzu apps workload tail billing-job --namespace demo --timestamp --since 1h"
作成されたCronJobを確認します。
$ kubectl get cronjob,job -n demo
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/billing-job 0 15 * * * False 0 <none> 3m48s
手動でJobを作成します。
kubectl create job -n demo --from cronjob/billing-job test-run
作成されたCronJobとJobを確認します。
$ kubectl get cronjob,job -n demo
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/billing-job 0 15 * * * False 0 <none> 5m12s
NAME COMPLETIONS DURATION AGE
job.batch/test-run 1/1 13s 26s
ログを確認します。
$ kubectl logs -n demo test-run-c9r5d
Setting Active Processor Count to 8
Calculating JVM memory based on 4528180K available memory
For more information on this calculation, see https://paketo.io/docs/reference/java-reference/#memory-calculator
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx4191438K -XX:MaxMetaspaceSize=72549K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 4528180K, Thread Count: 8, Loaded Class Count: 10395, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 124 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Dmanagement.health.probes.enabled="false" -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -XX:+ExitOnOutOfMemoryError -XX:ActiveProcessorCount=8 -XX:MaxDirectMemorySize=10M -Xmx4191438K -XX:MaxMetaspaceSize=72549K -XX:ReservedCodeCacheSize=240M -Xss1M -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -Dorg.springframework.cloud.bindings.boot.enable=true
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.5)
2023-04-10T16:38:45.371Z INFO 1 --- [ main] lol.maki.billing.BillingJobApplication : Starting BillingJobApplication v0.0.1-SNAPSHOT using Java 17.0.6 with PID 1 (/workspace/BOOT-INF/classes started by cnb in /workspace)
2023-04-10T16:38:45.376Z INFO 1 --- [ main] lol.maki.billing.BillingJobApplication : No active profile set, falling back to 1 default profile: "default"
2023-04-10T16:38:46.207Z INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2023-04-10T16:38:46.436Z INFO 1 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:b918459b-19ff-41d4-8f50-d482bba0dee8 user=SA
2023-04-10T16:38:46.440Z INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2023-04-10T16:38:46.829Z INFO 1 --- [ main] lol.maki.billing.BillingJobApplication : Started BillingJobApplication in 1.968 seconds (process running for 2.419)
2023-04-10T16:38:46.832Z INFO 1 --- [ main] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: []
2023-04-10T16:38:46.844Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.845Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
2023-04-10T16:38:46.860Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.860Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE I1 where I1.JOB_NAME = ? and I1.JOB_INSTANCE_ID in (SELECT max(I2.JOB_INSTANCE_ID) from BATCH_JOB_INSTANCE I2 where I2.JOB_NAME = ?)]
2023-04-10T16:38:46.868Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.869Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
2023-04-10T16:38:46.871Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.871Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
2023-04-10T16:38:46.872Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.872Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
2023-04-10T16:38:46.878Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.879Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]
2023-04-10T16:38:46.889Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.889Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT into BATCH_JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:46.892Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing SQL batch update [INSERT into BATCH_JOB_EXECUTION_PARAMS(JOB_EXECUTION_ID, PARAMETER_NAME, PARAMETER_TYPE, PARAMETER_VALUE, IDENTIFYING) values (?, ?, ?, ?, ?)] with a batch size of 100
2023-04-10T16:38:46.893Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT into BATCH_JOB_EXECUTION_PARAMS(JOB_EXECUTION_ID, PARAMETER_NAME, PARAMETER_TYPE, PARAMETER_VALUE, IDENTIFYING) values (?, ?, ?, ?, ?)]
2023-04-10T16:38:46.901Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.902Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO BATCH_JOB_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, JOB_EXECUTION_ID) VALUES(?, ?, ?)]
2023-04-10T16:38:46.904Z INFO 1 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=BillingJob]] launched with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}]
2023-04-10T16:38:46.922Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.923Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:46.928Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.928Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT COUNT(*) FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?]
2023-04-10T16:38:46.932Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.932Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_JOB_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, CREATE_TIME = ?, LAST_UPDATED = ? where JOB_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:46.936Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.936Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT SE.STEP_EXECUTION_ID, SE.STEP_NAME, SE.START_TIME, SE.END_TIME, SE.STATUS, SE.COMMIT_COUNT, SE.READ_COUNT, SE.FILTER_COUNT, SE.WRITE_COUNT, SE.EXIT_CODE, SE.EXIT_MESSAGE, SE.READ_SKIP_COUNT, SE.WRITE_SKIP_COUNT, SE.PROCESS_SKIP_COUNT, SE.ROLLBACK_COUNT, SE.LAST_UPDATED, SE.VERSION, SE.CREATE_TIME, JE.JOB_EXECUTION_ID, JE.START_TIME, JE.END_TIME, JE.STATUS, JE.EXIT_CODE, JE.EXIT_MESSAGE, JE.CREATE_TIME, JE.LAST_UPDATED, JE.VERSION from BATCH_JOB_EXECUTION JE join BATCH_STEP_EXECUTION SE on SE.JOB_EXECUTION_ID = JE.JOB_EXECUTION_ID where JE.JOB_INSTANCE_ID = ? and SE.STEP_NAME = ? order by SE.CREATE_TIME desc, SE.STEP_EXECUTION_ID desc]
2023-04-10T16:38:46.940Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.940Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT COUNT(*) from BATCH_JOB_EXECUTION JE JOIN BATCH_STEP_EXECUTION SE on SE.JOB_EXECUTION_ID = JE.JOB_EXECUTION_ID where JE.JOB_INSTANCE_ID = ? and SE.STEP_NAME = ?]
2023-04-10T16:38:46.942Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.942Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT into BATCH_STEP_EXECUTION(STEP_EXECUTION_ID, VERSION, STEP_NAME, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED, CREATE_TIME) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:46.943Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.943Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO BATCH_STEP_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, STEP_EXECUTION_ID) VALUES(?, ?, ?)]
2023-04-10T16:38:46.945Z INFO 1 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [BilliProcessing]
2023-04-10T16:38:46.946Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.947Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:46.948Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:46.948Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:46.955Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:46.955Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]
2023-04-10T16:38:47.023Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing SQL batch update [INSERT INTO BILL_STATEMENTS (id, first_name, last_name, minutes, data_usage,bill_amount) VALUES (?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:47.023Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO BILL_STATEMENTS (id, first_name, last_name, minutes, data_usage,bill_amount) VALUES (?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:47.027Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.028Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]
2023-04-10T16:38:47.029Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.029Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:47.030Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:47.030Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:47.034Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing SQL batch update [INSERT INTO BILL_STATEMENTS (id, first_name, last_name, minutes, data_usage,bill_amount) VALUES (?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:47.035Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO BILL_STATEMENTS (id, first_name, last_name, minutes, data_usage,bill_amount) VALUES (?, ?, ?, ?, ?, ?)]
2023-04-10T16:38:47.037Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.038Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]
2023-04-10T16:38:47.039Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.039Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:47.040Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:47.040Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:47.042Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.042Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]
2023-04-10T16:38:47.045Z INFO 1 --- [ main] o.s.batch.core.step.AbstractStep : Step: [BilliProcessing] executed in 99ms
2023-04-10T16:38:47.045Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.045Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:47.046Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:47.046Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:47.048Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.048Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_JOB_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE JOB_EXECUTION_ID = ?]
2023-04-10T16:38:47.051Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:47.052Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?]
2023-04-10T16:38:47.055Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2023-04-10T16:38:47.056Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT COUNT(*) FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?]
2023-04-10T16:38:47.057Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2023-04-10T16:38:47.057Z DEBUG 1 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_JOB_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, CREATE_TIME = ?, LAST_UPDATED = ? where JOB_EXECUTION_ID = ? and VERSION = ?]
2023-04-10T16:38:47.069Z INFO 1 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=BillingJob]] completed with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}] and the following status: [COMPLETED] in 129ms
2023-04-10T16:38:47.082Z INFO 1 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2023-04-10T16:38:47.088Z INFO 1 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Native Memory Tracking:
...
確認できたらworkloadを削除します。
tanzu apps workload delete -n demo billing-job
TAPからCronJobを作成されるようになりました。TAPをカスタマイズすることで可能性が広がりますね。
ちなみに、このブログをbackupしてS3に保存するためのWorkloadはこちらです。