Preliminary version. The functionality may change, but the basic features will be preserved. Compatibility with future versions is ensured, but may require additional migration actions.
Alternative ways to create and use DataExport resources without the d8 utility
Besides using the d8 utility, you can create a DataExport resource directly through a YAML manifest. In the example below, environment variables are used for easier configuration, replace their values with the required ones:
export NAMESPACE="d8-storage-volume-data-manager"
export DATA_EXPORT_RESOURCE_NAME="example-dataexport"
export TARGET_TYPE="PersistentVolumeClaim"
export TARGET_NAME="fs-pvc-data-exporter-fs-0"
kubectl apply -f -<<EOF
apiVersion: storage.deckhouse.io/v1alpha1
kind: DataExport
metadata:
name: ${DATA_EXPORT_RESOURCE_NAME}
namespace: ${NAMESPACE}
spec:
ttl: 10h
targetRef:
kind: ${TARGET_TYPE}
name: ${TARGET_NAME}
EOF
After creating the resource, extract the CA certificate by executing the following command:
kubectl -n $NAMESPACE get dataexport $DATA_EXPORT_RESOURCE_NAME -o jsonpath='{.status.ca}' | base64 -d > ca.pem
Check the certificate:
openssl x509 -in ca.pem -noout -text | head
Example output:
Issuer: CN = data-exporter-CA
Signature Algorithm: ecdsa-with-SHA256
Extract the URL from the DataExport resource and verify the export:
export POD_URL=$(kubectl -n $NAMESPACE get dataexport $DATA_EXPORT_RESOURCE_NAME -o jsonpath='{.status.url}')
echo "POD_URL: $POD_URL"
After creating the DataExport resource and extracting the necessary data, you can connect to the exporter using one of the following methods:
1. Authentication using certificate and key from local kubeconfig
This method uses existing credentials from your local kubeconfig file. Extract the keys from the configuration by executing the following commands:
cat ~/.kube/config | grep "client-certificate-data" | awk '{print $2}' | base64 -d > client.crt
cat ~/.kube/config | grep "client-key-data" | awk '{print $2}' | base64 -d > client.key
Check the contents of the target PVC using the command:
curl -v --cacert ca.pem ${POD_URL}api/v1/files/ --key client.key --cert client.crt
Example output:
..
..
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{"apiVersion": "v1", "items": [{"name":"4.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"hello","size":5,"modTime":"2025-03-03 10:53:06.895434814 +0000 UTC","type":"file"}
,{"name":"7.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"lost+found","modTime":"2025-03-03 10:29:31 +0000 UTC","type":"dir"}
,{"name":"8.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"10.txt","size":13,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"9.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"3.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"2.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"1.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"6.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"5.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
]}
2. Authentication using token and roles
This method involves creating a separate ServiceAccount with appropriate access permissions. Create a ServiceAccount using the command:
kubectl -n $NAMESPACE create serviceaccount data-exporter-test
Create a ClusterRole by executing the following command:
kubectl create -f - <<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: data-exporter-test-role
rules:
- apiGroups: ["storage.deckhouse.io"]
resources: ["dataexports/download"]
verbs: ["create"]
EOF
Create a token by running the commands:
export TOKEN=$(kubectl create token data-exporter-test --duration=24h)
echo $TOKEN
Create a ClusterRoleBinding by applying the manifest:
kubectl create -f - <<EOF
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: data-exporter-test-role-binding
namespace: ${NAMESPACE}
subjects:
- kind: ServiceAccount
name: data-exporter-test
namespace: ${NAMESPACE}
roleRef:
kind: ClusterRole
name: data-exporter-test-role
apiGroup: rbac.authorization.k8s.io
EOF
Check the contents of the target PVC by executing the request:
curl -H "Authorization: Bearer $TOKEN" \
-v --cacert ca.pem ${POD_URL}api/v1/files/
Example output:
..
..
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{"apiVersion": "v1", "items": [{"name":"4.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"hello","size":5,"modTime":"2025-03-03 10:53:06.895434814 +0000 UTC","type":"file"}
,{"name":"7.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"lost+found","modTime":"2025-03-03 10:29:31 +0000 UTC","type":"dir"}
,{"name":"8.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"10.txt","size":13,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"9.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"3.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"2.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"1.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"6.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
,{"name":"5.txt","size":12,"modTime":"2025-04-01 08:02:00.228156524 +0000 UTC","type":"file"}
]}
Important notes on working with the API
When working with exported data through the HTTP API, consider the following features:
- File downloads: Files are downloaded using standard GET requests containing the file path in the URL:
GET /api/v1/files/largeimage.iso,GET /api/v1/files/directory/largeimage.iso. The file path should not end with/. This download method is supported by standard tools (browsers, curl, etc.). File resumption is supported, but compression is not. - Directory browsing: Accessing a directory is carried out with a similar GET request, where the directory path should end with
/:GET /api/v1/files/— path to root,GET /api/v1/files/directory/— path to directory. - File listing: When accessing a directory, a file listing in this directory is provided: a JSON string containing the list of files is sent in the response body, including the name, type, and size of the files. File sizes are not cached and are recalculated on each directory request.