تامین ناوگان برای دستگاه های لینوکس جاسازی شده با 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 یافت.
به طور خلاصه، ما نیاز داریم:
- نقش IAM تبادل توکن، که دستگاههای اصلی برای مجاز کردن تماسها به سرویسهای AWS و نقش مستعار نقش AWS IoT که به نقش تبادل توکن اشاره میکند، استفاده میکنند.
- یک الگوی تامین ناوگان AWS IoT. الگو باید اطلاعات مورد نیاز برای ایجاد چیز و خط مشی را مشخص کند که به دستگاه هسته سبز گراس ایجاد شده متصل می شود. میتوانید از نام خطمشی اینترنت اشیا موجود استفاده کنید یا خطمشی را روی الگو تعریف کنید.
- یک گواهی ادعای تامین اینترنت اشیاء 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، مدیریت ناوگان بزرگی از دستگاه های تعبیه شده را می توان آسان تر، کارآمدتر و ایمن تر کرد.
اگر بازخوردی در مورد این پست دارید یا میخواهید مطالب مرتبط بیشتری را ببینید، لطفاً در اینجا یا در اینجا با من تماس بگیرید توییتر یا لینکدین