IK.AM

@making's tech note


Tanzu Application Platformでtype=serverのWorkloadに対してIngressを作る

🗃 {Dev/CaaS/Kubernetes/TAP}
🏷 Kubernetes 🏷 Cartographer 🏷 kind 🏷 Tanzu 🏷 TAP 🏷 Carvle 
🗓 Updated at 2023-08-13T06:01:17Z  🗓 Created at 2023-08-12T11:38:16Z   🌎 English Page

⚠️ 本記事の内容はVMwareによってサポートされていません。 記事の内容で生じた問題については自己責任で対応し、 VMwareサポート窓口には問い合わせないでください

Tanzu Application Platform (1.6時点)では、こちらのドキュメントに記載されているように、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=serverでアプリをデプロイした場合、Ingressでアプリを公開したい場合はIngressリソースを何かしらの方法で作成する必要があります。 以下の3つの方法を紹介します。

  • kubectlで直接Ingressリソースを作成する
  • OOTB SupplyChainで作成されるリソースにIngressを追加する
  • Carvel Package Supply Chainを使用する

目次

kubectlで直接Ingressリソースを作成する

まずはサンプルアプリのWorkloadを作成します。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type server \
  -n demo

このWorkloadから作成されるマニフェストは次のコマンドで確認できます。

kubectl get cm -n demo hello-nodejs-server -ojsonpath='{.data.delivery\.yml}'

次の出力が得られます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-nodejs
  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:
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: run
      app.kubernetes.io/part-of: hello-nodejs
      apps.tanzu.vmware.com/workload-type: server
      carto.run/workload-name: hello-nodejs
  template:
    metadata:
      annotations:
        conventions.carto.run/applied-conventions: |-
          appliveview-sample/app-live-view-appflavour-check
          spring-boot-convention/auto-configure-actuators-check
          spring-boot-convention/app-live-view-appflavour-check
        developer.conventions/target-containers: workload
      labels:
        app.kubernetes.io/component: run
        app.kubernetes.io/part-of: hello-nodejs
        apps.tanzu.vmware.com/workload-type: server
        carto.run/workload-name: hello-nodejs
    spec:
      containers:
      - image: ghcr.io/making/workloads/hello-nodejs-demo@sha256:052ffee7966eeda9cf3a0d6a255f70b443ed0c39ab24591ab4b9ab857b30995b
        name: workload
        resources: {}
        securityContext:
          runAsUser: 1000
      serviceAccountName: default
---
apiVersion: v1
kind: Service
metadata:
  name: hello-nodejs
  labels:
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
spec:
  selector:
    app.kubernetes.io/component: run
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server
    carto.run/workload-name: hello-nodejs
  ports:
  - targetPort: 8080
    port: 8080
    name: http

このアプリを例えば、hello-nodejs-demo.tap.192-168-228-200.sslip.io で公開したい場合 (envoyのExternalIPが192.168.228.201である前提です)、次のコマンドでIngressを作成すれば良いです。 TAPのmulti cluster構成の場合は、Runクラスタで実行してください。 ただし、app-editorにはこのコマンドを実行する権限がありませんapp-operatorであれば実行可能です。

  • TLSを使用しない場合
kubectl create ingress hello-nodejs -n demo \
  --rule="hello-nodejs-demo.tap.192-168-228-200.sslip.io/*=hello-nodejs:8080"

アプリにアクセスします。

$ curl -sv http://hello-nodejs-demo.tap.192-168-228-200.sslip.io
> GET / HTTP/1.1
> Host: hello-nodejs-demo.tap.192-168-228-200.sslip.io
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/1.1 200 OK
< x-powered-by: Express
< content-type: text/html; charset=utf-8
< content-length: 14
< etag: W/"e-LQS9yOYOT+WGITCx9XjB8GC9nDI"
< date: Thu, 10 Aug 2023 06:03:01 GMT
< x-envoy-upstream-service-time: 5
< server: envoy
< 
Hello World!!
  • TLSの証明書をcert-managerで発行する場合
kubectl create ingress hello-nodejs -n demo \
  --rule="hello-nodejs-demo.tap.192-168-228-200.sslip.io/*=hello-nodejs:8080,tls=hello-nodejs-tls" \
  --annotation cert-manager.io/cluster-issuer=tap-ingress-selfsigned

上記のannotationはtap-ingress-selfsignedというClusterIssuerが存在することが前提です。

アプリにアクセスします。

$ curl -skv https://hello-nodejs-demo.tap.192-168-228-200.sslip.io
> GET / HTTP/2
> Host: hello-nodejs-demo.tap.192-168-228-200.sslip.io
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/2 200 
< x-powered-by: Express
< content-type: text/html; charset=utf-8
< content-length: 14
< etag: W/"e-LQS9yOYOT+WGITCx9XjB8GC9nDI"
< date: Thu, 10 Aug 2023 06:03:53 GMT
< x-envoy-upstream-service-time: 5
< server: envoy
< 
Hello World!!
kubectl create ingress hello-nodejs -n demo \
  --rule="hello-nodejs-demo.tap.192-168-228-200.sslip.io/*=hello-nodejs:8080,tls=tap-default-tls" \
  --annotation projectcontour.io/tls-cert-namespace=tanzu-system-ingress

上記のannotationはtanzu-system-ingress namespaceに*.tap.192-168-228-200.sslip.ioに対するWildcard証明書を含むtap-default-tlsというSecretが存在し、TLSCertificateDelegationで参照可能になっていることが前提です。

kubectl createを実行する代わりにYAMLを管理したい場合は、上記のコマンドに--dry-run=client -oyamlオプションをつければ良いです。 また、Contour以外のIngressを使用したい場合は--classでIngressClass名を指定すれば良いです。

例えば次のようにTAPのRunクラスタにingress-nginxがインストールされている場合、

$ kubectl get ingressclass
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       3m30s

次のように--class=nginxをつければ良いです。 (ingress-nginx-controllerのExternalIPが192.168.228.201である前提です。)

kubectl create ingress hello-nodejs -n demo \
  --rule="hello-nodejs-demo.tap.192-168-228-201.sslip.io/*=hello-nodejs:8080" \
  --class=nginx

アプリにアクセスします。

$ curl -sv http://hello-nodejs-demo.tap.192-168-228-201.sslip.io
> GET / HTTP/1.1
> Host: hello-nodejs-demo.tap.192-168-228-201.sslip.io
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 10 Aug 2023 06:11:16 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 14
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"e-LQS9yOYOT+WGITCx9XjB8GC9nDI"
< 
Hello World!!

この方法はTAPのカスタマイズが不要で、シンプルである反面、デフォルトでは開発者(app-editor)がIngressを作成できないので、app-operatorに作成を依頼するか、次のようにapp-editorに権限を追加する必要があります。

kubectl apply -f -  << 'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: app-editor-with-ingress
  labels:
    apps.tanzu.vmware.com/aggregate-to-app-editor: "true"
rules:
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
  - create
  - patch
  - update
  - delete
  - deletecollection
EOF

また、Ingressリソースを別途管理する手間が発生します。 次のOOTB SupplyChainで作成されるリソースにIngressを追加する方法であれば、これらの課題は解決されます。

OOTB SupplyChainで作成されるリソースにIngressを追加する

以下のドキュメントに書かれている通り、ClusterConfigTemplateをカスタマイズすることでWorkloadから生成されるマニフェストにIngressを追加することができます。
https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.6/tap/workloads-server.html#define-a-workload-type-that-exposes-server-workloads-outside-the-cluster-5

この場合、type=server-ingressのように新規のWorkload Typeを追加するか、既存のtype=serverにIngressを追加するかの選択肢があります。

新規のWorkload Typeを追加する

既存のserver-templateをコピーして、server-ingress-templateを作成します。

server-ingress-templateを以下に定義します。server-templateからの差分は<------------ Added ---------------->の部分です。

apiVersion: carto.run/v1alpha1
kind: ClusterConfigTemplate
metadata:
  name: server-ingress-template
spec:
  configPath: .data

  params:
  - name: ports
    default:
    - containerPort: 8080
      port: 8080
      name: http

  healthRule:
    alwaysHealthy: {}

  ytt: |
    #@ load("@ytt:data", "data")
    #@ load("@ytt:yaml", "yaml")
    #@ load("@ytt:struct", "struct")
    #@ load("@ytt:assert", "assert")

    #@ 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 intOrString(v):
    #@   return v if type(v) == "int" else int(v.strip()) if v.strip().isdigit() else v
    #@ end

    #@ def merge_ports(ports_spec, containers):
    #@   ports = {}
    #@   for c in containers:
    #@     for p in getattr(c, "ports", []):
    #@       ports[p.containerPort] = {"targetPort": p.containerPort, "port": p.containerPort, "name": getattr(p, "name", str(p.containerPort))}
    #@     end
    #@   end
    #@   for p in ports_spec:
    #@     targetPort = getattr(p, "containerPort", p.port)
    #@     type(targetPort) in ("string", "int") or fail("containerPort must be a string or int")
    #@     targetPort = intOrString(targetPort)
    #@     
    #@     port = p.port
    #@     type(port) in ("string", "int") or fail("port must be a string or int")
    #@     port = int(port)
    #@     ports[p.port] = {"targetPort": targetPort, "port": port, "name": getattr(p, "name", str(p.port))}
    #@   end
    #@   return ports.values()
    #@ end

    #! <------------ Added ---------------->
    #@ def merge_annotations(fixed_values):
    #@   annotations = {}
    #@   if hasattr(data.values.params, "annotations"):
    #@     annotations.update(data.values.params.annotations)
    #@   end
    #@   annotations.update(fixed_values)
    #@   return annotations
    #@ end
    #! <------------ Added ---------------->
  
    #@ def delivery():
    ---
    apiVersion: apps/v1
    kind: Deployment
    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:
      selector:
        matchLabels: #@ data.values.config.metadata.labels
      template: #@ data.values.config
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: #@ data.values.workload.metadata.name
      labels: #@ merge_labels({ "app.kubernetes.io/component": "run", "carto.run/workload-name": data.values.workload.metadata.name })
    spec:
      selector: #@ data.values.config.metadata.labels
      ports:
      #@ hasattr(data.values.params, "ports") and len(data.values.params.ports) or assert.fail("one or more ports param must be provided.")
      #@ declared_ports = {}
      #@ if "ports" in data.values.params:
      #@   declared_ports = data.values.params.ports
      #@ else:
      #@   declared_ports = struct.encode([{ "containerPort": 8080, "port": 8080, "name": "http"}])
      #@ end
      #@ for p in merge_ports(declared_ports, data.values.config.spec.containers):
      - #@ p
      #@ end
    #! <------------ Added ---------------->
    #@ ingress_domain = "tap.192-168-228-200.sslip.io"
    #@ cluster_issuer = "tap-ingress-selfsigned"
    #@ port = intOrString(data.values.params.ports[0].port) if hasattr(data.values.params, "ports") and len(data.values.params.ports) > 0 and hasattr(data.values.params.ports[0], "port") else 8080
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: #@ data.values.workload.metadata.name
      annotations: #@ merge_annotations({"cert-manager.io/cluster-issuer": cluster_issuer, "kapp.k14s.io/change-rule": "upsert after upserting Services"})
      labels: #@ merge_labels({ "app.kubernetes.io/component": "run", "carto.run/workload-name": data.values.workload.metadata.name })
    spec:
      tls:
        - secretName: #@ "{}-tls".format(data.values.workload.metadata.name)
          hosts:
          - #@ "{}-{}.{}".format(data.values.workload.metadata.name, data.values.workload.metadata.namespace, ingress_domain)
      rules:
      - host: #@ "{}-{}.{}".format(data.values.workload.metadata.name, data.values.workload.metadata.namespace, ingress_domain)
        http:
          paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: #@ data.values.workload.metadata.name
                port:
                  number: #@ port
    #! <------------ Added ---------------->
    #@ end

    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: #@ data.values.workload.metadata.name + "-server"
      labels: #@ merge_labels({ "app.kubernetes.io/component": "config" })
    data:
      delivery.yml: #@ yaml.encode(delivery())

この内容をserver-ingress-template.yamlに保存し、applyします。TAPのmulti cluster構成の場合は、Buildクラスタで実行してください。

kubectl apply -f server-ingress-template.yaml

またSupplyChainから生成されたIngressリソースをDeliverableが作成できるように、次のコマンドでClusterRoleを追加します。TAPのmulti cluster構成の場合は、Runクラスタで実行してください。

cat << 'EOF' > deliverable-with-ingress.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deliverable-with-ingress
  labels:
    apps.tanzu.vmware.com/aggregate-to-deliverable: "true"
rules:
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
  - create
  - patch
  - update
  - delete
  - deletecollection
EOF
kubectl apply -f deliverable-with-ingress.yaml

tap-values.yamlに以下の内容を追加します。

ootb_supply_chain_basic:
  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: server-ingress #! <--- Added
      cluster_config_template_name: server-ingress-template

設定するキーはootb_supply_chain_<suppy_chain>であり、上記の例はsupply_chain: basicの場合です。

次のコマンドでTAPを更新します。TAPのmulti cluster構成の場合は、Buildクラスタで実行してください。

tanzu package installed update -n tap-install tap --values-file tap-values.yaml

次のコマンドを実行して、利用可能なWorkload Typeにserver-ingressが追加されたことを確認してください。

$ 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         server-ingress
   expressions   apps.tanzu.vmware.com/carvel-package-workflow   DoesNotExist

次のコマンドで、type=server-ingressのWorkloadを作成します。

kubectl delete ingress hello-nodejs -n demo # if exists
tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type server-ingress \
  -n demo

次のコマンドでWorkloadによって作成されたYAMLを確認できます。

kubectl get cm -n demo hello-nodejs-server -ojsonpath='{.data.delivery\.yml}'

次のようなYAMLが出力されます。Ingressが追加されています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-nodejs
  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:
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server-ingress
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: run
      app.kubernetes.io/part-of: hello-nodejs
      apps.tanzu.vmware.com/workload-type: server-ingress
      carto.run/workload-name: hello-nodejs
  template:
    metadata:
      annotations:
        conventions.carto.run/applied-conventions: |-
          appliveview-sample/app-live-view-appflavour-check
          spring-boot-convention/auto-configure-actuators-check
          spring-boot-convention/app-live-view-appflavour-check
        developer.conventions/target-containers: workload
      labels:
        app.kubernetes.io/component: run
        app.kubernetes.io/part-of: hello-nodejs
        apps.tanzu.vmware.com/workload-type: server-ingress
        carto.run/workload-name: hello-nodejs
    spec:
      containers:
      - image: ghcr.io/making/workloads/hello-nodejs-demo@sha256:052ffee7966eeda9cf3a0d6a255f70b443ed0c39ab24591ab4b9ab857b30995b
        name: workload
        resources: {}
        securityContext:
          runAsUser: 1000
      serviceAccountName: default
---
apiVersion: v1
kind: Service
metadata:
  name: hello-nodejs
  labels:
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server-ingress
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
spec:
  selector:
    app.kubernetes.io/component: run
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server-ingress
    carto.run/workload-name: hello-nodejs
  ports:
  - targetPort: 8080
    port: 8080
    name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-nodejs
  annotations:
    cert-manager.io/cluster-issuer: tap-ingress-selfsigned
    kapp.k14s.io/change-rule: upsert after upserting Services
  labels:
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server-ingress
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
spec:
  tls:
  - secretName: hello-nodejs-tls
    hosts:
    - hello-nodejs-demo.tap.192-168-228-200.sslip.io
  rules:
  - host: hello-nodejs-demo.tap.192-168-228-200.sslip.io
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: hello-nodejs
            port:
              number: 8080

Supply ChainからIngressリソースが作成されたことを確認できます。

$ kubectl get ing -n demo --show-labels
NAME           CLASS    HOSTS                                            ADDRESS           PORTS     AGE   LABELS
hello-nodejs   <none>   hello-nodejs-demo.tap.192-168-228-200.sslip.io   192.168.228.200   80, 443   96s   app.kubernetes.io/component=run,app.kubernetes.io/part-of=hello-nodejs,apps.tanzu.vmware.com/workload-type=server-ingress,carto.run/workload-name=hello-nodejs,kapp.k14s.io/app=1691647255322645686,kapp.k14s.io/association=v1.4aa1edeb0a707e6a5e81cfde4668a7b0
$ curl -ks https://hello-nodejs-demo.tap.192-168-228-200.sslip.io 
Hello World!!

ClusterConfigTemplateの追加とClusterRoleの追加をtanzu package installのタイミングでまとめて行いたい場合は、次のようにoverlayとしてファイルをSecretに登録すれば良いです。

# Muti Cluster構成の場合はBuild Clusterにて
kubectl -n tap-install create secret generic ootb-templates-server-ingress-template \
  -o yaml \
  --dry-run=client \
  --from-file=server-ingress-template.yaml \
  | kubectl apply -f-
# Muti Cluster構成の場合はRun Clusterにて
kubectl -n tap-install create secret generic tap-auth-deliverable-with-ingress \
  -o yaml \
  --dry-run=client \
  --from-file=deliverable-with-ingress.yaml \
  | kubectl apply -f-

tap-values.yamlに以下の設定を追加。

package_overlays:
- name: ootb-templates
  secrets:
  - name: ootb-templates-server-ingress-template # Muti Cluster構成の場合はBuild Clusterにて
- name: tap-auth
  secrets:
  - name: tap-auth-deliverable-with-ingress # Muti Cluster構成の場合はRun Clusterにて

TAPを更新します。

tanzu package installed update -n tap-install tap --values-file tap-values.yaml

既存のtype=serverにIngressを追加する

新規のWorkload Typeを追加する方法はTemplateを自分で管理できるので、カスタマイズしやすい一方、 コピー元のtype=serverのテンプレートが更新されたら、更新内容を反映させる必要があります。

次のoverlayを適用して、既存のClusterConfigTemplate server-templateを変更します。

apiVersion: v1
kind: Secret
metadata:
  name: ootb-templates-overlay-ingress
  namespace: tap-install
type: Opaque
stringData:
  overlay-ingress.yaml: |
    #@ def merge_annotations_def_string():
    #@   return '''
    #@ #@ def merge_annotations(fixed_values):
    #@ #@   annotations = {}
    #@ #@   if hasattr(data.values.params, "annotations"):
    #@ #@     annotations.update(data.values.params.annotations)
    #@ #@   end
    #@ #@   annotations.update(fixed_values)
    #@ #@   return annotations
    #@ #@ end
    #@ '''
    #@ end
    
    #@ load("@ytt:overlay", "overlay")
    #@ load("@ytt:data", "data")
    #@ ingress_domain = data.values.ingress_domain
    #@ cluster_issuer = data.values.cluster_issuer
    #@overlay/match by=overlay.subset({"kind":"ClusterConfigTemplate", "metadata": {"name": "server-template"}})
    ---
    spec:
      #@overlay/replace via=lambda left, right: "{}\n{}".format(left.replace("#@ def delivery():", '\n'.join([ merge_annotations_def_string(), "#@ def delivery():"])), '\n'.join(['  {}'.format(x) for x in right.replace("INGRESS_DOMAIN", ingress_domain).replace("CLUSTER_ISSUER", cluster_issuer).split('\n')]))
      ytt: |
        #@yaml/text-templated-strings
        ingress.yml: |
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: (@= data.values.workload.metadata.name @)
            annotations:
          (@= '\n'.join(['    {}'.format(x) for x in yaml.encode(merge_annotations({ "cert-manager.io/cluster-issuer": "CLUSTER_ISSUER", "kapp.k14s.io/change-rule": "upsert after upserting Services" })).split('\n')]) @)
            labels: 
          (@= '\n'.join(['    {}'.format(x) for x in yaml.encode(merge_labels({ "app.kubernetes.io/component": "run", "carto.run/workload-name": data.values.workload.metadata.name })).split('\n')]) @)
          spec:
            tls:
              - secretName: (@= data.values.workload.metadata.name @)-tls
                hosts:
                - (@= "{}-{}.{}".format(data.values.workload.metadata.name, data.values.workload.metadata.namespace, "INGRESS_DOMAIN") @)
            rules:
            - host: (@= "{}-{}.{}".format(data.values.workload.metadata.name, data.values.workload.metadata.namespace, "INGRESS_DOMAIN") @)
              http:
                paths:
                - pathType: Prefix
                  path: /
                  backend:
                    service:
                      name: (@= data.values.workload.metadata.name @)
                      port:
                        number: (@= str(data.values.params.ports[0].port) if hasattr(data.values.params, "ports") and len(data.values.params.ports) > 0 and hasattr(data.values.params.ports[0], "port") else "8080" @)

このファイルをootb-templates-overlay-ingress.yamlに保存して、applyします。

kubectl apply -f ootb-templates-overlay-ingress.yaml

tap-values.yamlに次の設定を追加します。

ootb_templates:
  ingress_domain: tap.192-168-228-200.sslip.io
  cluster_issuer: tap-ingress-selfsigned

package_overlays:
- name: ootb-templates # Muti Cluster構成の場合はBuild Clusterにて
  secrets:
  - name: ootb-templates-overlay-ingress

TAPを更新します。

tanzu package installed update -n tap-install tap --values-file tap-values.yaml

type=serverでWorkloadを作成します。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type server \
  -n demo

次のコマンドでWorkloadによって作成されたIngressのYAMLを確認できます。

kubectl get cm -n demo hello-nodejs-server -ojsonpath='{.data.ingress\.yml}'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-nodejs
  annotations:
    cert-manager.io/cluster-issuer: tap-ingress-selfsigned
    kapp.k14s.io/change-rule: upsert after upserting Services
    
  labels: 
    app.kubernetes.io/part-of: hello-nodejs
    apps.tanzu.vmware.com/workload-type: server
    app.kubernetes.io/component: run
    carto.run/workload-name: hello-nodejs
    
spec:
  tls:
    - secretName: hello-nodejs-tls
      hosts:
      - hello-nodejs-demo.tap.192-168-228-200.sslip.io
  rules:
  - host: hello-nodejs-demo.tap.192-168-228-200.sslip.io
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: hello-nodejs
            port:
              number: 8080

Supply ChainからIngressリソースが作成されたことを確認できます。

$ kubectl get ing -n demo --show-labels
NAME           CLASS    HOSTS                                            ADDRESS           PORTS     AGE    LABELS
hello-nodejs   <none>   hello-nodejs-demo.tap.192-168-228-200.sslip.io   192.168.228.200   80, 443   154m   app.kubernetes.io/component=run,app.kubernetes.io/part-of=hello-nodejs,apps.tanzu.vmware.com/workload-type=server,carto.run/workload-name=hello-nodejs,kapp.k14s.io/app=1691647255322645686,kapp.k14s.io/association=v1.4aa1edeb0a707e6a5e81cfde4668a7b0

新規のWorkload Typeを追加する場合に比べて、既存のWorkload Typeを更新する方法は、TAPのバージョンアップでコピー元のtemplateの変更を自動でマージするので、変更を反映させる手間が入りません。 一方で、overlayが次のバージョンでも機能するかどうかはわかりません。バージョンアップ時には必ず動作検証する必要があります。

Supply ChainからIngressを生成する方法は、自動でIngressリソースができるので便利なのですが、Workloadを作る時点で作成されるIngressのhost名が固定されてしまう点です。 今回の例だとIngressリソースにhello-nodejs-demo.tap.192-168-228-200.sslip.ioがハードコードされます。 アプリが動作する環境(Runクラスタなど)が1環境の場合は問題ないのですが、複数のRunクラスタにデプロイしたい場合は問題になります。Supply Chainから生成されるマニフェストを環境に応じてパラメータで変更することができません。

WorkaroundはGitopsモードを利用して、別のRunクラスタに対しては次のようなoverlayをGitレポジトリ上に作れば、デプロイ時にhost名が上書きされます。

#@ load("@ytt:overlay", "overlay")
#@ ingress_domain = "hello-nodejs-demo.production.example.com"
#@overlay/match by=overlay.subset({"kind":"Ingress"})
---
spec:
  tls:
  #@overlay/match by=overlay.index(0)
  - hosts:
    #@overlay/match by=overlay.index(0)
    - #@ ingress_domain
  rules:
  #@overlay/match by=overlay.index(0)
  - host: #@ ingress_domain

Carvel Package Supply Chainを使用する

Supply Chainから生成されるマニフェストを環境に応じてパラメータで変更することができないという課題を解決するのがCarvel Package Supply Chainsです。 TAP 1.5でAlphaバージョンとして導入され、TAP 1.6時点ではBetaバージョンです。まだ、実験的な機能で制約が多く、 OOTB Basic Supply Chainでのみ利用可能です。

Carvel Package Supply Chainsは通常のSupply Chainのようにマニフェストを作り、pushしますが、そのマニフェストをデプロイするためにDeliverableを作る代わりに、CarvelのPackageリソースを作成します。 このPackageを実行環境(Runクラスタなど)にインストールします。この時作成するPackageInstallリソースに対するパラメータを渡すことで実行環境に応じてパラメータを変更することができるようになります。 Carvel Package Supply Chainsではtype=serverの場合にIngressリソースも作成されます。

なお、TAP 1.6時点では、マニフェストのpush先はGit Repositoryのみなので、Gitopsモードが必須です。

Carvel Package Supply Chainsを有効するには、tap-values.yamlに次の設定を明示的に追加する必要があります。multi clusterの場合は、Buildクラスタでこの設定が必要です。

ootb_supply_chain_basic:
  carvel_package:
    workflow_enabled: true

この設定を有効にして、次のコマンドでTAPを更新します。

tanzu package installed update -n tap-install tap --values-file tap-values.yaml 

⚠️ Ingressの作成が重複するため、tap-values.yamlからootb-templates-overlay-ingressのoverlay設定を削除してください。

Supply Chainリストを確認するとsource-to-url-packageが追加されていることがわかります。

$ tanzu apps cluster-supply-chain list
NAME                         READY   AGE
basic-image-to-url           Ready   6h31m
basic-image-to-url-package   Ready   89s
source-to-url                Ready   6h31m
source-to-url-package        Ready   89s

このSupply Chainを使用するためのパラメータを確認すると、次のようにラベルで apps.tanzu.vmware.com/carvel-package-workflow=true を設定する必要があります。

$ tanzu apps cluster-supply-chain get source-to-url-package
---
# source-to-url-package: 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/carvel-package-workflow   In         true

実際に次のコマンドでCarvel Package Supply Chainを使ったWorkloadを作成します。 GitOpsモードを使うための設定は本記事では省略します。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --label apps.tanzu.vmware.com/carvel-package-workflow=true \
  --type server \
  --param gitops_branch=main \
  --param gitops_commit_message=Bump \
  --param gitops_server_address=https://github.com \
  --param gitops_repository_owner=making \
  --param gitops_repository_name=tap-gitops-manifests \
  --param gitops_user_email=makingx+bot@gmail.com \
  --param gitops_user_name=making-bot \
  --param gitops_ssh_secret=git-basic \
  -n demo

WorkloadのReadyになると、次のようなリソースが作成されます。

$ tanzu apps workload get hello-nodejs --namespace demo 
📡 Overview
   name:        hello-nodejs
   type:        server
   namespace:   demo

💾 Source
   type:       git
   url:        https://github.com/making/hello-nodejs
   branch:     master
   revision:   master@sha1:fde413c0fba0003c218a60bde69c8e254d3b15a6

📦 Supply Chain
   name:   source-to-url-package

   NAME               READY   HEALTHY   UPDATED   RESOURCE
   source-provider    True    True      6m25s     gitrepositories.source.toolkit.fluxcd.io/hello-nodejs
   image-provider     True    True      5m29s     images.kpack.io/hello-nodejs
   config-provider    True    True      5m22s     podintents.conventions.carto.run/hello-nodejs
   app-config         True    True      5m22s     configmaps/hello-nodejs-server
   service-bindings   True    True      5m22s     configmaps/hello-nodejs-with-claims
   api-descriptors    True    True      5m22s     configmaps/hello-nodejs-with-api-descriptors
   carvel-package     True    True      5m8s      taskruns.tekton.dev/hello-nodejs-carvel-package-j86xm
   config-writer      True    True      4m55s     runnables.carto.run/hello-nodejs-pkg-cfg-writer

🚚 Delivery

   Delivery resources not found.

💬 Messages
   No messages found.

🛶 Pods
   NAME                                    READY   STATUS      RESTARTS   AGE
   hello-nodejs-build-1-build-pod          0/1     Completed   0          6m27s
   hello-nodejs-carvel-package-j86xm-pod   0/3     Completed   0          5m22s
   hello-nodejs-pkg-cfg-writer-jsg9x-pod   0/2     Completed   0          5m6s

hello-nodejs-carvel-package-****でマニフェストをimgpkgでバンドル化してpushし、hello-nodejs-pkg-cfg-writer-****でそのimgpkgBundleをPackageリソースに定義し、gitレポジトリにpushします。 実際にpushされたPackageマニフェストは https://github.com/making/tap-gitops-manifests/blob/main/hello-nodejs.demo.tap/packages/20230811080453.0.0.yml です。

バンドル化されたマニフェストを次のコマンドでダウンロード可能です。(visibilityをpublicにしてあるので実際に実行して内容を確認できます)

imgpkg pull -b ghcr.io/making/workloads/hello-nodejs-demo-bundle@sha256:b0a013325c4c089befffd72643d576fb1109bebadce87f2f7b3615aef5ed9d75 -o /tmp/hello-nodejs

ではこのGit上にpushされたPackageリソースをapplyします。multi clusterの場合はRunクラスタにapplyします。 ドキュメントではここでGitOpsツールを使用することを推奨しており、

を使用する方法が紹介されています。前者の2つは追加のインストールなしで利用可能です。

ここではセットアップを省略するため、GitOpsを使用せず単純に次のようにkubectl applyでPackageリソースを作成します。

kubectl apply -f https://github.com/making/tap-gitops-manifests/raw/main/hello-nodejs.demo.tap/packages/20230811080453.0.0.yml -n demo

次のPackageリソースができました。

$ kubectl get package -n demo
NAME                                                     PACKAGEMETADATA NAME    VERSION                            AGE
hello-nodejs.demo.tap.20230811080453.0.0+build.fde413c   hello-nodejs.demo.tap   20230811080453.0.0+build.fde413c   5s

このPackageのパラメータを確認します。

$ tanzu package available get -n demo hello-nodejs.demo.tap/20230811080453.0.0+build.fde413c --values-schema

  KEY             DEFAULT                 TYPE     DESCRIPTION                                                         
  replicas        1                       integer  Number of replicas.                                                 
  workload_name   ""                      string   Required. Name of the workload, used by K8s Ingress HTTP rules.     
  cluster_issuer  tap-ingress-selfsigned  string   CertManager Issuer to use to generate certificate for K8s Ingress.  
  hostname        ""                      string   If set, K8s Ingress will be created with HTTP rules for hostname.   
  port            8080                    integer  Port number for the backend associated with K8s Ingress. 

Ingressを利用するために、workload_namehostnameを設定します。

cat <<EOF > hello-nodejs-values.yaml
workload_name: hello-nodejs
hostname: hello-nodejs-demo.stg.192-168-228-200.sslip.io
EOF

次のコマンドでこのパッケージをインストールします。multi clusterの場合はRunクラスタで実行します。-v>= 0.0.0を指定することで、新しいPackageがKubernetes上に作成されると自動でその新しいバージョンにアップデートされます。

tanzu package install -n demo hello-nodejs -p hello-nodejs.demo.tap -v ">= 0.0.0" --values-file hello-nodejs-values.yaml

インストールが完了したら、次のようなリソースが作成されたことがわかります。

$ kubectl get pkgi,deploy,svc,ing -n demo 
NAME                                               PACKAGE NAME            PACKAGE VERSION                    DESCRIPTION           AGE
packageinstall.packaging.carvel.dev/hello-nodejs   hello-nodejs.demo.tap   20230811080453.0.0+build.fde413c   Reconcile succeeded   12s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-nodejs   1/1     1            1           9s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/hello-nodejs   ClusterIP   10.96.113.106   <none>        8080/TCP   9s

NAME                                     CLASS    HOSTS                                            ADDRESS           PORTS     AGE
ingress.networking.k8s.io/hello-nodejs   <none>   hello-nodejs-demo.stg.192-168-228-200.sslip.io   192.168.228.200   80, 443   9s

Ingressで公開されたURLにアクセス可能です。

$ curl -k https://hello-nodejs-demo.stg.192-168-228-200.sslip.io 
Hello World!!

Carvel Package Supply Chainの場合、通常のSupply Chainのtype=serverなWorkloadで作成されるリソース(Deployment, Service)に加えて、Ingressが作成されました。 追加作成されるリソースはoverlayで定義されています。このoverlayファイルと変更可能なパラメータの定義はTAP 1.6からtap-values.yamlで上書き可能です。 デフォルトでは次のような定義になっています。

ootb_templates:
  carvel_package:
    parameters:
      - selector:
          matchLabels:
            apps.tanzu.vmware.com/workload-type: server
        schema: |
          #@data/values-schema
          ---
          #@schema/title "Workload name"
          #@schema/desc "Required. Name of the workload, used by K8s Ingress HTTP rules."
          #@schema/example "tanzu-java-web-app"
          #@schema/validation min_len=1
          workload_name: ""
  
          #@schema/title "Replicas"
          #@schema/desc "Number of replicas."
          replicas: 1
  
          #@schema/title "Port"
          #@schema/desc "Port number for the backend associated with K8s Ingress."
          port: 8080
  
          #@schema/title "Hostname"
          #@schema/desc "If set, K8s Ingress will be created with HTTP rules for hostname."
          #@schema/example "app.tanzu.vmware.com"
          hostname: ""
  
          #@schema/title "Cluster Issuer"
          #@schema/desc "CertManager Issuer to use to generate certificate for K8s Ingress."
          cluster_issuer: "tap-ingress-selfsigned"
        overlays: |
          #@ load("@ytt:overlay", "overlay")
          #@ load("@ytt:data", "data")
          #@overlay/match by=overlay.subset({"apiVersion":"apps/v1", "kind": "Deployment"})
          ---
          spec:
            #@overlay/match missing_ok=True
            replicas: #@ data.values.replicas
  
          #@ if data.values.hostname != "":
          ---
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: #@ data.values.workload_name
            annotations:
              cert-manager.io/cluster-issuer:  #@ data.values.cluster_issuer
              ingress.kubernetes.io/force-ssl-redirect: "true"
              kubernetes.io/ingress.class: contour
              kapp.k14s.io/change-rule: "upsert after upserting Services"
            labels:
              app.kubernetes.io/component: "run"
              carto.run/workload-name:  #@ data.values.workload_name
          spec:
            tls:
              - secretName: #@ data.values.workload_name
                hosts:
                - #@ data.values.hostname
            rules:
            - host: #@ data.values.hostname
              http:
                paths:
                - pathType: Prefix
                  path: /
                  backend:
                    service:
                      name: #@ data.values.workload_name
                      port:
                        number: #@ data.values.port
          #@ end

IngressにContourを利用するannotationがついています。前述のようにNginx Ingressを使うようにカスタマイズしてみます。 tap-values.yamlに次の設定を行います。

ootb_templates:
  carvel_package:
    parameters:
    - selector:
        matchLabels:
          apps.tanzu.vmware.com/workload-type: server
      schema: |
        #@data/values-schema
        ---
        #@schema/title "Workload name"
        #@schema/desc "Required. Name of the workload, used by K8s Ingress HTTP rules."
        #@schema/example "tanzu-java-web-app"
        #@schema/validation min_len=1
        workload_name: ""

        #@schema/title "Replicas"
        #@schema/desc "Number of replicas."
        replicas: 1

        #@schema/title "Port"
        #@schema/desc "Port number for the backend associated with K8s Ingress."
        port: 8080

        #@schema/title "Hostname"
        #@schema/desc "If set, K8s Ingress will be created with HTTP rules for hostname."
        #@schema/example "app.tanzu.vmware.com"
        hostname: ""

        #@schema/title "Cluster Issuer"
        #@schema/desc "CertManager Issuer to use to generate certificate for K8s Ingress."
        cluster_issuer: "tap-ingress-selfsigned"
      overlays: |
        #@ load("@ytt:overlay", "overlay")
        #@ load("@ytt:data", "data")
        #@overlay/match by=overlay.subset({"apiVersion":"apps/v1", "kind": "Deployment"})
        ---
        spec:
          #@overlay/match missing_ok=True
          replicas: #@ data.values.replicas

        #@ if data.values.hostname != "":
        ---
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: #@ data.values.workload_name
          annotations:
            cert-manager.io/cluster-issuer:  #@ data.values.cluster_issuer
            ingress.kubernetes.io/force-ssl-redirect: "true"
            #! kubernetes.io/ingress.class: contour <----- Removed
            kapp.k14s.io/change-rule: "upsert after upserting Services"
          labels:
            app.kubernetes.io/component: "run"
            carto.run/workload-name:  #@ data.values.workload_name
        spec:
          ingressClassName: nginx #! <----- Added
          tls:
            - secretName: #@ data.values.workload_name
              hosts:
              - #@ data.values.hostname
          rules:
          - host: #@ data.values.hostname
            http:
              paths:
              - pathType: Prefix
                path: /
                backend:
                  service:
                    name: #@ data.values.workload_name
                    port:
                      number: #@ data.values.port
        #@ end

次のコマンドでTAPを更新します。

tanzu package installed update -n tap-install tap --values-file tap-values.yaml 

Workloadの状態を確認すると、hello-nodejs-carvel-package-****hello-nodejs-pkg-cfg-writer-****が新たに生成されていることがわかります。 テンプレートの変更を検知して、新しいマニフェストのimgpkg bundle作成とgit pushが行われました。

$ tanzu apps workload get hello-nodejs --namespace demo 
📡 Overview
   name:        hello-nodejs
   type:        server
   namespace:   demo

💾 Source
   type:       git
   url:        https://github.com/making/hello-nodejs
   branch:     master
   revision:   master@sha1:fde413c0fba0003c218a60bde69c8e254d3b15a6

📦 Supply Chain
   name:   source-to-url-package

   NAME               READY     HEALTHY   UPDATED   RESOURCE
   source-provider    True      True      9m41s     gitrepositories.source.toolkit.fluxcd.io/hello-nodejs
   image-provider     True      True      8m45s     images.kpack.io/hello-nodejs
   config-provider    True      True      8m38s     podintents.conventions.carto.run/hello-nodejs
   app-config         True      True      8m38s     configmaps/hello-nodejs-server
   service-bindings   True      True      8m38s     configmaps/hello-nodejs-with-claims
   api-descriptors    True      True      8m38s     configmaps/hello-nodejs-with-api-descriptors
   carvel-package     True      True      11s       taskruns.tekton.dev/hello-nodejs-carvel-package-v7psj
   config-writer      Unknown   Unknown   4s        runnables.carto.run/hello-nodejs-pkg-cfg-writer

🚚 Delivery

   Delivery resources not found.

💬 Messages
   Workload [HealthyConditionRule]:   Not all Steps in the Task have finished executing

🛶 Pods
   NAME                                    READY   STATUS      RESTARTS   AGE
   hello-nodejs-7455c98c94-c4zlt           1/1     Running     0          4m23s
   hello-nodejs-build-1-build-pod          0/1     Completed   0          9m44s
   hello-nodejs-carvel-package-j86xm-pod   0/3     Completed   0          8m39s
   hello-nodejs-carvel-package-v7psj-pod   0/3     Completed   0          26s
   hello-nodejs-pkg-cfg-writer-ctxfx-pod   0/2     Completed   0          13s
   hello-nodejs-pkg-cfg-writer-jsg9x-pod   0/2     Completed   0          8m23s

To see logs: "tanzu apps workload tail hello-nodejs --namespace demo --timestamp --since 1h"

生成されたPackageリソースは https://github.com/making/tap-gitops-manifests/blob/main/hello-nodejs.demo.tap/packages/20230811081306.0.0.yml です。 バンドル化されたマニフェストは次のコマンドでダウンロードできます。

imgpkg pull -b ghcr.io/making/workloads/hello-nodejs-demo-bundle@sha256:8971d6979d6823edbe502162ddb9ab6dde665ac807857dbe4ea89857ce2db28c -o /tmp/hello-nodejs

新しいPackageをkubectlでapplyします。GitOpsを使用している場合(推奨)は自動で新しいPackageが追加されます。

kubectl apply -f https://github.com/making/tap-gitops-manifests/raw/main/hello-nodejs.demo.tap/packages/20230811081306.0.0.yml -n demo

次のコマンドで新しいPackageを確認できます。

$ kubectl get package -n demo  
NAME                                                     PACKAGEMETADATA NAME    VERSION                            AGE
hello-nodejs.demo.tap.20230811080453.0.0+build.fde413c   hello-nodejs.demo.tap   20230811080453.0.0+build.fde413c   5m53s
hello-nodejs.demo.tap.20230811081306.0.0+build.fde413c   hello-nodejs.demo.tap   20230811081306.0.0+build.fde413c   6s

PackageInstallが新しいパッケージを検出して、自動でインストールします。次のコマンドで新しいバージョンのパッケージがデプロイされていることがわかり、Ingressのnginxのものが利用されていることがわかります。

$ kubectl get pkgi,deploy,svc,ing -n demo 
NAME                                               PACKAGE NAME            PACKAGE VERSION                    DESCRIPTION           AGE
packageinstall.packaging.carvel.dev/hello-nodejs   hello-nodejs.demo.tap   20230811081306.0.0+build.fde413c   Reconcile succeeded   5m44s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-nodejs   1/1     1            1           5m41s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/hello-nodejs   ClusterIP   10.96.113.106   <none>        8080/TCP   5m41s

NAME                                     CLASS   HOSTS                                            ADDRESS           PORTS     AGE
ingress.networking.k8s.io/hello-nodejs   nginx   hello-nodejs-demo.stg.192-168-228-200.sslip.io   192.168.228.201   80, 443   5m41s

Nginx Ingressを経由したRoutingを利用するために、次のようにhostnameを変更します。

cat <<EOF > hello-nodejs-values.yaml
workload_name: hello-nodejs
hostname: hello-nodejs-demo.stg.192-168-228-201.sslip.io
EOF

新しいパラメータを次のコマンドで反映します。

tanzu package installed update -n demo hello-nodejs --values-file hello-nodejs-values.yaml

次のコマンドでIngressのhostnameが更新されたことを確認します。

$ kubectl get pkgi,deploy,svc,ing -n demo 
NAME                                               PACKAGE NAME            PACKAGE VERSION                    DESCRIPTION           AGE
packageinstall.packaging.carvel.dev/hello-nodejs   hello-nodejs.demo.tap   20230811081306.0.0+build.fde413c   Reconcile succeeded   6m26s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-nodejs   1/1     1            1           6m23s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/hello-nodejs   ClusterIP   10.96.113.106   <none>        8080/TCP   6m23s

NAME                                     CLASS   HOSTS                                            ADDRESS           PORTS     AGE
ingress.networking.k8s.io/hello-nodejs   nginx   hello-nodejs-demo.stg.192-168-228-201.sslip.io   192.168.228.201   80, 443   6m23s

新しいhostnameを使ってアプリにアクセスします。

$ curl -k https://hello-nodejs-demo.stg.192-168-228-201.sslip.io
Hello World!!

Carvel Package Supply Chainを使うと実行環境(Runクラスタ)毎に、パラメータを変えられることを試せました。 TAP 1.6時点では、実行環境の設定が少し煩雑に感じます。


type=serverでアプリをデプロイした場合に、Ingressでアプリを公開したい場合の3つの方法を紹介しました。

  • kubectlで直接Ingressリソースを作成する
  • OOTB SupplyChainで作成されるリソースにIngressを追加する
  • Carvel Package Supply Chainを使用する

TAP 1.6時点では、どれも一長一短です。Carvel Package Supply ChainがGAになれば、これが一番いい選択かもしれません。 現時点ではkubectlで直接Ingressリソースを作成するか、OOTB SupplyChainで作成されるリソースにIngressを追加するのが現実的ではないでしょうか。


✒️️ Edit  ⏰ History  🗑 Delete