Slide 1

Slide 1 text

kcp: Kubernetes APIs Are All You Need #techfeed_live 公認エキスパート No.150 チェシャ猫 (@y_taka_23) TechFeed Experts Night #28 〜コンテナ技術最前線 8th May. 2024

Slide 2

Slide 2 text

$ kubectl get pods error: the server doesn't have a resource type "pods" $ kubectl get deploy error: the server doesn't have a resource type "deploy" $ kubectl get nodes error: the server doesn't have a resource type "nodes" $ kubectl get configmaps NAME DATA AGE kube-root-ca.crt 1 126m $ kubectl version Client Version: v1.29.2 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3 Server Version: v1.28.1+kcp-v0.24.0 通常のリソースが存在しない サーバのバージョンが “kcp”

Slide 3

Slide 3 text

Containers kubectl

Slide 4

Slide 4 text

おさらい:コンテナが起動するまで ● Deployment を作成するとコンテナが起動する ● 各 Controller が担当リソースを監視してアクション ○ DeploymentController が ReplicaSet を作成 ○ ReplicaSetController が Pod を作成 ○ Kubelet が Node 上にコンテナを実際に起動 ● これら Controller は controller-manager に含まれている

Slide 5

Slide 5 text

Deployment Controller ReplicaSet Controller kubectl

Slide 6

Slide 6 text

Deployment Controller ReplicaSet Controller Watch Create kubectl

Slide 7

Slide 7 text

Deployment Controller ReplicaSet Controller Watch Create Watch Create kubectl

Slide 8

Slide 8 text

Deployment Controller ReplicaSet Controller Containers Watch Create Watch Create Watch Run kubectl

Slide 9

Slide 9 text

自分の担当の「何か」を監視して 差分があればリアクティブに「何か」する

Slide 10

Slide 10 text

Reconciliation Loop

Slide 11

Slide 11 text

コンテナ以外への一般化 ● この考え方はコンテナ以外にも応用できる ● CustomResourceDefinition (CRD) による拡張 ○ 自前のリソースを定義して CRUD API を拡張 ○ Controller がリソースを継続的に監視してアクション ● Kubernetes-native な OSS のデファクトスタンダード ○ cert-manager, Vitess, Prometheus Operator 他多数

Slide 12

Slide 12 text

“The Platform of Platforms”

Slide 13

Slide 13 text

例:写真共有サービス ● 写真が共有できるサービスを開発する ● 社内共通基盤の Kuberentes クラスタ上で運用したい ○ 既に様々なアプリがクラスタ上に載っている ○ アプリ側にもある程度 Kubernetes の知見がある ● プライベートクラウドの S3 互換ストレージを利用したい ○ 他のアプリもこのストレージを利用している

Slide 14

Slide 14 text

社内の各チームの責務 ● インフラチーム (Platform Team) ○ 他チームが使用するクラスタの運用管理 ● アプリチーム (Stream Aligned Team) ○ ユーザがアクセスする写真管理アプリ本体の開発 ● ストレージチーム (Complicated Subsystem Team) ○ 内製ストレージサービスの開発とリソース管理

Slide 15

Slide 15 text

ストレージの Bucket の払い出しを CRD にしたらセルフサービス化できそう

Slide 16

Slide 16 text

CustomResourceDefinition apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: buckets.storage.example.com spec: group: storage.example.com names: kind: Bucket listKind: BucketList singular: bucket plural: buckets scope: Namespaced versions: - name: v1 served: true storage: true (右上に続く) (左下の続き) schema: openAPIV3Schema: type: object properties: spec: type: object properties: bucketName: type: string encryption: type: boolean カスタムリソースの設定項目

Slide 17

Slide 17 text

Bucket の払い出し apiVersion: storage.example.com/v1 kind: Bucket metadata: name: photo-bucket spec: bucketName: photo-bucket encryption: true 定義に対応する設定項目

Slide 18

Slide 18 text

どうやって権限と責務を分割する? ● 各アプリでクラスタを分ける ○ クラスタの運用コストでインフラチームが死ぬ ● Namespace で分け、Controller はアプリ側に置く ○ Controller の運用でアプリチームが死ぬ ● Namespace で分け、Controller をストレージ側に置く ○ 全アプリと調整が必要になりストレージチームが死ぬ

Slide 19

Slide 19 text

結論:誰かが死ぬ

Slide 20

Slide 20 text

https://www.cncf.io/projects/kcp/

Slide 21

Slide 21 text

KubeCon EU 2024 でも発表 https://www.youtube.com/watch?v=7op_r9R0fCo https://www.youtube.com/watch?v=-P1kUo5zZR4

Slide 22

Slide 22 text

kcp が目指すもの ● API プラットフォームのためのフレームワーク ○ CRUD API の管理に特化した Kubernetes API Server ○ Pod / Volume 系のリソースが定義されていない ● 責務を分離できる設計になっている ○ 階層構造の Workspace が定義できる ○ API を提供する側と使用する側が分離されている

Slide 23

Slide 23 text

root app photo chat storage db クラスタは全体でひとつ インフラチーム管理

Slide 24

Slide 24 text

root app photo chat storage db クラスタは全体でひとつ インフラチーム管理 写真共有 アプリチーム管理 ストレージ チーム管理 リソースは 原則不可視

Slide 25

Slide 25 text

$ kubectl workspace tree . └── root ├── app │ ├── chat │ └── photo ├── db └── storage $ kubectl workspace :root:app:chat Current workspace is 'root:app:chat' (type root:universal). $ kubectl get configmaps NAME DATA AGE example 1 10s kube-root-ca.crt 1 3m23s $ kubectl workspace :root:app:photo Current workspace is 'root:app:photo' (type root:universal). $ kubectl get configmaps NAME DATA AGE kube-root-ca.crt 1 4m22s Workspace の階層構造 chat Workspace からは ConfigMap が見える photo Workspace からは ConfigMap が見えない

Slide 26

Slide 26 text

API の定義と公開 ● APIResourceSchema ○ CRD に類似、API で CRUD 操作する対象を定義 ● APIExport ○ 公開する APIResourceSchema を選択 ● APIBinding ○ API 利用側の Workspace から APIExport を参照

Slide 27

Slide 27 text

root app photo chat storage db

Slide 28

Slide 28 text

root app photo chat storage db APIResource Schema

Slide 29

Slide 29 text

root app photo chat storage db APIResource Schema APIExport 特定バージョンの API 定義を参照

Slide 30

Slide 30 text

root app photo chat storage db APIResource Schema APIExport APIBinding Workspace と API 名を参照 特定バージョンの API 定義を参照

Slide 31

Slide 31 text

root app photo chat storage db APIResource Schema APIExport APIBinding Bucket (CustomResource) Workspace と API 名を参照 特定バージョンの API 定義を参照

Slide 32

Slide 32 text

APIResourceSchema apiVersion: apis.kcp.io/v1alpha1 kind: APIResourceSchema metadata: name: v240508.buckets.storage.example.com spec: group: storage.example.com names: kind: Bucket listKind: BucketList singular: bucket plural: buckets scope: Namespaced versions: - name: v1 served: true storage: true (右上へ続く) (左下の続き) schema: type: object properties: apiVersion: type: string kind: type: string metadata: type: object spec: type: object properties: bucketName: type: string encryption: type: boolean 詳細バージョンを 定義する リソース定義方法は CRD に似ている

Slide 33

Slide 33 text

APIExport apiVersion: apis.kcp.io/v1alpha1 kind: APIExport metadata: name: buckets.storage.example.com spec: latestResourceSchemas: - v240508.buckets.storage.example.com 内部的な詳細バージョンと 外部バージョンを紐付け

Slide 34

Slide 34 text

APIBinding apiVersion: apis.kcp.io/v1alpha1 kind: APIBinding metadata: name: buckets-api spec: reference: export: path: root:storage name: buckets.storage.example.com 使用する側からは 内部バージョンは不可視

Slide 35

Slide 35 text

$ kubectl workspace :root:storage Current workspace is 'root:storage' (type root:organization). $ kubectl apply -f apiresourceschema.yaml apiresourceschema.apis.kcp.io/v240508.buckets.storage.example.com created $ kubectl apply -f apiexport.yaml apiexport.apis.kcp.io/buckets.storage.example.com created $ kubectl workspace :root:app:photo Current workspace is 'root:app:photo' (type root:universal). $ kubectl apply -f bucket.yaml error: resource mapping not found for name: "photo-bucket" namespace: "" from "bucket.yaml": no matches for kind "Bucket" in version "storage.example.com/v1" ensure CRDs are installed first $ kubectl apply -f apibinding.yaml apibinding.apis.kcp.io/buckets-api created $ kubectl apply -f bucket.yaml bucket.storage.example.com/photo-bucket created APIBinding を作成して初めて Bucket 払い出し API が使用できる

Slide 36

Slide 36 text

まとめ ● Kubernetes はコンテナに留まらない基盤 ○ CustomResource に対する Reconciliation ● しかし Controller の責務を置く場所が悩ましい ○ インフラ/アプリ以外の「共通サービス」チームの存在 ● kcp は API プラットフォーム構築に特化した API Server ○ API(≒ CRD) を公開する側と使用する側の分離

Slide 37

Slide 37 text

From the Platform of Platforms, To the Platform of APIs Presented By チェシャ猫 (@y_taka_23)