TAPでJavaアプリをデプロイする際にPrivate Maven Repositoryを使いたいときのメモ。
キャッシュ用途や社内ライブラリのホストなどに使用する想定。
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 <none> 80/TCP 87s
settings.xmlの用意
ここではmirror repositoryとしてbucketrepoを使用する設定をsettings.xmlに記述し、それを次の形式のSecretに設定する。
cat <<EOF > settings-xml.yaml
apiVersion: v1
kind: Secret
metadata:
name: settings-xml
type: service.binding/maven
stringData:
type: maven
settings.xml: |
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>bucketrepo</id>
<username>admin</username>
<password>changeme</password>
</server>
</servers>
<mirrors>
<mirror>
<id>bucketrepo</id>
<name>bucketrepo</name>
<url>http://bucketrepo.bucketrepo.svc.cluster.local/bucketrepo</url>
<mirrorOf>*,!sonatype-snapshots</mirrorOf>
</mirror>
</mirrors>
</settings>
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)側の設定が必要。
こんな感じ
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対応
cat <<EOF > 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 <none> 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
cat <<EOF > settings-xml.yaml
apiVersion: v1
kind: Secret
metadata:
name: settings-xml
type: service.binding/maven
stringData:
type: maven
settings.xml: |
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>bucketrepo</id>
<username>admin</username>
<password>changeme</password>
</server>
</servers>
<mirrors>
<mirror>
<id>bucketrepo</id>
<name>bucketrepo</name>
<url>https://bucketrepo.192-168-228-200.sslip.io/bucketrepo</url>
<mirrorOf>*,!sonatype-snapshots</mirrorOf>
</mirror>
</mirrors>
</settings>
EOF
kubectl apply -f settings-xml.yaml -n demo
cat <<EOF > 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