Tanzu Platform の知らなくてもいい話- Capabilities/Profiles

最新製品である Tanzu Platform のマニアックすぎてブログに書くのを躊躇した内容を書いていきます。 注意点ですが、ここから書くことは「知らなくてもいい」ことです。

今回は Capabilities / Profiles を解説します。なお、この記事は KCP/Kine の理解が前提です。

Space での利用可能なAPIとCapabilitiesとProfiles

KCP/Kine でも紹介した以下の絵にあるよう、Space や ClusterGroup で定義したリソースが Syncer を経由して、対向のk8sに情報が反映されます。

ここでの利用可能なAPI一覧はワークスペースを切り替え kubectl api-resources をすれば確認ができます。 ポイントがSpaceからなんでもかんでも実行できるわけではないという点です。では、APIが足りないときはどうすればいいのでしょうか?

この中で、ClusterGroup のAPI一覧はカスタマイズできる手段は筆者はまだ見つけることができていません。 しかし、Spaceであれば、カスタマイズができます。それが TP を理解する上で、個人的には鬼門、「なんじゃこりゃ」の総本山、CapabilitiesとProfilesです。

TP GUIから確認できる、これです。

KCPの概念を知った上で解説すると以下の機能をもっています。

  • Profiles : SpaceワークスペースへAPIを追加する方法
  • Capabilities : CarvelPackage Managementをベースに、APIのインストールと定義を担っており、これがProfilesから参照される

ここからもう少し、細かくみていきます。

CapabilitiesとProfile を使って Space から k8s service をいじる

通常のSpace のワークスペースからは、Kubernetesでは一般的に使われる core/v1の Service が定義されていません。 以下のコマンドは失敗しますが、想定どおりです。

1% tanzu space use
2# 適当なスペースを選択
3% kubectl get svc
4error: the server doesn't have a resource type "svc"

ここでは、Profile と Capabilities から Space から K8s Service をコントロールできるようにします。その過程で、Capabilities と Pod の理解を試みます。

自作 Capabilities の登録

ここではオフィシャルサポートが一切ないですが、自作の Capabilities を Tanzu Platform に登録してきます。 該当のパッケージ情報はいかに存在しています。

コード:https://github.com/mhoshi-vm/tp-k8s-service-from-space
コンテナイメージ:https://github.com/mhoshi-vm/tp-k8s-service-from-space/pkgs/container/tp-k8s-service-from-space

これらは、CarvelPackage Managementを元に作成しているものですが、テーマからは逸脱するので説明を省きます。

TPに切り替え、まずはプロジェクトのワークスペースに入ります。

1tanzu project use tpadmin

ここで、今回の自作パッケージを登録していきます。

1tanzu package repository add tp-k8s-service-from-space --url ghcr.io/mhoshi-vm/tp-k8s-service-from-space:latest

kubectl にはなりますが、登録も確認できます。

1% kubectl get pkgr
2NAME                        AGE   DESCRIPTION
3tap-saas-sha256-e989369     14d   Ready
4tp-k8s-service-from-space   4s    Ready
1% kubectl get package | grep "k8s-service.*0.0.1"
2k8s-service-capability.tanzu.japan.com.0.0.1

この状態でTPのGUIの [Spaces] > [Capabilities] > [Available] を見ると、K8s Service Capabilites という名のものが確認できます。

コードをみていきます。

https://github.com/mhoshi-vm/tp-k8s-service-from-space/blob/main/packages/k8s-service-capability.tanzu.japan.com/0.0.1.yaml#L5

これらの情報は、kind: Pacakgeannotations.capability.tanzu.vmware.com/provides のJSONの情報を参照してTP GUIに反映され、Capabilitiesとして登録されます。 逆をいえば、この annotation がないと、TP GUIには出現しません。さらに重要なのがgroupVersionKindsにどのAPIをSpaceに公開したいかを一覧化していきます。

なお、今回のケースは不要ですが、3rdパーティのAPIを追加するときは、template に必要なコントローラのインストールなども定義していきます。

自作 Capabilities を ClusterGroup にインストール

Capabilities を ClusterGroup にインストールします。 以下のコマンドで ClusterGroupのワークスペースに切り替えます。途中プロンプトで、どのClusterGroupに対してインストールするか聞かれるので選択します。

1tanzu operations clustergroup use

ワークスペース切り替え後、以下のコマンドで自作Capabilityのインストール準備はします。 tanzu project useと同じコマンドとおもうかもですが、執筆時点では、Projectのワークスペースに対するSyncerが定義されていないので、実際の対向K8sには反映されません。 なので、ClusterGroupで実行することで実際の対向K8sに反映します。

1tanzu package repository add tp-k8s-service-from-space --url ghcr.io/mhoshi-vm/tp-k8s-service-from-space:latest

執筆時点だと、実行後以下のような出力になりますが、問題なく実行できていると思って結構です。

1% kubectl get pkgr
2NAME                        AGE    DESCRIPTION
3tp-k8s-service-from-space   18s    Not Ready: the server could not find the requested resource (get packages.data.packaging.carvel.dev)

そして、この状態で、[Spaces] > [Capabilities] > [Available] のK8s Service Capabilitesを選択します。

右上の Install Package を実行します。

“Select a cluster group on which to deploy the package” でインストールする先のクラスタを選択して Install Package を実行します。

Profile の作成

SpaceにAPIをみえるようにするためには、前段でインストールした自作 Capability を定義した Profile を作成します。 [Spaces] > [Profiles] から [Create Profiles] を選択します。

名前はなんでもいいですが、ここでは k8s-service にしています。

Traitsですが、今回は無視してください。別記事でとりあげるかもしれません。

Capabilitiesで自作Capabilityを登録します。そのまま Create を実行します。

Space を作成 / K8s Service の作成

いよいよ準備ができたのでSpaceを作って実際のk8s serviceを作っていきます。

[Spaces] > [Overview] > [Create Space] を選択します。 Space Profiles にさきほど作成したProfileを選択します。AvailabilityTargetはいつもどおりの設定でいいです。

ここからはCLIです。スペースのワークスペースに切り替えます。

1tanzu space use k8s-service

API一覧をのぞきます。すると本来は存在しない、Services のAPIが並んでいることがわかります。

 1% kubectl api-resources
 2NAME                        SHORTNAMES   APIVERSION                     NAMESPACED   KIND
 3configmaps                               v1                             true         ConfigMap
 4events                                   v1                             true         Event
 5limitranges                              v1                             true         LimitRange
 6resourcequotas                           v1                             true         ResourceQuota
 7secrets                                  v1                             true         Secret
 8serviceaccounts                          v1                             true         ServiceAccount
 9services                    svc          v1                             true         Service <<<注目<<<<<<<<<<<<<<<<<<<<<<<<<<<<
10localsubjectaccessreviews                authorization.k8s.io/v1        true         LocalSubjectAccessReview
11selfsubjectaccessreviews                 authorization.k8s.io/v1        false        SelfSubjectAccessReview
12selfsubjectrulesreviews                  authorization.k8s.io/v1        false        SelfSubjectRulesReview
13subjectaccessreviews                     authorization.k8s.io/v1        false        SubjectAccessReview
14events                                   events.k8s.io/v1               true         Event
15clusterrolebindings                      rbac.authorization.k8s.io/v1   false        ClusterRoleBinding
16clusterroles                             rbac.authorization.k8s.io/v1   false        ClusterRole
17rolebindings                             rbac.authorization.k8s.io/v1   true         RoleBinding
18roles                                    rbac.authorization.k8s.io/v1   true         Role
19syncresourcesets            srs          ucp.tanzu.vmware.com/v1        true         SyncResourceSet

ここで、Type: Loadbalancer の k8s service を作ってみます。

1kubectl create svc loadbalancer hoge --tcp=8080:8080

しばらくすると実行が完了すると思います。なお、普通の k8s で Type: Loadbalancer を作成すれば、.status.loadBalancer に接続先のエンドポイント情報が表示されますが、何も表示されません。

 1% kubectl get svc hoge -o yaml
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  annotations: {}
 6  creationTimestamp: "2025-01-21T08:44:59Z"
 7  generation: 1
 8  labels:
 9    app: hoge
10  name: hoge
11  namespace: default
12  resourceVersion: "1426062"
13  uid: eafa02f8-3042-41f8-bd2b-35338b0de673
14spec:
15  ports:
16  - name: 8080-8080
17    port: 8080
18    protocol: TCP
19    targetPort: 8080
20  selector:
21    app: hoge
22  type: LoadBalancer
23status:
24  loadBalancer: {} <<<注目<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

TPでは、対向クラスタのステータスなどは、Sync Resource Set (SRS)でみられます。

1% kubectl get srs -o yaml

実際出力をみると、こちらには、Type: Loadbalancer の実行結果とエンドポイントが表示されます。

 1status:
 2...
 3    data:
 4      tp-wk1:
 5        k8s-service-7f7ff58bf8-mmr9t:
 6          hoge:
 7            results:
 8              .metadata.annotations:
 9                agent.tanzu.vmware.com/clusterpath: root:c957a32b-b30c-21f7-95e1-f22cffe0eecf:dc7d70e1-d928-4bb2-88f5-ac0fc25c8524:k8s-service
10                agent.tanzu.vmware.com/upstream-namespace: default
11                agent.tanzu.vmware.com/upstream-uid: eafa02f8-3042-41f8-bd2b-35338b0de673
12                kcp.io/cluster: j1f1tjgos93ryang
13              .metadata.creationTimestamp: "2025-01-21T08:45:40Z"
14              .metadata.generation: 1
15              .metadata.labels:
16                agent.tanzu.vmware.com/syncer-selector: txbta4fvbvkhprrg7xb7ejeo6owkcmmhaeqa3jukk7klxfspxtla....h
17                app: hoge
18              .metadata.name: hoge
19              .metadata.namespace: k8s-service-7f7ff58bf8-mmr9t
20              .metadata.resourceVersion: "10359689"
21              .metadata.uid: 942dd0f2-27b1-4dd0-8f5f-5827891c70f4
22              .status:
23                loadBalancer:
24                  ingress:
25                  - ip: 192.168.251.49   <<<注目<<<<<<<
26                    ipMode: VIP

もし、対向K8sのKubeconfigがあれば、同じIPアドレスが表示された、Type:Loadbalancerが作成されることを確認できるかと思います。

 1% export KUBECONFIG=<Deploy Cluster Kubeconfig>
 2% kubectl get svc -o yaml -n k8s-service-7f7ff58bf8-mmr9t
 3apiVersion: v1
 4items:
 5- apiVersion: v1
 6  kind: Service
 7  metadata:
 8    annotations:
 9      agent.tanzu.vmware.com/clusterpath: root:c957a32b-b30c-21f7-95e1-f22cffe0eecf:dc7d70e1-d928-4bb2-88f5-ac0fc25c8524:k8s-service
10      agent.tanzu.vmware.com/upstream-namespace: default
11      agent.tanzu.vmware.com/upstream-uid: eafa02f8-3042-41f8-bd2b-35338b0de673
12      kcp.io/cluster: j1f1tjgos93ryang
13    creationTimestamp: "2025-01-21T08:45:40Z"
14    finalizers:
15    - service.kubernetes.io/load-balancer-cleanup
16    generation: 1
17    labels:
18      agent.tanzu.vmware.com/syncer-selector: txbta4fvbvkhprrg7xb7ejeo6owkcmmhaeqa3jukk7klxfspxtla....h
19      app: hoge
20    name: hoge
21    namespace: k8s-service-7f7ff58bf8-mmr9t
22    resourceVersion: "10359689"
23    uid: 942dd0f2-27b1-4dd0-8f5f-5827891c70f4
24  spec:
25    allocateLoadBalancerNodePorts: true
26    clusterIP: 10.96.168.56
27    clusterIPs:
28    - 10.96.168.56
29    externalTrafficPolicy: Cluster
30    internalTrafficPolicy: Cluster
31    ipFamilies:
32    - IPv4
33    ipFamilyPolicy: SingleStack
34    ports:
35    - name: 8080-8080
36      nodePort: 32057
37      port: 8080
38      protocol: TCP
39      targetPort: 8080
40    selector:
41      app: hoge
42    sessionAffinity: None
43    type: LoadBalancer
44  status:
45    loadBalancer:
46      ingress:
47      - ip: 192.168.251.49 <<<注目<<<<<<<
48        ipMode: VIP
49kind: List
50metadata:
51  resourceVersion: ""

今回は、あくまで非常にシンプルな K8s Service の例ですが、この仕組みがわかれば、自動化を行う上で、足りないAPIをスペースにどんどん追加できます。 とはいえ、この記事が「知らなくてもいい」とあるよう、基本的にはお客様には、こういったカスタマイズをしなくてもいいように開発が勧められているので、カスタマイズはほどほどにしたほうがいいと思います。

以上 Capabilities/Profiles を解説しました。