GreenGrass IoT - Deploy docker-compose along with it's dependencies as a different component

0

Hello, I'm trying to deploy docker-compose dependencies and prerequisites on my IoT ubuntu based edge device, then run my custom docker-compose.yaml component. When trying to deploy only the docker-compose dependencies component, and then the custom docker-compose.yaml component, everything works fine. Although, when I'm connecting the two of them into one deployment, and putting the docker-compose-dependencies as a dependency component in my recipe, it seems to ignore the docker-compose-dependency (even though it is appearing in the dependency resolver in GreenGrass logs).

My docker-compose-dependency recipe:

{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "docker-compose-dependency",
  "ComponentVersion": "1.0.9",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "My first Greengrass component.",
  "ComponentPublisher": "Me",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "Message": "world"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Name": "Linux",
      "Lifecycle": {
        "Run": {
          "Script": "install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && chmod a+r /etc/apt/keyrings/docker.gpg && echo deb [arch=arm64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu   focal stable > /etc/apt/sources.list.d/docker.list && apt-get update && apt-get install docker-ce docker-ce-cli containerd.io -y && curl -L https://github.com/ubiquiti/docker-compose-aarch64/releases/download/1.22.0/docker-compose-Linux-aarch64 -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose",
          "RequiresPrivilege": "true"
        }
      },
      "Artifacts": []
    }
  ],
  "Lifecycle": {}
}

My docker-compose-yaml recipe:

{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "docker-compose-yaml",
  "ComponentVersion": "1.0.31",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "A component that uses Docker Compose to run images from our private ecr.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.DockerApplicationManager": {
      "VersionRequirement": ">=2.0.0 <2.1.0",
      "DependencyType": "HARD"
    },
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": ">=2.0.0 <2.1.0",
      "DependencyType": "HARD"
    },
    "docker-compose-dependency": {
      "VersionRequirement": ">1.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "all"
      },
      "Lifecycle": {
        "run": "docker-compose -f {artifacts:path}/docker-compose.yaml up"
      },
      "Artifacts": [
        {
          "Uri": "docker:****************.dkr.ecr.eu-central-1.amazonaws.com/my-test-image:******",
          "Unarchive": "NONE",
          "Permission": {
            "Read": "OWNER",
            "Execute": "NONE"
          }
        },       
        {
          "Uri": "docker:traefik:v2.10",
          "Unarchive": "NONE",
          "Permission": {
            "Read": "OWNER",
            "Execute": "NONE"
          }
        },
        {
          "Uri": "s3://*********/docker-compose.yaml",
          "Digest": "***********************************************",
          "Algorithm": "SHA-256",
          "Unarchive": "NONE",
          "Permission": {
            "Read": "OWNER",
            "Execute": "NONE"
          }
        }
      ]
    }
  ],
  "Lifecycle": {}
}

I tried to create a deployment once with only the docker-compose-yaml component to be installed, and once with both of them to be installed, but ended up with the same result.

Thanks!

1 Answer
0

The issue is that docker is a pre-requisite of aws.greengrass.DockerApplication, while in your case you are installing docker via the docker-compose-dependencies component which is only a dependency of your docker-compose-yaml component. When Greenrass tried to pull the docker: container images artifacts, it fails since docker is not yet installed.

While I would recommend to install dependencies such as docker, language run-times, etc, as part of the device system image, you can:

  1. Replace the docker: artifacts with s3: artifacts, storing the container images in S3 and loading them up in your recipe Run: lifecycle via docker load {artifacts:path}/image.tar.gz. The advantage of this approach is that the image is downloaded before your current component is stopped, thus limiting the downtime

  2. Remove the container images from the artifacts section and perform a docker pull <image> in your recipe Run: lifecycle. This allows you to leverage the container registry and not have to export the image to S3, but will cause a longer downtime, since your current component will be stopped before the new image gets pulled from the registry.

  3. Install docker on the system, and only keep curl -L https://github.com/ubiquiti/docker-compose-aarch64/releases/download/1.22.0/docker-compose-Linux-aarch64 -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose" as part of your docker-compose-dependencies component.

  4. Ensure docker-compose-dependencies is deployed to the device before deploying the docker-compose-yaml component (or any other component depending on aws.greengrass.DockerApplication.

AWS
EXPERT
answered 8 months ago
  • Thanks a lot for your answer!

    1. As for pushing those images to s3, it might limit the flexibility in case we're using latest images, and force us to create some CI processes to always keep the s3 images up-to-date.
    2. Good call, might go with this one although I understood that pulling from our private ecr using policies and roles is a more secure way than having pull secret on the edge.
    3. Sounds good.
    4. Can you please elaborate on this one? Because this is basically what I initially tried to do, but struggled with the dependencies as mentioned. I guess this one should come along answer number 3, is that right?
    1. I recommend to use specific versions of the containers for each recipe version. If you use latest, the image might not endup being the one you expect since Greengrass might not pull it from the repo
    2. You can leverage the TES role to login into ECR as explained here (https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry)
    3. What I meant is that you do not use dependencies but make sure via custom logic that the docker-compose-dependencies component has been already deployed to the devices where you want to deploy docker-compose-yaml.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions