我們開始把之前文章中所描述的FRC各項元件,建置repo在gitlab上,並使用Jenkins的webhook功能去trigger其部署流程。
Jenkins設定如下:
流程包含Build docker image & Uploade image to ECR(AWS container registry)
最後用以下指令部署在EKS上
kubectl set image -f manifests/deploy/thing-deploy.yaml ${IMAGE_NAME}=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE_NAME}:latest --local -o yaml | kubectl apply -f -
Deploy內容包含,前端FRC control panel & Scene Builder,後端API,Unity ENV Creator,virtual things(IoT Bridge & Unity),greengrass(local server)。
當virtual things部署完成,IoT Bridge(app code的內容請參考本系列之前文章)會自動在AWS IoT Core上create things
EKS的logs訊息如下
從AWS IoT的MQTT test client可以收到來virtual thing送過來的訊息
補上Jenkins trigger greengrass component deploy的script的部份。其中要注意的是,這裡設定要trigger deployment的device node(vm),就是要進行連結到Greengrass的local server(stage "AWS IoT Greengrass setting" 的步驟)。
pipeline {
agent {
label "${device_node}"
}
environment {
GITLAB_API_TOKEN = credentials('gitlab-token')
}
stages {
stage('Build Image') {
steps {
withAWS(credentials:'aws-admin-credentials') {
sh "rm -r -f ${image_name}"
sh "git clone -b ${BRANCH_NAME} https://${GITLAB_API_TOKEN}@gitlab.com/paia-digital-twin/${image_name}.git"
sh "cd ${image_name} && git pull origin ${BRANCH_NAME}"
script {
docker_compose_path = "/usr/bin/docker-compose"
if (fileExists(docker_compose_path) == false) {
sh "curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-\$(uname -s)-\$(uname -m)\" -o $docker_compose_path"
sh "chmod +x $docker_compose_path"
}
}
sh "cd ${image_name} && sed -i 's/\$ECR_COMPONENT/'${image_name}'/g' docker-compose.yaml"
sh "cd ${image_name} && sed -i 's/\$VERSION/'${version}'/g' docker-compose.yaml"
sh "cd ${image_name} && sed -i 's/\$THING_NAME/'${image_name}'/g' docker-compose.yaml"
sh "cd ${image_name} && COMPOSE_DOCKER_CLI_BUILD=1 docker-compose build"
}
}
}
stage('Push Image') {
steps{
script {
docker.withRegistry("https://${registry}", registryCredential ) {
sh("docker tag ${image_name}:${version} ${registry}/${image_name}:${version}")
dockerImage = docker.image("${registry}/${image_name}:${version}")
dockerImage.push()
}
}
}
}
stage('Upload docker compose yaml'){
steps{
withAWS(credentials:'aws-admin-credentials') {
script {
aws_cli_path = "/usr/local/bin/aws"
if (fileExists(aws_cli_path) == false) {
sh 'curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"'
sh 'unzip -o awscliv2.zip'
sh './aws/install --update'
}
sh "cd ${image_name} && aws s3 cp ./docker-compose.yaml s3://${AWS_S3_PATH}/${image_name}/${version}/artifacts/docker-compose.yaml"
}
}
}
}
stage('AWS IoT Greengrass setting'){
steps{
withAWS(credentials:'aws-admin-credentials') {
script {
sh "cd ${image_name} && curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip && unzip greengrass-nucleus-latest.zip -d GreengrassCore"
sh "cd ${image_name} && sudo -E java -Droot=\"/greengrass/v2\" -Dlog.store=FILE -jar ./GreengrassCore/lib/Greengrass.jar --thing-name $device_node --component-default-user ggc_user:ggc_group --provision true --setup-system-service true --deploy-dev-tools true"
sh "sudo groupadd -f docker"
sh "sudo usermod -aG docker ggc_user"
}
}
}
}
}
}
然後再用以下指令去控制greengrass做對地端的自動部署。
sed -i 's/$VERSION/'"$VERSION"'/g' ./greengrass/recipe.json
sed -i 's/$ECR_COMPONENT/'"$ECR_COMPONENT"'/g' ./greengrass/recipe.json
sed -i 's/$AWS_ACCOUNT_ID/'"$AWS_ACCOUNT_ID"'/g' ./greengrass/recipe.json
sed -i 's/$AWS_REGION/'"$AWS_REGION"'/g' ./greengrass/recipe.json
sed -i 's/$AWS_S3_PATH/'"$AWS_S3_PATH"'/g' ./greengrass/recipe.json
aws greengrassv2 create-component-version --region $AWS_REGION --inline-recipe fileb://greengrass/recipe.json
sed -i 's/$VERSION/'"$VERSION"'/g' ./deployment.json
sed -i 's/$ECR_COMPONENT/'"$ECR_COMPONENT"'/g' ./deployment.json
sed -i 's/$THING_NAME/'"$THING_NAME"'/g' ./deployment.json
sed -i 's/$AWS_ACCOUNT_ID/'"$AWS_ACCOUNT_ID"'/g' ./deployment.json
sed -i 's/$AWS_REGION/'"$AWS_REGION"'/g' ./deployment.json
aws greengrassv2 create-deployment --region $AWS_REGION --cli-input-json fileb://greengrass/deployment.json
這裡用大量sed的語法去取代變數,是為了方便在jenkins中寫pipeline script去客製化控制流程。