Deploy a custom Anjuna Confidential Pod
To deploy your custom application as an Anjuna Confidential Pod (Confidential Pod), create a Kubernetes Pod specification:
|
The image specified in the Pod specification should match the image specified via
The cluster must have access to your container image as well, otherwise the Confidential Pod might fail to start with image pull errors. For private images, provide credentials to the cluster via an image pull secret or other means. The |
Create an image pull secret
If the container image (${CONTAINER_IMAGE}) built on the previous page
was pushed to a private registry,
you must create an image pull secret so that Kubernetes can pull it
when deploying your Confidential Pod.
For example, to create an image pull secret for the Azure Container Registry provisioned by Terraform, run:
$ export ACR_TOKEN_NAME="acr-token-${RANDOM}"
$ export ACR_TOKEN=$(az acr token create -n ${ACR_TOKEN_NAME} \
-r ${AZURE_REGISTRY_NAME} \
--repository env content/read \
| jq -r '.credentials.passwords[] | select(.name == "password1") | .value')
$ kubectl create secret docker-registry anjuna-kubernetes-env \
--docker-server ${AZURE_REGISTRY_NAME}.azurecr.io \
--docker-username ${ACR_TOKEN_NAME} \
--docker-password ${ACR_TOKEN}
Once the secret is created, reference it in the imagePullSecrets field of your Pod specification.
$ cat <<EOF > env.yaml
apiVersion: v1
kind: Pod
metadata:
name: env
labels:
app: env
# use the Anjuna Custom Container Runtime
# to run this Pod as a Confidential Pod
anjuna.io/run-confidential: "yes"
annotations:
# reference the Confidential Pod image ID
cvm.anjuna.io/image: "${AZURE_IMAGE_ID}"
spec:
imagePullSecrets:
- name: anjuna-kubernetes-env
containers:
- name: env
image: "${CONTAINER_IMAGE}:latest"
imagePullPolicy: Always
env:
- name: LOG_LEVEL
value: "debug"
- name: DB_USERNAME
value: "root"
- name: DB_PASSWORD
value: "p455w0rd"
volumeMounts:
- name: data
mountPath: /data
- name: logshipper
image: docker.io/library/alpine:latest
imagePullPolicy: Always
command: ["sh", "-c", "tail -F /data/app.log"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir:
medium: Memory
EOF
This Confidential Pod specification defines two containers that share an in-memory empty directory:
-
env, the main application, which writes its logs to/data/app.log. -
logshipper, which tails the same file from the shared directory and re-emits its contents on standard output.
The data volume is declared as an emptyDir that uses the Memory medium,
and is mounted into both containers at /data.
The Memory medium is required:
it backs the directory with memory rather than the worker Node’s disk,
which keeps the shared data inside the CVM.
This matches the emptyDirs and emptyDirMounts
defined in the Confidential Pod Configuration file on the previous page.
Refer to
Empty directories
for more details on how empty directories are configured and shared.
The specification also sets three environment variables on the env container:
-
LOG_LEVEL=debug -
DB_USERNAME=root -
DB_PASSWORD=p455w0rd
Only LOG_LEVEL will be applied to the Confidential Pod,
because it was explicitly allowed by the Confidential Pod Configuration file.
The other environment variables defined in the Pod specification will be ignored.
Refer to untrusted configuration
to learn more about how to set environment variables,
and how to allow environment variables and volume mounts from the Pod specification.
Refer to the Troubleshooting section to see the log message that notifies you when these environment variables have been ignored.
|
Since Instead, you can configure your Confidential Pod to fetch secrets from an Anjuna Policy Manager (APM) instance. Secrets will be provided to your application only after its measurements are verified by the APM through a remote attestation process. Refer to the Anjuna Policy Manager documentation to see how to configure an APM integration for your Confidential Pod. |
Start the application Pod
To start the Confidential Pod, run the following command:
$ kubectl apply -f env.yaml
This command applies the Pod spec to the cluster, which will in turn launch a new Confidential Pod for the custom application.
Use the following command to check the status of your Pod:
$ kubectl get pod env
When the Pod status is Running,
inspect the logs of the logshipper container:
$ kubectl logs env -c logshipper
You should see output similar to the following:
LOG_LEVEL=debug
PWD=/
HOME=/root
DB_USERNAME=user
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/env
logging
logging
The environment that the env container recorded at startup demonstrates that
both containers share the in-memory empty directory:
the logshipper container is reading the very file that the env container wrote.
The recurring logging lines confirm that the logshipper is streaming the file
as it grows, rather than reading it only once.
Note that in the environment recorded above:
-
LOG_LEVELis set to "debug", as defined in the Pod specification (and allowed by the Confidential Pod Configuration file). -
DB_USERNAMEis set touser, which is the value defined in the Confidential Pod Configuration file. The value set in the Pod specification (root) was ignored, becauseDB_USERNAMEwas not explicitly allowed by the Confidential Pod Configuration fileuntrusted.env.allowfield. -
DB_PASSWORDis not set, because it is only defined in the Pod specification, but not explicitly allowed by the Confidential Pod Configuration fileuntrusted.env.allowfield.