--- title: Tanzu Application PlatformでJavaアプリのイメージをビルドする際にPrivate Maven Repositoryを参照するメモ tags: ["Kubernetes", "Tanzu", "TAP", "Tanzu Build Service", "kpack", "Maven"] categories: ["Dev", "CaaS", "Kubernetes", "TAP"] date: 2022-12-14T04:12:34Z updated: 2023-01-25T14:41:22Z --- TAPでJavaアプリをデプロイする際にPrivate Maven Repositoryを使いたいときのメモ。 キャッシュ用途や社内ライブラリのホストなどに使用する想定。 参考ドキュメントはこちら https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.3/tap/GUID-tanzu-build-service-tbs-workload-config.html ### Maven Repositoryのインストール ここではPrivate Maven Repositoryとして軽量な https://github.com/jenkins-x/bucketrepo を使用する Helm Chartを使ってインストールする。 ``` helm repo add jx3 https://jenkins-x-charts.github.io/repo helm repo update ``` helmでbucketrepoのインストール ``` helm upgrade --install bucketrepo jx3/bucketrepo \ -n bucketrepo \ --set secrets.adminUser.username=admin \ --set secrets.adminUser.password=changeme \ --create-namespace \ --wait ``` Podの確認 ``` $ kubectl get pod -n bucketrepo NAME READY STATUS RESTARTS AGE bucketrepo-bucketrepo-5f8fcd86f7-xxkgz 1/1 Running 0 32s ``` Serviceの確認 ``` $ kubectl get svc -n bucketrepo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE bucketrepo ClusterIP 10.96.131.38 80/TCP 87s ``` ### settings.xmlの用意 ここでは[mirror repository](https://maven.apache.org/settings.html#mirrors)としてbucketrepoを使用する設定をsettings.xmlに記述し、それを次の形式のSecretに設定する。 ```yaml cat < settings-xml.yaml apiVersion: v1 kind: Secret metadata: name: settings-xml type: service.binding/maven stringData: type: maven settings.xml: | bucketrepo admin changeme bucketrepo bucketrepo http://bucketrepo.bucketrepo.svc.cluster.local/bucketrepo *,!sonatype-snapshots EOF ``` Workloadを作成するnamespaceにこのSecretを作成する。 ``` kubectl apply -f settings-xml.yaml -n demo ``` ### Workloadの作成 `buildServiceBindings` paramでsettings.xmlを設定したSecretを参照する。 ``` tanzu apps workload apply tanzu-java-web-app \ -n demo\ --git-repo https://github.com/vmware-tanzu/application-accelerator-samples \ --git-branch main \ --sub-path tanzu-java-web-app \ --type web \ --app tanzu-java-web-app \ --build-env BP_GRADLE_BUILD_FILE=skip-gradle \ --param-yaml buildServiceBindings='[{"name": "settings-xml", "kind": "Secret"}]' \ --annotation autoscaling.knative.dev/minScale=1 \ -y ``` 初回はbucketrepoにキャッシュがないため、mirror repositoryなしの通常ビルドを同じくらいの時間がかかる。 ``` $ kubectl logs -n demo tanzu-java-web-app-build-1-build-pod -c build | grep 'BUILD SUCCESS' -B 1 -A 4 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 02:17 min [INFO] Finished at: 2022-12-14T04:00:19Z [INFO] ------------------------------------------------------------------------ ``` Build Serviceによるキャッシュが消えるように、Workloadを一度削除する。 ``` tanzu apps workload delete -n demo tanzu-java-web-app -y ``` もう一度Workloadを作成 ``` tanzu apps workload apply tanzu-java-web-app \ -n demo\ --git-repo https://github.com/vmware-tanzu/application-accelerator-samples \ --git-branch main \ --sub-path tanzu-java-web-app \ --type web \ --app tanzu-java-web-app \ --param-yaml buildServiceBindings='[{"name": "settings-xml", "kind": "Secret"}]' \ --annotation autoscaling.knative.dev/minScale=1 \ -y ``` Build Serviceによるキャッシュがなくても、10秒でビルド完了。速い! ``` $ kubectl logs -n demo tanzu-java-web-app-build-1-build-pod -c build | grep 'BUILD SUCCESS' -B 1 -A 4 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 10.674 s [INFO] Finished at: 2022-12-14T04:09:05Z [INFO] ------------------------------------------------------------------------ ``` --- テスト時にもこのsettings.xmlを使用するには別途Tekton(Pipeline)側の設定が必要。 こんな感じ ```yaml apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: maven-test-pipeline labels: apps.tanzu.vmware.com/pipeline: test apps.tanzu.vmware.com/language: java spec: params: - name: source-url - name: source-revision tasks: - name: test params: - name: source-url value: $(params.source-url) - name: source-revision value: $(params.source-revision) taskSpec: volumes: - name: settings-xml secret: secretName: settings-xml params: - name: source-url - name: source-revision steps: - name: test image: eclipse-temurin:17 volumeMounts: - mountPath: /opt/maven name: settings-xml readOnly: true script: |- set -ex cd `mktemp -d` curl -s $(params.source-url) | tar -m -xzvf - ./mvnw clean test -V -s /opt/maven/settings.xml ``` ### bucketrepoのTLS対応 ```yaml cat < bucketrepo-ingress.yaml apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer-bootstrap namespace: bucketrepo spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: selfsigned-root-ca namespace: bucketrepo spec: isCA: true commonName: selfsigned-root-ca secretName: selfsigned-root-ca issuerRef: name: selfsigned-issuer-bootstrap kind: Issuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer namespace: bucketrepo spec: ca: secretName: selfsigned-root-ca --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: bucketrepo namespace: bucketrepo annotations: cert-manager.io/issuer: selfsigned-issuer spec: tls: - hosts: - bucketrepo.192-168-228-200.sslip.io secretName: bucketrepo-tls rules: - host: bucketrepo.192-168-228-200.sslip.io http: paths: - path: / pathType: Prefix backend: service: name: bucketrepo port: number: 80 EOF kubectl apply -f bucketrepo-ingress.yaml ``` ``` $ kubectl get ing,secret -n bucketrepo NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/bucketrepo bucketrepo.192-168-228-200.sslip.io 192.168.228.200 80, 443 20s NAME TYPE DATA AGE secret/bucketrepo-config Opaque 1 23m secret/bucketrepo-tls kubernetes.io/tls 3 15s secret/jenkins-x-bucketrepo Opaque 2 23m secret/selfsigned-root-ca kubernetes.io/tls 3 20s secret/sh.helm.release.v1.bucketrepo.v1 helm.sh/release.v1 1 23m ``` ``` kubectl get secret -n bucketrepo bucketrepo-tls -otemplate='{{index .data "ca.crt" | base64decode}}' > bucketrepo-ca.crt ``` ``` $ curl --cacert bucketrepo-ca.crt -v https://bucketrepo.192-168-228-200.sslip.io * Trying 192.168.228.200:443... * Connected to bucketrepo.192-168-228-200.sslip.io (192.168.228.200) port 443 (#0) * ALPN: offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * CAfile: bucketrepo-ca.crt * CApath: none * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 * ALPN: server accepted h2 * Server certificate: * subject: [NONE] * start date: Jul 29 00:04:29 2023 GMT * expire date: Oct 27 00:04:29 2023 GMT * subjectAltName: host "bucketrepo.192-168-228-200.sslip.io" matched cert's "bucketrepo.192-168-228-200.sslip.io" * issuer: CN=selfsigned-root-ca * SSL certificate verify ok. * using HTTP/2 * h2h3 [:method: GET] * h2h3 [:path: /] * h2h3 [:scheme: https] * h2h3 [:authority: bucketrepo.192-168-228-200.sslip.io] * h2h3 [user-agent: curl/7.88.1] * h2h3 [accept: */*] * Using Stream ID: 1 (easy handle 0x12b814800) > GET / HTTP/2 > Host: bucketrepo.192-168-228-200.sslip.io > user-agent: curl/7.88.1 > accept: */* > < HTTP/2 404 < content-type: text/plain; charset=utf-8 < x-content-type-options: nosniff < date: Sat, 29 Jul 2023 00:05:16 GMT < content-length: 19 < x-envoy-upstream-service-time: 1 < server: envoy < 404 page not found ``` ```yaml cat < settings-xml.yaml apiVersion: v1 kind: Secret metadata: name: settings-xml type: service.binding/maven stringData: type: maven settings.xml: | bucketrepo admin changeme bucketrepo bucketrepo https://bucketrepo.192-168-228-200.sslip.io/bucketrepo *,!sonatype-snapshots EOF ``` ``` kubectl apply -f settings-xml.yaml -n demo ``` ```yaml cat < bucketrepo-ca.yaml apiVersion: v1 kind: Secret metadata: name: bucketrepo-ca type: service.binding/ca-certificates stringData: type: ca-certificates ca.crt: | $(cat bucketrepo-ca.crt | sed 's/^/ /g') EOF ``` ``` kubectl apply -f bucketrepo-ca.yaml -n demo ``` ``` $ kubectl get secret -n demo | grep service.binding bucketrepo-ca service.binding/ca-certificates 2 2s settings-xml service.binding/maven 2 3m9s ``` ``` tanzu apps workload apply tanzu-java-web-app \ -n demo\ --git-repo https://github.com/vmware-tanzu/application-accelerator-samples \ --git-branch main \ --sub-path tanzu-java-web-app \ --type web \ --app tanzu-java-web-app \ --build-env BP_GRADLE_BUILD_FILE=skip-gradle \ --param-yaml buildServiceBindings='[{"name": "bucketrepo-ca", "kind": "Secret"}, {"name": "settings-xml", "kind": "Secret"}]' \ --annotation autoscaling.knative.dev/minScale=1 \ -y ```