Build an Anjuna Confidential Pod image
If you have not already done so, follow the guide Example 1 - Deploy Nginx as an Anjuna Confidential Pod. It goes into more detail on the process of building Anjuna Confidential Pod (Confidential Pod) images.
In this example, you will build a custom application from scratch that uses some of the features of the Anjuna Confidential Pod Configuration File.
Build a container
Start by building a simple Docker container.
First, cd into a new temporary directory.
$ cd $(mktemp -d)
Then, run the following command to create the Dockerfile,
which defines an image that writes its logs to a file in a shared directory,
not to standard output.
The application first records its environment using the env command,
then appends a log line every second:
$ cat <<EOF > Dockerfile
FROM alpine:latest
CMD ["sh", "-c", "env > /data/app.log; while true; do echo logging >> /data/app.log; sleep 1; done"]
EOF
In this example,
the container image is stored in the Docker Artifact Registry of Google Cloud,
identified by the environment variable ANJ_IMAGE_REGISTRY and path ANJ_IMAGE_PATH.
$ export CONTAINER_IMAGE="${ANJ_IMAGE_REGISTRY}/${ANJ_IMAGE_PATH}/env"
$ docker build . -t "${CONTAINER_IMAGE}"
$ docker push "${CONTAINER_IMAGE}"
Build the Confidential Pod image
Building a Confidential Pod image builds and measures a VM disk image that contains your target application. Creating and storing VM disks in Google Cloud requires a storage bucket. The following sections will guide you step by step in this process.
Before creating the needed resources, generate a random suffix that will be used to ensure that resource names are unique. It also helps to quickly identify related resources (i.e., if they share the same suffix):
$ export SUFFIX="${RANDOM}"
Create a storage bucket
Before building the Confidential Pod image, create a storage bucket to store the measured disk image.
$ export GCP_STORAGE_BUCKET="env-${SUFFIX}"
$ gcloud storage buckets create gs://${GCP_STORAGE_BUCKET}
Build and upload the Confidential Pod image
Before building the Confidential Pod image, create a Confidential Pod Configuration file.
The configuration file env-cpod-config.yaml below does the following:
-
Sets the value of the environment variable
DB_USERNAMEtouser. -
Allows the environment variable
LOG_LEVELto be set in the Pod specification. -
Defines a shared, in-memory empty directory named
data. -
Runs a
logshippercontainer that tails the log file that the mainenvcontainer writes to the shared directory.
The env container writes its logs to /data/app.log,
and the logshipper container mounts the same data empty directory
and tails that file, re-emitting each line on its own standard output.
Because the empty directory is backed by memory,
it is a convenient place for containers to exchange data
without writing it to the worker Node’s disk.
This example illustrates how multiple containers in a Confidential Pod can share data
securely through an empty directory.
Refer to the Configuration reference to learn more about the Confidential Pod Configuration file and all the features that it supports. In particular, see Empty directories for details on sharing data between containers.
$ cat > env-cpod-config.yaml <<EOF
pod:
emptyDirs:
- name: data
containers:
- name: env # This should match the name of the container in the Pod/Deployment.
image: "${CONTAINER_IMAGE}:latest"
env:
- name: DB_USERNAME
value: user
untrusted:
env:
allow:
- LOG_LEVEL
emptyDirMounts:
- name: data
mountPath: /data
- name: logshipper # tails the log file written by the env container
image: docker.io/library/alpine:latest
command: ["sh", "-c", "tail -F /data/app.log"]
emptyDirMounts:
- name: data
mountPath: /data
EOF
To build the Confidential Pod image, run the following command:
In the command below,
you must always specify the fully-qualified container image reference,
i.e., including the registry, the repository, and a tag, as in <registry>/<repository>:<tag>.
|
$ ${ANJ_K8S_TOOLSET_DIR}/anjuna-k8s-cli/anjuna-k8s-cli build gcp \
--disk-size 2G \
--cpod-config env-cpod-config.yaml
Once the image is built, upload it to the Google Cloud bucket you created previously. Notice that a suffix is used in the image name to differentiate between versions. Make sure to change the version number on subsequent uploads, because the command will fail if the version number already exists.
$ VERSION=0001
$ export ANJUNA_ENV_IMAGE_NAME=env-image-${VERSION}
$ anjuna-gcp-cli disk upload \
--bucket ${GCP_STORAGE_BUCKET} \
--disk disk.raw \
--image ${ANJUNA_ENV_IMAGE_NAME}
Note the ANJUNA_ENV_IMAGE_NAME variable exported here. It will be used
when configuring the Kubernetes Deployment manifest
on the next page of this guide to deploy the env-image-${VERSION} as an
Confidential Pod.