

终止支持通知： Amazon 将于 2025 年 12 月 15 日终止对的支持 Amazon IoT Analytics。2025 年 12 月 15 日之后，您将无法再访问 Amazon IoT Analytics 控制台或 Amazon IoT Analytics 资源。有关更多信息，请参阅[Amazon IoT Analytics 终止支持](https://docs.amazonaws.cn/iotanalytics/latest/userguide/iotanalytics-end-of-support.html)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用自定义容器进行分析
<a name="automate-custom-container"></a>

本节包含有关如何使用 Jupyter notebook 构建 Docker 容器的信息。如果重复使用第三方构建的笔记本，则存在安全风险：包含的容器可能使用您的用户权限执行任意代码。此外，笔记本生成的 HTML 可以显示在 Amazon IoT Analytics 控制台中，从而在显示 HTML 的计算机上提供潜在的攻击媒介。在使用之前，请确保您信任任何第三方笔记本的作者。

您可以创建自己的自定义容器并使用该 Amazon IoT Analytics 服务运行它。为此，您需要安装 Docker 映像并将其上传到 Amazon ECR，然后设置数据集来运行容器操作。本节提供一个使用 Octave 的过程示例。

本教程假定：
+ 本地计算机上已安装 Octave
+ 本地计算机上已设置 Docker 账户
+ 拥有 Amazon ECR 或 Amazon IoT Analytics 访问权限的 Amazon 账户

**步骤 1：设置 Docker 映像**

本教程需要三个主要文件。其名称和内容如下：
+ `Dockerfile` - 用于 Docker 容器化过程的初始设置。

  ```
  FROM ubuntu:16.04
  
  # Get required set of software
  RUN apt-get update
  RUN apt-get install -y software-properties-common
  RUN apt-get install -y octave
  RUN apt-get install -y python3-pip
  
  # Get boto3 for S3 and other libraries
  RUN pip3 install --upgrade pip
  RUN pip3 install boto3
  RUN pip3 install urllib3
  
  # Move scripts over
  ADD moment moment
  ADD run-octave.py run-octave.py
  
  # Start python script
  ENTRYPOINT ["python3", "run-octave.py"]
  ```
+ `run-octave.py`— 解析来自 JSON Amazon IoT Analytics，运行 Octave 脚本，然后将构件上传到 Amazon S3。

  ```
  import boto3
  import json
  import os
  import sys
  from urllib.parse import urlparse
  
  # Parse the JSON from IoT Analytics
  with open('/opt/ml/input/data/iotanalytics/params') as params_file:
      params = json.load(params_file)
  
  variables = params['Variables']
  
  order = variables['order']
  input_s3_bucket = variables['inputDataS3BucketName']
  input_s3_key = variables['inputDataS3Key']
  output_s3_uri = variables['octaveResultS3URI']
  
  local_input_filename = "input.txt"
  local_output_filename = "output.mat"
  
  # Pull input data from S3...
  s3 = boto3.resource('s3')
  s3.Bucket(input_s3_bucket).download_file(input_s3_key, local_input_filename)
  
  # Run Octave Script
  os.system("octave moment {} {} {}".format(local_input_filename, local_output_filename, order))
  
  # # Upload the artifacts to S3
  output_s3_url = urlparse(output_s3_uri)
  output_s3_bucket = output_s3_url.netloc
  output_s3_key = output_s3_url.path[1:]
  
  s3.Object(output_s3_bucket, output_s3_key).put(Body=open(local_output_filename, 'rb'), ACL='bucket-owner-full-control')
  ```
+ `moment` - 一个简单的 Octave 脚本，可根据输入或输出文件和指定的顺序计算时刻。

  ```
  #!/usr/bin/octave -qf
  
  arg_list = argv ();
  input_filename = arg_list{1};
  output_filename = arg_list{2};
  order = str2num(arg_list{3});
  
  [D,delimiterOut]=importdata(input_filename)
  M = moment(D, order)
  
  save(output_filename,'M')
  ```

1. 下载每个文件的内容。创建一个新目录，并将所有文件都放入该目录，然后`cd`到该目录。

1. 运行以下命令。

   ```
   docker build -t octave-moment .
   ```

1. 您应该会在 Docker 存储库中看到一个新映像。通过运行以下命令验证它。

   ```
   docker image ls | grep octave-moment
   ```

**步骤 2：将 Docker 映像上传到 Amazon ECR 存储库**

1. 创建 Amazon ECR 存储库。

   ```
   aws ecr create-repository --repository-name octave-moment
   ```

1. 获取 Docker 环境的登录信息。

   ```
   aws ecr get-login
   ```

1. 复制输出并运行它。输出应与以下内容类似。

   ```
   docker login -u AWS -p {{password}} -e none https://{{your-aws-account-id}}.dkr.ecr..amazonaws.com
   ```

1. 用 Amazon ECR 存储库标签标记您创建的映像。

   ```
   docker tag {{your-image-id}}  {{your-aws-account-id}}.dkr.ecr.{{region}}.amazonaws.com/octave-moment
   ```

1. 将映像推送到 Amazon ECR

   ```
   docker push {{your-aws-account-id}}.dkr.ecr.{{region}}.amazonaws.com/octave-moment
   ```

**步骤 3：将示例数据上传到 Amazon S3 存储桶**

1. 将以下内容下载至文件`input.txt`。

   ```
   0.857549  -0.987565  -0.467288  -0.252233  -2.298007
    0.030077  -1.243324  -0.692745   0.563276   0.772901
   -0.508862  -0.404303  -1.363477  -1.812281  -0.296744
   -0.203897   0.746533   0.048276   0.075284   0.125395
    0.829358   1.246402  -1.310275  -2.737117   0.024629
    1.206120   0.895101   1.075549   1.897416   1.383577
   ```

1. 创建名称为 `octave-sample-data-{{your-aws-account-id}}` 的 Amazon S3 存储桶。

1. 将文件 `input.txt` 上传到您刚刚创建的 Amazon S3 存储桶。现在，您应该有了一个名为 `octave-sample-data-{{your-aws-account-id}}` 的存储桶，其中包含文件 `input.txt`。

**步骤 4：创建容器执行角色**

1. 将以下内容复制到名为 `role1.json` 的文件中。{{your-aws-account-id}}替换为您的 Amazon 账户 ID {{aws-region}} 和您的 Amazon 资源 Amazon 区域。
**注意**  
此示例包括一个全局条件上下文密钥，用于防止混淆代理安全问题。有关更多信息，请参阅 [防止跨服务混淆座席](cross-service-confused-deputy-prevention.md)。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": [
                       "sagemaker.amazonaws.com",
                       "iotanalytics.amazonaws.com"
                   ]
               },
               "Action": "sts:AssumeRole",
               "Condition": {
                   "StringEquals": {
                       "aws:SourceAccount": "{{123456789012}}"
                   },
                   "ArnLike": {
                       "aws:SourceArn": "arn:aws:iotanalytics:{{us-east-1}}:{{123456789012}}:dataset/{{your-dataset}}"
                   }
               }
           }
       ]
   }
   ```

------

1. 使用您下载的文件 Amazon IoT Analytics`role1.json`，创建一个向 SageMaker AI 和授予访问权限的角色。

   ```
   aws iam create-role --role-name container-execution-role --assume-role-policy-document file://role1.json
   ```

1. 将以下内容下载到名为 `policy1.json` 的文件，并将 {{`your-account-id`}} 替换为您的账户 ID（请参阅 `Statement:Resource` 下的第二个 ARN）。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetBucketLocation",
                   "s3:PutObject",
                   "s3:GetObject",
                   "s3:PutObjectAcl"
               ],
               "Resource": [
                   "arn:aws:s3:*:*:dataset/*",
                   "arn:aws:s3:*:*:octave-sample-data-{{123456789012}}/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "iotanalytics:*"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "ecr:GetAuthorizationToken",
                   "ecr:GetDownloadUrlForLayer",
                   "ecr:BatchGetImage",
                   "ecr:BatchCheckLayerAvailability",
                   "logs:CreateLogGroup",
                   "logs:CreateLogStream",
                   "logs:DescribeLogStreams",
                   "logs:GetLogEvents",
                   "logs:PutLogEvents"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetBucketLocation",
                   "s3:ListBucket",
                   "s3:ListAllMyBuckets"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 使用您刚刚下载的文件 `policy.json` 创建一个 IAM policy。

   ```
   aws iam create-policy --policy-name ContainerExecutionPolicy --policy-document file://policy1.json
   ```

1. 将 策略附加到该角色。

   ```
   aws iam attach-role-policy --role-name container-execution-role --policy-arn arn:aws:iam::{{your-account-id}}:policy/ContainerExecutionPolicy
   ```

**步骤 5：使用容器操作创建一个数据集**

1. 将以下内容下载到名为 `cli-input.json` 的文件中，并用相应的值替换 {{`your-account-id`}} 和 {{`region`}} 的所有实例。

   ```
   {
       "datasetName": "octave_dataset",
       "actions": [
           {
               "actionName": "octave",
               "containerAction": {
                   "image": "{{your-account-id}}.dkr.ecr.{{region}}.amazonaws.com/octave-moment",
                   "executionRoleArn": "arn:aws:iam::{{your-account-id}}:role/container-execution-role",
                   "resourceConfiguration": {
                       "computeType": "ACU_1",
                       "volumeSizeInGB": 1
                   },
                   "variables": [
                       {
                           "name": "octaveResultS3URI",
                           "outputFileUriValue": {
                               "fileName": "output.mat"
                           }
                       },
                       {
                           "name": "inputDataS3BucketName",
                           "stringValue": "octave-sample-data-{{your-account-id}}"
                       },
                       {
                           "name": "inputDataS3Key",
                           "stringValue": "input.txt"
                       },
                       {
                           "name": "order",
                           "stringValue": "3"
                       }
                   ]
               } 
           }
       ]
   }
   ```

1. 使用您刚刚下载并编辑的文件 `cli-input.json` 创建一个数据集。

   ```
   aws iotanalytics create-dataset —cli-input-json file://cli-input.json
   ```

**步骤 6：调用数据集内容生成**

1. 运行以下命令。

   ```
   aws iotanalytics create-dataset-content --dataset-name octave-dataset
   ```

**步骤 7：获取数据集内容**

1. 运行以下命令。

   ```
   aws iotanalytics get-dataset-content --dataset-name octave-dataset --version-id \$LATEST
   ```

1. 您可能需要等待几分钟时间，直到 `DatasetContentState` 为 `SUCCEEDED`。

**步骤 8：在 Octave 中打印输出**

1. 使用 Octave shell 通过运行以下命令从容器中打印输出。

   ```
   bash> octave
   octave> load output.mat
   octave> disp(M)
   -0.016393 -0.098061 0.380311 -0.564377 -1.318744
   ```