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 .pod.containers.image in the Confidential Pod Configuration, which is set at build time. If they do not match, the Confidential Pod emits a warning and uses the measured, build-time image instead.

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 .spec.containers[0].name field of the Pod (or .spec.template.spec.containers[0].name of a Deployment) must match the container name that you provided via .pod.containers.name in the Confidential Pod Configuration, which is set at build time.

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 DB_USERNAME and DB_PASSWORD are secret credentials, you may not want to store them as plaintext in your Kubernetes manifest.

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_LEVEL is set to "debug", as defined in the Pod specification (and allowed by the Confidential Pod Configuration file).

  • DB_USERNAME is set to user, which is the value defined in the Confidential Pod Configuration file. The value set in the Pod specification (root) was ignored, because DB_USERNAME was not explicitly allowed by the Confidential Pod Configuration file untrusted.env.allow field.

  • DB_PASSWORD is not set, because it is only defined in the Pod specification, but not explicitly allowed by the Confidential Pod Configuration file untrusted.env.allow field.

Stop the application Pod

To stop and delete the Confidential Pod, run the following command:

$ kubectl delete -f env.yaml

The Confidential VM (CVM) that was created to run this Confidential Pod will also be deleted in Azure.