COSI (Container Object Storage Interface) เป็น driver ที่ช่วย deploy และ config Object Storage ทำหน้าที่เหมือนกับ CSI (Container Storage Interface) เพื่อสร้าง volume ทั้งที่เป็น block และ file storage ให้กับ container หน้าที่ของ COSI จะสร้าง Bucket และ Access/Secret key ให้อัตโนมัติ ทำให้การใช้งาน object storage ทำได้อัตโนมัติผ่าน deployment metadata (yaml) ลดงาน operation ในการจัดการ object storage ให้กับ container application
COSI vs CSI Comparison
| Concept | CSI (Block/File) | COSI(Object) |
| Storage Class | StorageClass | BucketClass |
| Claim | PersistentVolumeClaim | BucketClaim |
| Access | Built into PVC | BucketAccess + BucketAccessClass |
| Mount | Volume mount in pod | Credentials secret in pod |
| Protocal | Block/NFS/etc | S3, GCS, Azure Blob |
| Status | Stable (v1) | Alpha (v1alpha1) |
Provider ที่ support COSI driver เช่น
| Provider | Driver |
| MinIO | minio.objectstorage.k8s.io |
| AWS S3 | s3.amazonaws.com |
| Ceph/RadosGW | ceph.objectstorage.k8s.io |
| Nutanix Objects | nutanix.objectstorage.k8s.io |
เปิดใช้งาน COSI ใน NKP สามารถทำได้ผ่าน Application Catalog โดยเข้าไปที่ COSI Driver for Nutanix

เข้าไปที่ enable option และกรอกข้อมูลที่จำเป็นตามตัวอย่าง


หลังจากกดปุ่ม Save ระบบจะติดตั้ง COSI CRD และ COSI Controller ไปยัง Kubernetes Cluster ที่เลือก โดยสามารถตรวจสอบได้จากตัวอย่าง
[root@guest-bastion-server-1 nutanix]# kubectl get crds | grep objectstoragebucketaccessclasses.objectstorage.k8s.io 2026-02-13T14:37:53Zbucketaccesses.objectstorage.k8s.io 2026-02-13T14:37:53Zbucketclaims.objectstorage.k8s.io 2026-02-13T14:37:53Zbucketclasses.objectstorage.k8s.io 2026-02-13T14:37:53Zbuckets.objectstorage.k8s.io 2026-02-13T14:37:53Z[root@guest-bastion-server-1 nutanix]# kubectl get pod -n container-object-storage-systemNAME READY STATUS RESTARTS AGEcontainer-object-storage-controller-667886cd7f-l658v 1/1 Running 0 12h
NKP จะติดตั้ง BucketClass ให้อัตโนมัติ โดยตรวจสอบได้จาก cli
[root@guest-bastion-server-1 nutanix]# kubectl get bucketclassesNAME AGEcosi-nutanix-nkp 47m[root@guest-bastion-server-1 nutanix]# kubectl get bucketclasses cosi-nutanix-nkp -o yamlapiVersion: objectstorage.k8s.io/v1alpha1deletionPolicy: DeletedriverName: ntnx.objectstorage.k8s.iokind: BucketClassmetadata: annotations: meta.helm.sh/release-name: cosi-resources-nutanix meta.helm.sh/release-namespace: develop creationTimestamp: "2026-02-14T02:16:04Z" generation: 1 labels: app.kubernetes.io/managed-by: Helm helm.toolkit.fluxcd.io/name: cosi-resources-nutanix helm.toolkit.fluxcd.io/namespace: develop name: cosi-nutanix-nkp resourceVersion: "642878" uid: 58023be3-9179-40c7-be4d-24219c4a7735
ตรวจสอบว่า NKP ได้สร้าง BucketAccessClass ให้
[root@guest-bastion-server-1 nutanix]# kubectl get BucketAccessClassNAME AGEcosi-nutanix-nkp 50m[root@guest-bastion-server-1 nutanix]# kubectl get BucketAccessClass cosi-nutanix-nkp -o yamlapiVersion: objectstorage.k8s.io/v1alpha1authenticationType: KEYdriverName: ntnx.objectstorage.k8s.iokind: BucketAccessClassmetadata: annotations: meta.helm.sh/release-name: cosi-resources-nutanix meta.helm.sh/release-namespace: develop creationTimestamp: "2026-02-14T02:16:04Z" generation: 1 labels: app.kubernetes.io/managed-by: Helm helm.toolkit.fluxcd.io/name: cosi-resources-nutanix helm.toolkit.fluxcd.io/namespace: develop name: cosi-nutanix-nkp resourceVersion: "642877" uid: 4bd6a0e8-0a16-4039-8746-66e2c7c00a87
ทำการสร้าง BucketClaim (เหมือน PVC สำหรับ object storage)
apiVersion: objectstorage.k8s.io/v1alpha1kind: BucketClaimmetadata: name: test-bucketclaimspec: bucketClassName: cosi-nutanix-nkp protocols: - s3
สร้าง BucketAccess เพื่อให้ COSI Controller สร้าง credential สำหรับ connect ไปยัง S3 Bucket อัตโนมติ
apiVersion: objectstorage.k8s.io/v1alpha1kind: BucketAccessmetadata: name: nkp-test-bucketaccessspec: bucketAccessClassName: cosi-nutanix-nkp bucketClaimName: test-bucketclaim credentialsSecretName: nkp-test-objectstore-credentials
ตรวจสอบว่า cosi controller ได้ทำการสร้าง secret ตามที่กำหนดใน BucketAccess metadata
[root@guest-bastion-server-1 nutanix]# kubectl get secret nkp-test-objectstore-credentialsNAME TYPE DATA AGEnkp-test-objectstore-credentials Opaque 1 47m[root@guest-bastion-server-1 nutanix]# k get secret nkp-test-objectstore-credentials -o yamlapiVersion: v1data: BucketInfo: eyJtZXRhZGF0YSI6eyJuYW1lIjoiYmMtNTM3OTBlOGQtZDMzMC00N2QzLWE2MjAtOWI4ODVmYTEwNTQ3IiwiY3JlYXRpb25UaW1lc3RhbXAiOm51bGx9LCJzcGVjIjp7ImJ1Y2tldE5hbWUiOiJjb3NpLW51dGFuaXgtbmtwYjE5Y2EwZTItNzRjNC00YmNmLWE3YjctMmUzN2U2MDY5YWM2IiwiYXV0aGVudGljYXRpb25UeXBlIjoiS0VZIiwic2VjcmV0UzMiOnsiZW5kcG9pbnQiOiJodHRwczovLzE5Mi4xNjguMTAuNTI6NDQzIiwicmVnaW9uIjoidXMtZWFzdC0xIiwiYWNjZXNzS2V5SUQiOiJMc2pDRG9ZeTREX09wRl9sVmo5UkNQRERnUS1SOG1NXyIsImFjY2Vzc1NlY3JldEtleSI6ImVpZW45bjdUM1pHZ2oxSGtydVZvVmNOM1VuUlAybnBjIn0sInNlY3JldEF6dXJlIjpudWxsLCJwcm90b2NvbHMiOlsiIl19fQ==kind: Secretmetadata: creationTimestamp: "2026-02-14T03:46:44Z" finalizers: - cosi.objectstorage.k8s.io/secret-protection name: nkp-test-objectstore-credentials namespace: default resourceVersion: "727116" uid: 1d6c999c-6605-4580-9db4-e18c7fe1a41ctype: Opaque
[root@guest-bastion-server-1 nutanix]# kubectl get secret nkp-test-objectstore-credentials -o jsonpath='{.data.BucketInfo}' | base64 -d | jq .{ "metadata": { "name": "bc-53790e8d-d330-47d3-a620-9b885fa10547", "creationTimestamp": null }, "spec": { "bucketName": "cosi-nutanix-nkpb19ca0e2-74c4-4bcf-a7b7-2e37e6069ac6", "authenticationType": "KEY", "secretS3": { "endpoint": "https://192.168.10.52:443", "region": "us-east-1", "accessKeyID": "LsjCDoYy4D_OpF_lVj9RCPDDgQ-R8mM_", "accessSecretKey": "eien9n7T3ZGgj1HkruVoVcN3UnRP2npc" }, "secretAzure": null, "protocols": [ ""
Deploy cosi-test container เพื่อทดสอบอ่านเขียนข้อมูลลงใน bucket storage ได้ถูกต้อง
apiVersion: v1kind: Podmetadata: name: cosi-test namespace: defaultspec: containers: - name: test image: amazon/aws-cli:latest command: ["/bin/sh", "-c"] args: - | echo "=== COSI Bucket Test ===" # Install jq yum install -y jq 2>/dev/null || apk add jq 2>/dev/null # Parse BucketInfo JSON BUCKET_INFO=$(cat /cosi/BucketInfo) export AWS_ACCESS_KEY_ID=$(echo $BUCKET_INFO | jq -r '.spec.secretS3.accessKeyID') export AWS_SECRET_ACCESS_KEY=$(echo $BUCKET_INFO | jq -r '.spec.secretS3.accessSecretKey') BUCKET_NAME=$(echo $BUCKET_INFO | jq -r '.spec.bucketName') ENDPOINT=$(echo $BUCKET_INFO | jq -r '.spec.secretS3.endpoint') echo "Bucket: $BUCKET_NAME" echo "Endpoint: $ENDPOINT" # Write test echo "Hello from COSI!" > /tmp/testfile.txt aws s3 cp /tmp/testfile.txt s3://$BUCKET_NAME/testfile.txt \ --endpoint-url $ENDPOINT --no-verify-ssl # List bucket aws s3 ls s3://$BUCKET_NAME/ --endpoint-url $ENDPOINT --no-verify-ssl # Read test aws s3 cp s3://$BUCKET_NAME/testfile.txt /tmp/downloaded.txt \ --endpoint-url $ENDPOINT --no-verify-ssl cat /tmp/downloaded.txt echo "=== Test Complete ===" sleep 3600 volumeMounts: - name: cosi-credentials mountPath: /cosi readOnly: true volumes: - name: cosi-credentials secret: secretName: nkp-test-objectstore-credentials
ตรวจสอบการทำงาน จาก log ของ pod cosi-test
[root@guest-bastion-server-1 nutanix]# kubectl logs cosi-test=== COSI Bucket Test ===Amazon Linux 2023 repository 23 MB/s | 54 MB 00:02Last metadata expiration check: 0:00:09 ago on Sat Feb 14 04:46:32 2026.Package jq-1.7.1-51.amzn2023.x86_64 is already installed.Dependencies resolved.Nothing to do.Complete!Bucket: cosi-nutanix-nkpb19ca0e2-74c4-4bcf-a7b7-2e37e6069ac6Endpoint: https://192.168.10.52:443
