Tutorial: Deploying a custom container to an SC//Reliant node
This tutorial walks you through the full process of deploying your own container to the SC//Reliantâ„¢ platform. You build a simple container image, push it to Amazon Elastic Container Registry (ECR), define the registry and the container in SC//Reliant Platform Manager, and then deploy the change to your node.
The example container is a small nginx web server that serves a single page, so you can confirm it is running with a web browser or curl.
Prerequisites
This tutorial does not cover setting up an AWS account or AWS credentials. Before you start, you must have the following:
- A build machine with Docker installed. On macOS and Windows, this is Docker Desktop. Depending on how Docker is set up on your build machine, you might need to prefix
dockercommands withsudo. If so, usesudoconsistently for everydockercommand in this tutorial. - The AWS CLI version 2 installed on the build machine and signed in with an identity that has permission to create Amazon ECR repositories and push images to them.
- An AWS access key ID and secret access key that SC//Reliant nodes use to pull images from Amazon ECR. These must be long-term access keys for an IAM user, which have an access key ID beginning with
AKIA. If you do not have them, ask your AWS administrator. Temporary credentials cannot be used. See Only temporary AWS credentials are available. We recommend keys that have permission only to pull images. - Access to SC//Reliant Platform Manager, with permission to edit the node group the target node belongs to.
- SSH access to the target node. If the node is part of a cluster, perform every step on the node in this tutorial on the primary node of the cluster.
- If the node group has Network Access Control enabled, a Network Access rule that allows your computer's network to reach container ports on the node. Without one, you cannot request the page from your computer in Step 6. See Container (Docker) network access.
Requirements for container images
An SC//Reliant node runs Linux on x86_64 processors, so every image you deploy must be built for the linux/amd64 platform. An image built for an ARM processor, such as one built on an Apple silicon Mac, cannot run on a node. The Dockerfile in this tutorial targets linux/amd64 for you. For the full requirements, and for recommendations on building images for the edge, see Best practices for building container images.
Step 1: Create the Dockerfile
-
Create an empty directory for the project and change to it.
mkdir reliant-test cd reliant-test -
Create a file named
Dockerfilewith the following content.# Simple test image for deployment to an SC//Reliant node. # # SC//Reliant nodes run Linux on x86_64 processors, so the image must be # built for linux/amd64. The platform is pinned here so that the image is # built correctly even on an ARM-based build machine, such as an Apple # silicon Mac. FROM --platform=linux/amd64 nginx:stable-alpine # Replace the default nginx page with one that identifies this image. RUN printf '%s\n' \ '<!DOCTYPE html>' \ '<html>' \ '<head><title>SC//Reliant test container</title></head>' \ '<body><h1>Hello from an SC//Reliant node</h1></body>' \ '</html>' \ > /usr/share/nginx/html/index.html EXPOSE 80Docker's build checks report a
FromPlatformFlagConstDisallowedwarning for theFROMline. The warning is expected, because the fixed platform is intentional.
Step 2: Build and test the image locally
We recommend building and running your container locally to verify that it works before you deploy it to the SC//Reliant platform.
-
Build the image from the directory that contains the Dockerfile.
docker build -t reliant-test:1.0 . -
Confirm that the image was built for the correct platform.
docker image inspect reliant-test:1.0 --format '{{.Os}}/{{.Architecture}}'The output must be
linux/amd64. If it is anything else, the image will not run on an SC//Reliant node. -
Run the container, mapping port
8080on your build machine to port80in the container.docker run --rm -d --name reliant-test -p 8080:80 reliant-test:1.0On a build machine with an ARM processor, Docker runs the
linux/amd64image under emulation and prints a warning similar to the following. The warning is expected and the container still runs.WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested -
Confirm that the container responds.
curl http://localhost:8080The output contains
Hello from an SC//Reliant node. -
Stop the container. Because it was started with
--rm, Docker also removes it.docker stop reliant-test
Step 3: Push the image to Amazon ECR
In this step you create a private repository in Amazon ECR, sign Docker in to the registry, and push the image.
Replace the following placeholders in the commands:
<aws_account_id>: your 12-digit AWS account ID.<region>: the AWS Region to create the repository in, for exampleus-east-2.<repository_name>: the name of the repository, for examplereliant-test. A name can include a namespace separated by a slash, such asteam/reliant-test.
Your registry URI is <aws_account_id>.dkr.ecr.<region>.amazonaws.com. You use it again in Step 4.
-
Create the repository.
aws ecr create-repository --repository-name <repository_name> --region <region>The output includes the
repositoryUri, in the format<aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository_name>. -
Sign Docker in to your registry.
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.comThe output ends with
Login Succeeded. If you rundockercommands withsudo, placesudobeforedocker login, not beforeaws. The sign-in token is valid for 12 hours, after which you must run this command again. -
Tag the local image with the repository URI and a version tag.
docker tag reliant-test:1.0 <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository_name>:1.0 -
Push the image.
docker push <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository_name>:1.0 -
Confirm that the image is in the repository.
aws ecr describe-images --repository-name <repository_name> --region <region> --query 'imageDetails[].imageTags'The output includes the
1.0tag.
Step 4: Define the container registry in SC//Reliant Platform Manager
In this step you give the nodes in your node group the registry URI and access keys they need to pull images from your private ECR registry.
Containers on a clustered pair of nodes are defined in the Cluster Docker Resources property, which this tutorial uses. Containers on a standalone node are defined in the Docker property instead. The fields are the same in both. For more information, see Managing SC//Reliant Platform Manager data for containers.
- Sign in to the SC//Reliant Platform Manager at https://platform.reliant.io/.
- From the left navigation menu, choose Node Groups, and then search for and select your node group.
- Choose Node Group Properties, and then open the Cluster Docker Resources property for editing.
- For ECR, turn on Enable this option.
- Choose Add new value.
- In the new field, under which Fully qualified URL of your ECR is displayed, enter your registry URI in the format
<aws_account_id>.dkr.ecr.<region>.amazonaws.com. Do not includehttps://or the repository name. - For Access ID, enter the AWS access key ID that the nodes use to pull images.
- For access key, enter the matching AWS secret access key.
- Choose Save.
- On the Review your changes page, confirm that the only property value change is to Cluster Docker Resources, and then choose Save.
- On the Confirm Impact pop-up window, type the number of impacted nodes shown in the message, and then choose Confirm.
Saving the property stores the configuration in the SC//Reliant Platform Manager but does not apply it to the nodes. You deploy it in Step 6, together with the container definition.
Step 5: Define the container in SC//Reliant Platform Manager
In this step you define the container, and the Docker network it connects to, in the same Cluster Docker Resources property you edited in Step 4. For the full list of settings, see the Containers hash reference.
- In the SC//Reliant Platform Manager, open the Cluster Docker Resources property of your node group for editing, as in Step 4.
-
If Custom Networks does not already contain a network you want the container to use, add one.
- Under Custom Networks, choose Add new value.
- In the new field, enter a name for the network, for example
net1. - For Driver, enter
bridge. - Optionally, for Subnet, enter the IP address subnet to assign to the network in CIDR format, for example
172.28.29.0/26. Choose a subnet that does not overlap any network the node is connected to.
Docker cannot change a network after it has been created on a node, so decide on the settings before you deploy.
-
Under Containers, choose Add new value. If the node group has no containers defined yet, a blank container entry is already displayed. Use that entry instead.
- In the new field, under which Name of the docker container is displayed, enter a name for the container, for example
nginx. Use a name that no other container in the node group uses. - For Image, enter the full repository URI without the tag, in the format
<aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository_name>. - For Tag, enter
1.0. - For Exposed Ports, enter
80:80. The format is<host_port>:<container_port>, the same as the-poption ofdocker run, so this publishes port80in the container on port80of the node. No other container on the node can already publish the same host port. To publish more ports, choose Add new value and enter one mapping in each field. - For Networks, enter the name of the network from Custom Networks, for example
net1. - Choose Save, review the changes, and confirm the impact, as in Step 4.
Step 6: Deploy the change and verify the container
In this step you run Puppet on the node to apply the configuration, and then confirm that the container is running and responds.
-
Sign in to the node.
ssh <node_hostname> -
If the node is part of a cluster, confirm that it is the primary node. For more information, see cluster.status.
rvc cluster statusActive Nodemust betrue. If it isfalse, end the session and sign in to the other node in the cluster instead. -
Run Puppet. For more information, see puppet.run.
rvc puppet runThe command prints
Running puppet...and returns while the run continues in the background. -
Check the Puppet run. For more information, see puppet.status.
rvc puppet statusRepeat the command until
StateisstoppedandLast Run Atshows the time of your run. -
Confirm that the container is running. For more information, see docker.containers.
rvc docker containersThe container is named
docker-container-<container_name>-resource, its image is your repository URI with the tag1.0, and its status begins withUp. On a cluster,In Clusterisyes, because the cluster manages the container. The output is similar to the following:ID Image Names Status In Cluster ------------------------------------------------------------------------------------------------------------------------------------------- 31cdc003ea71 <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository_name>:1.0 docker-container-nginx-resource Up 8 seconds yes -
From your computer, request the page from the node.
curl http://<node_ip_address>:80The output contains
Hello from an SC//Reliant node.
Troubleshooting
If you run into a problem at any step, see Troubleshooting container deployment issues.