Volumes
In this section, you will learn how to leverage Kubernetes volumes in order to mount files and directories inside an AWS Nitro Enclave running as a Pod.
Using persistent storage in the context of enclaves might present a security risk to the enclave, as it creates shared storage between the AWS Nitro Enclave and the untrusted parent instance. Refer to the Persistent storage security section before proceeding. |
Before running any of the examples below, download the license from the Anjuna Resource Center.
This license file will be mounted to your nginx
Pod as
a Kubernetes secret.
Run the following command to create a Kubernetes secret:
$ kubectl create secret generic anjuna-license --from-file=license.yaml=license.yaml
Mounting a ConfigMap
A common use case for volumes is mounting configuration files inside of Pods.
In the example below,
the Anjuna Nitro K8s Toolset will automatically create an Enclave Image File from the Pod spec.
This includes correctly mapping the specified volumeMounts
inside of the enclave
so that the application running inside of the enclave can access the ConfigMap contents.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: config-map-name
data:
data.txt: "Welcome to Anjuna!"
---
apiVersion: v1
kind: Pod
metadata:
name: nitro-busybox-pod
labels:
nitro.k8s.anjuna.io/managed: "yes"
spec:
containers:
- name: nitro-busybox-pod
command:
- "sh"
- "-ec"
- |
cat /tmp/data/data.txt && echo
sleep infinity
image: busybox
resources:
limits:
memory: "2048Mi"
cpu: "2"
volumeMounts:
- name: config-volume
mountPath: /tmp/data
volumes:
- name: config-volume
configMap:
name: config-map-name
After its startup, the enclave will display the contents of /tmp/data/data.txt
and sleep indefinitely.
You can create this Pod by saving the Pod spec above to example-configmap.yaml
and then running:
$ kubectl create -f example-configmap.yaml
Check the Pod logs to confirm that the enclave can access the mounted file:
$ kubectl logs nitro-busybox-pod -f
The output will include many logs,
including the steps the Anjuna Nitro K8s Toolset takes to create an Enclave Image File from your Pod spec.
Then, the application (as specified in the command
field) will run.
You should see the following toward the end of the output:
ANJ-ENCLAVE: Service anjunafs started with original pid=465
ANJ-ENCLAVE: Mounting volume with mountPath '/tmp/data'
ANJ-ENCLAVE: Mounting volume with mountPath '/var/run/secrets/kubernetes.io/serviceaccount'
ANJ-ENCLAVE: Launched "/bin/sh" with pid=470
Welcome to Anjuna!
Using PersistentVolume
and PersistentVolumeClaim
The other common use case for volumes is providing persistent storage to containers,
which have ephemeral filesystems otherwise.
Applications running inside enclaves can also benefit from the persistent volumes in Kubernetes.
In the example below, you will mount /tmp/data
, backed by a 1Gi PersistentVolume
that is
dynamically provisioned by the Storage Class gp2
(default for EKS).
Note that manually provisioned volumes should work in the same way.
The application will write a file to the persisted directory
(see the command
field of the Pod spec).
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
storageClassName: gp2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: nitro-busybox-pod
labels:
nitro.k8s.anjuna.io/managed: "yes"
spec:
containers:
- name: nitro-busybox-pod
command:
- "sh"
- "-ec"
- |
echo "I am a persisted file" | tee /tmp/data/file.txt
sleep infinity
image: busybox
resources:
limits:
memory: "2048Mi"
cpu: "2"
volumeMounts:
- name: data
mountPath: /tmp/data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
To create this example, save the manifests above to example-pvc.yaml
and run:
kubectl create -f example-pvc.yaml
Using volumes with pre-built EIFs
In the examples above, the Anjuna Nitro K8s Toolset automatically created an Enclave Image File (EIF) from your Pod spec. This will generate enclave configuration files dynamically, which will map the volume mounts inside the enclave. If you want to have full control over the enclave configuration file, you can rely on a pre-built EIF. By using a pre-built EIF, the Anjuna Nitro K8s Toolset will run your EIF instead of creating one on-the-fly.
To use pre-built EIFs,
you must explicitly configure basic
volume mounts in your enclave configuration file.
Learn more about Persistent storage and
Persistent storage mounts.
For instance,
you could create or extend your existing enclave configuration file with a new basic
mount for
the data
volume,
as shown below:
version: 1.8
# ... other fields of your enclave config file ...
mounts:
- type: basic
name: data # must match the volume name in the Pod spec
mountPath: /tmp/data
After building and pushing your new EIF, you can transform the previous Pod spec with a
PersistentVolumeClaim
to use a pre-built EIF saved to s3://<bucket>/busybox.eif
by adding
the nitro.k8s.anjuna.io/imageLocation
annotation:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
storageClassName: gp2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: nitro-busybox-pod
labels:
nitro.k8s.anjuna.io/managed: "yes"
annotations:
nitro.k8s.anjuna.io/imageLocation: "s3://<bucket>/busybox.eif"
spec:
containers:
- name: nitro-busybox-pod
image: busybox
resources:
limits:
memory: "2048Mi"
cpu: "2"
volumeMounts:
- name: data
mountPath: /tmp/data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc