برنامه نویسی

تامین ناوگان برای دستگاه های لینوکس جاسازی شده با AWS IoT Greengrass

معرفی

مدیریت ناوگان بزرگی از دستگاه‌های تعبیه‌شده می‌تواند پیچیده و چالش برانگیز باشد، به‌ویژه زمانی که صحبت از ایجاد یک تصویر واحد است که می‌تواند روی چندین دستگاه فلش شود. این دستگاه‌ها باید بتوانند با استفاده از اطلاعات منحصربه‌فرد مانند شماره سریال خود، پس از راه‌اندازی اولیه، خود تهیه شوند. در این پست وبلاگ، ما بحث خواهیم کرد که چگونه AWS IoT Greengrass – Fleet Provisioning می تواند این فرآیند را برای دستگاه های لینوکس جاسازی شده ساده کند و آن را کارآمدتر و قابل اعتمادتر کند.

برای مهندسین سیستم های جاسازی شده با تجربه در لینوکس جاسازی شده و Yocto، ما شما را در ساخت تصویر Raspberry Pi Yocto با Greengrass با پلاگین Fleet Provisioning راهنمایی می کنیم. این امر تهیه و مدیریت یکپارچه دستگاه و همچنین ثبت و پیکربندی خودکار را تضمین می کند.

تامین ناوگان بر اساس ادعا

لطفاً در اینجا توجه داشته باشید که لامبدا از پیش تهیه شده اختیاری است اما به منظور ایجاد یک لایه امنیتی بیشتر تشویق می شود. در این پست به آن نمی پردازیم. شما می توانید در اینجا بیشتر در مورد آن بیاموزید.

با مجموعه مرحله، بیایید به پیش نیازهای راه اندازی AWS IoT Greengrass و Fleet Provisioning برای دستگاه های لینوکس تعبیه شده شما بپردازیم.

پیش نیازها

قبل از وارد شدن به فرآیند آماده سازی هاست و پیکربندی ساخت تصویر Yocto، راه اندازی AWS IoT Core ضروری است. این شامل ایجاد خط مشی ها، دریافت گواهی ادعا و اطمینان از نصب و پیکربندی AWS CLI است. اطلاعات کلی در مورد نحوه انجام این کار را می توان در راهنمای توسعه دهنده AWS IoT Greengrass یافت.
به طور خلاصه، ما نیاز داریم:

  1. نقش IAM تبادل توکن، که دستگاه‌های اصلی برای مجاز کردن تماس‌ها به سرویس‌های AWS و نقش مستعار نقش AWS IoT که به نقش تبادل توکن اشاره می‌کند، استفاده می‌کنند.
  2. یک الگوی تامین ناوگان AWS IoT. الگو باید اطلاعات مورد نیاز برای ایجاد چیز و خط مشی را مشخص کند که به دستگاه هسته سبز گراس ایجاد شده متصل می شود. می‌توانید از نام خط‌مشی اینترنت اشیا موجود استفاده کنید یا خط‌مشی را روی الگو تعریف کنید.
  3. یک گواهی ادعای تامین اینترنت اشیاء AWS و کلید خصوصی برای الگوی تامین ناوگان.

دستگاه ها را می توان با گواهی ادعای تامین و کلید خصوصی تعبیه شده در آنها ساخت. هنگامی که دستگاه برای اولین بار به AWS IoT متصل می شود، از گواهی ادعا برای ثبت دستگاه جدید و مبادله آن به گواهی دستگاه منحصر به فرد استفاده می کند. گواهی ادعای تامین نیاز به ضمیمه خط مشی AWS IoT دارد که به دستگاه ها اجازه می دهد تا الگوی تامین ناوگان را ثبت و استفاده کنند.

برای کارآمدتر کردن این فرآیند، می‌توانیم از یک الگوی CloudFormation استفاده کنیم که اکثر این مراحل را خودکار می‌کند:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  ProvisioningTemplateName:
    Type: String
    Default: 'GreengrassFleetProvisioningTemplate' 
  GGTokenExchangeRoleName:
    Type: String
    Default: 'GGTokenExchangeRole'
  GGFleetProvisioningRoleName:
    Type: String
    Default: 'GGFleetProvisioningRole'
  GGDeviceDefaultPolicyName:
    Type: String
    Default: 'GGDeviceDefaultIoTPolicy'
  GGProvisioningClaimPolicyName:
    Type: String
    Default: 'GGProvisioningClaimPolicy'

Resources:

  GGTokenExchangeRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref GGTokenExchangeRoleName
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - credentials.iot.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: "https://dev.to/"
      Policies:
        - PolicyName: !Sub ${GGTokenExchangeRoleName}Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - 'iot:DescribeCertificate'
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                  - 'logs:DescribeLogStreams'
                  - 's3:GetBucketLocation'
                Resource: '*'

  GGTokenExchangeRoleAlias:
    Type: AWS::IoT::RoleAlias
    Properties:
      RoleArn: !GetAtt GGTokenExchangeRole.Arn
      RoleAlias: !Sub ${GGTokenExchangeRoleName}Alias

  GGFleetProvisioningRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref GGFleetProvisioningRoleName
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - iot.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: "https://dev.to/"
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AWSIoTThingsRegistration'

  GGDeviceDefaultPolicy:
    Type: AWS::IoT::Policy
    Properties:
      PolicyName: !Ref GGDeviceDefaultPolicyName
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
            - 'iot:Connect'
            - 'iot:Publish'
            - 'iot:Subscribe'
            - 'iot:Receive'
            - 'iot:Connect'
            - 'greengrass:*'
          Resource: '*'
        - Effect: Allow
          Action:
            - 'iot:AssumeRoleWithCertificate'
          Resource: !GetAtt GGTokenExchangeRoleAlias.RoleAliasArn

  GGFleetProvisionTemplate:
    Type: AWS::IoT::ProvisioningTemplate
    Properties:
      TemplateName: !Ref ProvisioningTemplateName
      Description: 'Fleet Provisioning template for AWS IoT Greengrass.'
      Enabled: True
      ProvisioningRoleArn: !GetAtt GGFleetProvisioningRole.Arn
      TemplateBody: !Sub |+ 
        {
          "Parameters": {
            "ThingName": {
              "Type": "String"
            },
            "ThingGroupName": {
              "Type": "String"
            },
            "AWS::IoT::Certificate::Id": {
              "Type": "String"
            }
          },
          "Resources": {
            "GGThing": {
              "OverrideSettings": {
                "AttributePayload": "REPLACE",
                "ThingGroups": "REPLACE",
                "ThingTypeName": "REPLACE"
              },
              "Properties": {
                "AttributePayload": {},
                "ThingGroups": [
                  {
                    "Ref": "ThingGroupName"
                  }
                ],
                "ThingName": {
                  "Ref": "ThingName"
                }
              },
              "Type": "AWS::IoT::Thing"
            },
            "GGDefaultPolicy": {
              "Properties": {
                "PolicyName": "${GGDeviceDefaultPolicyName}"
              },
              "Type": "AWS::IoT::Policy"
            },
            "GGCertificate": {
              "Properties": {
                "CertificateId": {
                  "Ref": "AWS::IoT::Certificate::Id"
                },
                "Status": "Active"
              },
              "Type": "AWS::IoT::Certificate"
            }
          }
        }

  GGProvisioningClaimPolicy:
    Type: AWS::IoT::Policy
    Properties:
      PolicyName: !Ref GGProvisioningClaimPolicyName
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
            - 'iot:Connect'
          Resource: '*'
        - Effect: Allow
          Action:
            - 'iot:Publish'
            - 'iot:Receive'
          Resource: 
            - !Sub 'arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/$aws/certificates/create/*'
            - !Sub 'arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/$aws/provisioning-templates/${ProvisioningTemplateName}/provision/*'
        - Effect: Allow
          Action:
            - 'iot:Subscribe'
          Resource:
            - !Sub 'arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topicfilter/$aws/certificates/create/*'
            - !Sub 'arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topicfilter/$aws/provisioning-templates/${ProvisioningTemplateName}/provision/*'

Outputs:

  GGTokenExchangeRole:
    Description: Name of token exchange role.
    Value: !Ref GGTokenExchangeRole
  GGTokenExchangeRoleAlias:
    Description: Name of token exchange role alias.
    Value: !Ref GGTokenExchangeRoleAlias
  GGFleetProvisionTemplate:
    Description: Name of Fleet provisioning template.
    Value: !Ref GGFleetProvisionTemplate
  GGProvisioningClaimPolicy:
     Description: Name of claim certificate IoT policy.
     Value: !Ref GGProvisioningClaimPolicy
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فایل را ذخیره کنید و پشته CloudFormation را از template.yaml ایجاد کنید:

aws cloudformation create-stack --stack-name GGFleetProvisoning --template-body [file://template.yaml](file://template.yaml/) —capabilities CAPABILITY_NAMED_IAM
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

چند دقیقه صبر کنید تا منابع ایجاد شود. می توانید وضعیت را از کنسول CloudFormation یا با دستور زیر بررسی کنید:

aws cloudformation describe-stacks —stack-name GGFleetProvisoning
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

گواهی ادعا ایجاد کنید

اینها را در تصویر کارت SD RPi خود جاسازی می کنیم و برای تهیه دستگاه های خود استفاده می کنیم.

mkdir claim-certs

export CERTIFICATE_ARN=$(aws iot create-keys-and-certificate \
    --certificate-pem-outfile "claim-certs/claim.cert.pem" \
    --public-key-outfile "claim-certs/claim.pubkey.pem" \
    --private-key-outfile "claim-certs/claim.pkey.pem" \
    --set-as-active \
    --query certificateArn)

curl -o "claim-certs/claim.root.pem" https://www.amazontrust.com/repository/AmazonRootCA1.pem

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خط مشی AWS IoT را به گواهی ادعای تدارکات پیوست کنید

همانطور که سیاست اینترنت اشیا را به نام ایجاد کردیم GGProvisioningClaimPolicy با CloudFormation فقط می توانیم از نام برای پیوست کردن خط مشی استفاده کنیم:

aws iot attach-policy —policy-name GGProvisioningClaimPolicy —target ${CERTIFICATE_ARN//\"}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

یک گروه چیز ایجاد کنید

هنگامی که دستگاه‌های ما تهیه می‌شوند، بخشی از این گروه چیز خواهند شد و به ما اجازه می‌دهند بعداً استقرار ناوگان Thing Group را هدف قرار دهیم.

aws iot create-thing-group —thing-group-name EmbeddedLinuxFleet
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر ما باید خوب برویم و تصویر RPI خود را بسازیم.

ساختن تصویر RPi

ساخت یک تصویر Yocto برای Raspberry Pi به چندین مرحله نیاز دارد، از جمله راه اندازی محیط ساخت، شبیه سازی مخازن لازم، پیکربندی ساخت و در نهایت ساختن خود تصویر. در اینجا یک راهنمای گام به گام برای کمک به شما در این فرآیند آورده شده است:

یک پنجره ترمینال در ایستگاه کاری خود باز کنید که همه پیش نیازها را بر اساس سند ساخت پروژه Yocto دارد.

توجه به خاطر این آموزش، متغیر BASE به دایرکتوری والد محیط ساخت اشاره دارد. در اینجا، این تنظیم خواهد شد $HOME. اگر از پارتیشن دیگری به عنوان دایرکتوری پایه استفاده می کنید، لطفاً آن را مطابق با آن تنظیم کنید.

export BASEDIR=$(pwd)
export DIST=poky-rpi4
export B=kirkstone
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

لایه پایه Poky را شبیه سازی کنید تا شامل OpenEmbedded Core، Bitbake و غیره باشد تا محیط ساخت Yocto را بسازید.

git clone -b $B git://git.yoctoproject.org/poky.git $BASEDIR/$DIST
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مخازن وابسته اضافی را شبیه سازی کنید. توجه داشته باشید که ما فقط آنچه را که برای AWS IoT Greengrass لازم است شبیه سازی می کنیم.

git clone -b $B git://git.openembedded.org/meta-openembedded \
    $BASEDIR/$DIST/meta-openembedded
git clone -b $B git://git.yoctoproject.org/meta-raspberrypi \
    $BASEDIR/$DIST/meta-raspberrypi
git clone -b $B git://git.yoctoproject.org/meta-virtualization \
    $BASEDIR/$DIST/meta-virtualization
git clone -b $B git://git.yoctoproject.org/meta-java \
    $BASEDIR/$DIST/meta-java
git clone -b $B git://github.com/aws/meta-aws \
    $BASEDIR/$DIST/meta-aws
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

منبع اسکریپت محیط Yocto. این دانه build/conf فهرست راهنما.

cd $BASEDIR/$DIST
. ./oe-init-build-env
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

لایه های لازم را به آن اضافه کنید bblayers.conf استفاده كردن bitbake-layer add-layer:

bitbake-layers add-layer ../meta-openembedded/meta-oe
bitbake-layers add-layer ../meta-openembedded/meta-python
bitbake-layers add-layer ../meta-openembedded/meta-filesystems
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-virtualization
bitbake-layers add-layer ../meta-raspberrypi
bitbake-layers add-layer ../meta-java
bitbake-layers add-layer ../meta-aws
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

را پیکربندی کنید local.conf:

در اینجا ذکر این نکته مهم است که جدا از پیکربندی استاندارد رزبری پای:

MACHINE ?= "raspberrypi4-64"

DISABLE_VC4GRAPHICS = "1"

# Parallelism Options
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"

# Additional image features
USER_CLASSES ?= "buildstats"

# By default disable interactive patch resolution (tasks will just fail instead):
PATCHRESOLVE = "noop"

# Disk Space Monitoring during the build
BB_DISKMON_DIRS = "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    HALT,${TMPDIR},100M,1K \
    HALT,${DL_DIR},100M,1K \
    HALT,${SSTATE_DIR},100M,1K"

CONF_VERSION = "2"

DISTRO_FEATURES += "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_init_manager = "systemd"
VIRTUAL-RUNTIME_initscripts = ""
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما باید روی قسمت پیکربندی Greengrass FleetProvisioning تمرکز کنیم که باید به شکل زیر باشد:


IMAGE_INSTALL:append = " greengrass-bin "
GGV2_DATA_EP     = "xxx-ats.iot.<your aws region>.amazonaws.com"
GGV2_CRED_EP     = "xxx.iot.<your aws region>.amazonaws.com"
GGV2_REGION      = "<your aws region>"
GGV2_THING_NAME  = "ELThing"
GGV2_TES_RALIAS  = "GGTokenExchangeRoleAlias" # we got this from the cloudformation
GGV2_THING_GROUP = "EmbeddedLinuxFleet"

PACKAGECONFIG:pn-greengrass-bin = "fleetprovisioning"
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا ذکر این نکته ضروری است که ما در حال اضافه کردن هستیم greengrass-bin به تصویر ما و سپس ارائه تنظیمات اضافی مورد نیاز توسط config.yaml و همچنین اضافه کردن PACKAGECONFIG:pn-greengrass-bin = "fleetprovisioning" به منظور فعال کردن عملکرد

برای به دست آوردن منطقه AWS و نقاط پایانی اینترنت اشیا، می توانیم موارد زیر را انجام دهیم:

echo "GGV2_REGION="$(aws configure get region)
echo "GGV2_DATA_EP="$(aws --output text iot describe-endpoint \
    --endpoint-type iot:Data-ATS \
    --query 'endpointAddress')
echo "GGV2_CRED_EP="$(aws --output text iot describe-endpoint \
    --endpoint-type iot:CredentialProvider \
    --query 'endpointAddress')
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

لطفاً توجه داشته باشید که ما به یک Thing Name منحصر به فرد نیاز داریم که برای هر دستگاه تولید شود، بنابراین در اینجا نام Thing به عنوان پیشوند گرفته می شود و یک اسکریپت در داخل یک وجود دارد. greengreass-bin دستوری که با استفاده از آدرس MAC، شناسه منحصر به فرد دستگاه را به نام چیز اضافه می کند.

#!/bin/sh
file_path="$1"
default_iface=$(busybox route | grep default | awk '{print $8}')
mac_address=$(busybox ifconfig "$default_iface" | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' | tr ':' '_')
sed -i "s/<unique>/$mac_address/g" "$file_path"
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

meta-aws
└── recipes-iot
    └── aws-iot-greengrass
        └──files
            └── replace_board_id.sh
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به راحتی می توانید این فایل را با هر روش دیگری برای به دست آوردن منحصر به فرد بودن مانند شماره سریال یا موارد مشابه جایگزین کنید

در نهایت باید اعتبار ادعای خود را که در ابتدا ایجاد کرده بودیم کپی کنیم تا در ساخت ما گنجانده شود:

cp  "claim-certs/claim.cert.pem" \
    "claim-certs/claim.pkey.pem" \
    "claim-certs/claim.root.pem" \
    meta-aws/recipes-iot/aws-iot-greengrass/files/
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

لطفاً مسیرها را بر اساس محل گواهی‌های تولید شده و دستور غذا تنظیم کنید.

پس از همه اینها باید به ساختن تصویر خود ادامه دهیم.

bitbake core-image-minimal
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⌛ چند ساعت بعد ⌛ ساخت باید کامل شود و می‌توانیم تصویر حاصل را در فهرست زیر پیدا کنیم:

ls tmp/deploy/images/raspberrypi4-64/*sdimg
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای فلش کردن تصویر روی کارت SD، از ابزاری مانند ‘dd’ استفاده کنید.

sudo dd if=tmp/deploy/images/raspberrypi4-64/core-image-minimal-raspberrypi4-64.sdimg of=/dev/sdX bs=4M
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

جایی که باید مطمئن شویم که “/dev/sdX” را با شناسه دستگاه مناسب برای کارت SD جایگزین کنیم.

⚠️ لطفاً شناسه کارت SD را دوباره بررسی کنید زیرا یک اشتباه در اینجا می تواند سیستم ایستگاه کاری شما را پاک کند

روشن کردن دستگاه برای اولین بار

هنگامی که کارت SD با برق و اینترنت متصل به رزبری پای دوباره وارد شد، دستگاه باید آماده سازی را انجام دهد و در لیست دستگاه های هسته گرین گراس ظاهر شود.

aws greengrassv2 list-core-devices

{
    "coreDevices": [
        {
            "coreDeviceThingName": "ELThing_11_22_33_44_55_60",
            "status": "HEALTHY",
            "lastStatusUpdateTimestamp": "2023-04-25T15:39:00.703000+00:00"
        },
       {
            "coreDeviceThingName": "ELThing_11_22_33_44_55_61",
            "status": "HEALTHY",
            "lastStatusUpdateTimestamp": "2023-03-31T03:11:17.911000+00:00"
        },
       {
            "coreDeviceThingName": "ELThing_11_22_33_44_55_62",
            "status": "HEALTHY",
            "lastStatusUpdateTimestamp": "2023-02-25T15:17:29.505000+00:00"
        },        
    ]
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

موفقیت!

نتیجه

به طور خلاصه، مدیریت ناوگان بزرگی از دستگاه‌های لینوکس تعبیه‌شده می‌تواند یک کار پیچیده و چالش برانگیز باشد، به‌ویژه زمانی که صحبت از ایجاد یک تصویر واحد است که می‌تواند بر روی چندین دستگاه فلش شود. با این حال، AWS IoT Greengrass با Fleet Provisioning می تواند این فرآیند را ساده کرده و کارآمدتر و قابل اعتمادتر کند. در این پست وبلاگ، پیش نیازهای راه اندازی AWS IoT Greengrass و Fleet Provisioning، از جمله ایجاد خط مشی ها، دریافت گواهی ادعا و پیکربندی ساخت تصویر Yocto را مورد بحث قرار داده ایم. ما همچنین یک راهنمای گام به گام برای ساخت تصویر Yocto برای Raspberry Pi با پیکربندی Greengrass Fleet Provisioning ارائه کرده ایم. با استفاده از AWS IoT Greengrass – Fleet Provisioning، مدیریت ناوگان بزرگی از دستگاه های تعبیه شده را می توان آسان تر، کارآمدتر و ایمن تر کرد.

اگر بازخوردی در مورد این پست دارید یا می‌خواهید مطالب مرتبط بیشتری را ببینید، لطفاً در اینجا یا در اینجا با من تماس بگیرید توییتر یا لینکدین

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا