diff --git a/.pipelines/azure_pipeline_dev.yaml b/.pipelines/azure_pipeline_dev.yaml new file mode 100644 index 000000000..6d50e5788 --- /dev/null +++ b/.pipelines/azure_pipeline_dev.yaml @@ -0,0 +1,100 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: +- ci_dev + +pool: + name: Azure-Pipelines-CI-Test-EO + +variables: + armServiceConnectionName: 'ci-1es-acr-connection' + subscription: '9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb' + containerRegistry: 'containerinsightsprod' + repoImageName: '${{ variables.containerRegistry }}.azurecr.io/public/azuremonitor/containerinsights/cidev' + +steps: +- bash: | + commit=$(git rev-parse --short HEAD) + echo "##vso[task.setvariable variable=commit;]$commit" + + datetime=$(date +'%Y%m%d%s') + echo "##vso[task.setvariable variable=datetime;]$datetime" + + cd deployment/multiarch-agent-deployment/ServiceGroupRoot/Scripts + tar -czvf ../artifacts.tar.gz pushAgentToAcr.sh + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment artifacts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/deployment" + Contents: | + **/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/.pipelines" + Contents: | + *.sh + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/kubernetes" + Contents: | + *.yaml + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/charts" + Contents: | + **/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/test/e2e" + Contents: | + *.yaml + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: AzureCLI@2 + inputs: + azureSubscription: ${{ variables.armServiceConnectionName }} + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + + sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + docker buildx create --name testbuilder + docker buildx use testbuilder + + az --version + az account show + az account set -s ${{ variables.subscription }} + az acr login -n ${{ variables.containerRegistry }} + + docker buildx build --platform linux/amd64,linux/arm64 --tag ${{ variables.repoImageName }}:$(datetime)-$(commit) -f kubernetes/linux/Dockerfile.multiarch --metadata-file $(Build.ArtifactStagingDirectory)/metadata.json --build-arg IMAGE_TAG=$(datetime)-$(commit) --push . + + docker pull ${{ variables.repoImageName }}:$(datetime)-$(commit) + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generation Task' + inputs: + BuildDropPath: '$(Build.ArtifactStagingDirectory)' + DockerImagesToScan: 'golang:1.14, ubuntu:18.04, ${{ variables.repoImageName }}:$(datetime)-$(commit)' + +- task: PublishBuildArtifacts@1 + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: drop diff --git a/.pipelines/azure_pipeline_prod.yaml b/.pipelines/azure_pipeline_prod.yaml new file mode 100644 index 000000000..046d41910 --- /dev/null +++ b/.pipelines/azure_pipeline_prod.yaml @@ -0,0 +1,100 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: +- ci_prod + +pool: + name: Azure-Pipelines-CI-Prod-EO + +variables: + armServiceConnectionName: 'ci-1es-acr-connection-prod' + subscription: '30c56c3a-54da-46ea-b004-06eb33432687' + containerRegistry: 'containerinsightsbuild' + repoImageName: '${{ variables.containerRegistry }}.azurecr.io/official/linux' + +steps: +- bash: | + commit=$(git rev-parse --short HEAD) + echo "##vso[task.setvariable variable=commit;]$commit" + + datetime=$(date +'%Y%m%d%s') + echo "##vso[task.setvariable variable=datetime;]$datetime" + + cd deployment/multiarch-agent-deployment/ServiceGroupRoot/Scripts + tar -czvf ../artifacts.tar.gz pushAgentToAcr.sh + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment artifacts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/deployment" + Contents: | + **/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/.pipelines" + Contents: | + **/*.sh + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/kubernetes" + Contents: | + *.yaml + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/charts" + Contents: | + **/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: CopyFiles@2 + displayName: "Copy ev2 deployment scripts" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/test/e2e" + Contents: | + *.yaml + TargetFolder: '$(Build.ArtifactStagingDirectory)/build' + +- task: AzureCLI@2 + inputs: + azureSubscription: ${{ variables.armServiceConnectionName }} + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + + sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + docker buildx create --name testbuilder + docker buildx use testbuilder + + az --version + az account show + az account set -s ${{ variables.subscription }} + az acr login -n ${{ variables.containerRegistry }} + + docker buildx build --platform linux/amd64,linux/arm64 --tag ${{ variables.repoImageName }}:ciprod-$(datetime)-$(commit) -f kubernetes/linux/Dockerfile.multiarch --metadata-file $(Build.ArtifactStagingDirectory)/metadata.json --build-arg IMAGE_TAG=ciprod-$(datetime)-$(commit) --push . + + docker pull ${{ variables.repoImageName }}:ciprod-$(datetime)-$(commit) + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generation Task' + inputs: + BuildDropPath: '$(Build.ArtifactStagingDirectory)' + DockerImagesToScan: 'golang:1.14, ubuntu:18.04, ${{ variables.repoImageName }}:ciprod-$(datetime)-$(commit)' + +- task: PublishBuildArtifacts@1 + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: drop \ No newline at end of file diff --git a/README.md b/README.md index 7d42c75d6..f0fa40e53 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,25 @@ bash build-and-publish-docker-image.sh --image /: ``` > Note: format of the imagetag will be `ci`. possible values for release are test, dev, preview, dogfood, prod etc. +You can also build and push images for multiple architectures. This is powered by docker buildx +``` +cd ~/Docker-Provider/kubernetes/linux/dockerbuild +sudo docker login # if you want to publish the image to acr then login to acr via `docker login ` +# build and publish using docker buildx +bash build-and-publish-docker-image.sh --image /: --multiarch +``` + +or directly use the docker buildx commands +``` +# multiple platforms +cd ~/Docker-Provider +docker buildx build --platform linux/arm64/v8,linux/amd64 -t /: --build-arg IMAGE_TAG= -f kubernetes/linux/Dockerfile.multiarch --push . + +# single platform +cd ~/Docker-Provider +docker buildx build --platform linux/amd64 -t /: --build-arg IMAGE_TAG= -f kubernetes/linux/Dockerfile.multiarch --push . +``` + If you prefer to build docker provider shell bundle and image separately, then you can follow below instructions ##### Build Docker Provider shell bundle diff --git a/build/linux/Makefile b/build/linux/Makefile index 3f35e1204..9203f1d73 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -11,10 +11,16 @@ BUILD_TYPE=Release PF=Linux PF_MAJOR=1 PF_MINOR=0 -PF_ARCH=x64 PF_WIDTH=64 PF_DISTRO=ULINUX -BUILD_CONFIGURATION=Linux_ULINUX_1.0_x64_64_Release + +ifeq ($(arch),) + PF_ARCH=amd64 +else + PF_ARCH=$(arch) +endif + +BUILD_CONFIGURATION=Linux_ULINUX_1.0_$(PF_ARCH)_64_Release # RM - Remove a file # RMDIR - Remove a directory @@ -90,16 +96,7 @@ endif STAGING_DIR := $(INTERMEDIATE_DIR)/staging -# For consistency, the architecture should be i686 (for x86) and x86_64 (for x64) -DOCKER_ARCH := $(shell echo $(PF_ARCH) | sed -e 's/x86$$/i686/' -e 's/x64$$/x86_64/') -OUTPUT_PACKAGE_PREFIX=docker-cimprov-$(CONTAINER_BUILDVERSION_MAJOR).$(CONTAINER_BUILDVERSION_MINOR).$(CONTAINER_BUILDVERSION_PATCH)-$(CONTAINER_BUILDVERSION_BUILDNR).universal.$(DOCKER_ARCH) - - -ifeq ("$(wildcard /usr/bin/dpkg-deb)","") - DPKG_LOCATION="--DPKG_LOCATION=$(BASE_DIR)/build/linux/installer/InstallBuilder/tools/bin/dpkg-deb-$(PF_ARCH)" -else - DPKG_LOCATION= -endif +OUTPUT_PACKAGE_PREFIX=docker-cimprov-$(CONTAINER_BUILDVERSION_MAJOR).$(CONTAINER_BUILDVERSION_MINOR).$(CONTAINER_BUILDVERSION_PATCH)-$(CONTAINER_BUILDVERSION_BUILDNR).universal.$(PF_ARCH) #-------------------------------------------------------------------------------- @@ -130,7 +127,7 @@ KIT_STATUS: fluentbitplugin : @echo "========================= Building fluentbit out_oms go plugin for logs" $(MKPATH) $(INTERMEDIATE_DIR) - make -C $(GO_SOURCE_DIR) fbplugin + make -C $(GO_SOURCE_DIR) fbplugin arch=$(PF_ARCH) $(COPY) $(GO_SOURCE_DIR)/out_oms.so $(INTERMEDIATE_DIR) rubypluginstests : @@ -192,7 +189,6 @@ kit : fluentbitplugin --VERSION=$(CONTAINER_BUILDVERSION_MAJOR).$(CONTAINER_BUILDVERSION_MINOR).$(CONTAINER_BUILDVERSION_PATCH) \ --RELEASE=$(CONTAINER_BUILDVERSION_BUILDNR) \ --CONTAINER_BUILD_LIBRARY=$(CONTAINERLIB_FILENAME) \ - $(DPKG_LOCATION) \ --OUTPUTFILE=$(OUTPUT_PACKAGE_PREFIX) \ --DATAFILE_PATH=$(BASE_DIR)/build/linux/installer/datafiles \ base_container.data linux.data linux_dpkg.data diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/Parameters/ContainerInsights.Linux.Parameters.json b/deployment/multiarch-agent-deployment/ServiceGroupRoot/Parameters/ContainerInsights.Linux.Parameters.json new file mode 100644 index 000000000..70d0950a2 --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/Parameters/ContainerInsights.Linux.Parameters.json @@ -0,0 +1,68 @@ +{ + "$schema": "http://schema.express.azure.com/schemas/2015-01-01-alpha/RolloutParameters.json", + "contentVersion": "1.0.0.0", + "wait": [ + { + "name": "waitSdpBakeTime", + "properties": { + "duration": "PT24H" + } + } + ], + "shellExtensions": [ + { + "name": "PushAgentToACR", + "type": "ShellExtensionType", + "properties": { + "maxexecutiontime": "PT1H" + }, + "package": { + "reference": { + "path": "artifacts.tar.gz" + } + }, + "launch": { + "command": [ + "/bin/bash", + "pushAgentToAcr.sh" + ], + "environmentVariables": [ + { + "name": "ACR_NAME", + "value": "__ACR_NAME__" + }, + { + "name": "AGENT_RELEASE", + "value": "__AGENT_RELEASE__" + }, + { + "name": "AGENT_IMAGE_TAG_SUFFIX", + "value": "__AGENT_IMAGE_TAG_SUFFIX__" + }, + { + "name": "AGENT_IMAGE_FULL_PATH", + "value": "public/azuremonitor/containerinsights/__AGENT_RELEASE__:__AGENT_RELEASE____AGENT_IMAGE_TAG_SUFFIX__" + }, + { + "name": "CDPX_REGISTRY", + "value": "__CDPX_LINUX_REGISTRY__" + }, + { + "name": "CDPX_REPO_NAME", + "value": "__CDPX_LINUX_REPO_NAME__" + }, + { + "name": "CDPX_TAG", + "value": "__CDPX_LINUX_TAG__" + } + ], + "identity": { + "type": "userAssigned", + "userAssignedIdentities": [ + "__MANAGED_IDENTITY__" + ] + } + } + } + ] + } \ No newline at end of file diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/RolloutSpecs/RolloutSpecs.json b/deployment/multiarch-agent-deployment/ServiceGroupRoot/RolloutSpecs/RolloutSpecs.json new file mode 100644 index 000000000..250878590 --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/RolloutSpecs/RolloutSpecs.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/rolloutSpecification.json", + "ContentVersion": "1.0.0.0", + "RolloutMetadata": { + "ServiceModelPath": "ServiceModels//Public.ServiceModel.json", + "ScopeBindingsPath": "ScopeBindings//Public.ScopeBindings.json", + "Name": "ContainerInsightsAgent", + "RolloutType": "Major", + "BuildSource": { + "Parameters": { + "VersionFile": "buildver.txt" + } + }, + "Notification": { + "Email": { + "To": "omscontainers@microsoft.com" + } + } + }, + "OrchestratedSteps": [ + { + "name": "PushLinuxAgent", + "targetType": "ServiceResource", + "targetName": "PushLinuxAgent", + "actions": [ "Shell/PushAgentToACR" ], + "dependsOn": [ ] + } + ] + } \ No newline at end of file diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/ScopeBindings/Public.ScopeBindings.json b/deployment/multiarch-agent-deployment/ServiceGroupRoot/ScopeBindings/Public.ScopeBindings.json new file mode 100644 index 000000000..cbc6db8b3 --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/ScopeBindings/Public.ScopeBindings.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/scopeBindings.json", + "contentVersion": "0.0.0.1", + "scopeBindings": [ + { + "scopeTagName": "Global", + "bindings": [ + { + "find": "__ACR_NAME__", + "replaceWith": "$(ACRName)" + }, + { + "find": "__AGENT_RELEASE__", + "replaceWith": "$(AgentRelease)" + }, + { + "find": "__AGENT_IMAGE_TAG_SUFFIX__", + "replaceWith": "$(AgentImageTagSuffix)" + }, + { + "find": "__MANAGED_IDENTITY__", + "replaceWith": "$(ManagedIdentity)" + }, + { + "find": "__CDPX_LINUX_REGISTRY__", + "replaceWith": "$(CDPXLinuxRegistry)" + }, + { + "find": "__CDPX_WINDOWS_REGISTRY__", + "replaceWith": "$(CDPXWindowsRegistry)" + }, + { + "find": "__CDPX_LINUX_TAG__", + "replaceWith": "$(CDPXLinuxTag)" + }, + { + "find": "__CDPX_WINDOWS_TAG__", + "replaceWith": "$(CDPXWindowsTag)" + }, + { + "find": "__CDPX_LINUX_REPO_NAME__", + "replaceWith": "$(CDPXLinuxRepoName)" + }, + { + "find": "__CDPX_WINDOWS_REPO_NAME__", + "replaceWith": "$(CDPXWindowsRepoName)" + } + ] + } + ] +} \ No newline at end of file diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/Scripts/pushAgentToAcr.sh b/deployment/multiarch-agent-deployment/ServiceGroupRoot/Scripts/pushAgentToAcr.sh new file mode 100644 index 000000000..d39cedde0 --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/Scripts/pushAgentToAcr.sh @@ -0,0 +1,72 @@ +#!/bin/bash +set -e + +# Note - This script used in the pipeline as inline script + +if [ -z $AGENT_IMAGE_TAG_SUFFIX ]; then + echo "-e error value of AGENT_IMAGE_TAG_SUFFIX variable shouldnt be empty. check release variables" + exit 1 +fi + +if [ -z $AGENT_RELEASE ]; then + echo "-e error AGENT_RELEASE shouldnt be empty. check release variables" + exit 1 +fi + +#Make sure that tag being pushed will not overwrite an existing tag in mcr +MCR_TAG_RESULT="`wget -qO- https://mcr.microsoft.com/v2/azuremonitor/containerinsights/ciprod/tags/list`" +if [ $? -ne 0 ]; then + echo "-e error unable to get list of mcr tags for azuremonitor/containerinsights/ciprod repository" + exit 1 +fi +TAG_EXISTS=$(echo $MCR_TAG_RESULT | jq '.tags | contains(["'"$AGENT_RELEASE$AGENT_IMAGE_TAG_SUFFIX"'"])') + +if $TAG_EXISTS; then + echo "-e error ${AGENT_IMAGE_TAG_SUFFIX} already exists in mcr. make sure the image tag is unique" + exit 1 +fi + +if [ -z $AGENT_IMAGE_FULL_PATH ]; then + echo "-e error AGENT_IMAGE_FULL_PATH shouldnt be empty. check release variables" + exit 1 +fi + +if [ -z $CDPX_TAG ]; then + echo "-e error value of CDPX_TAG shouldn't be empty. check release variables" + exit 1 +fi + +if [ -z $CDPX_REGISTRY ]; then + echo "-e error value of CDPX_REGISTRY shouldn't be empty. check release variables" + exit 1 +fi + +if [ -z $CDPX_REPO_NAME ]; then + echo "-e error value of CDPX_REPO_NAME shouldn't be empty. check release variables" + exit 1 +fi + +if [ -z $ACR_NAME ]; then + echo "-e error value of ACR_NAME shouldn't be empty. check release variables" + exit 1 +fi + + +#Login to az cli and authenticate to acr +echo "Login cli using managed identity" +az login --identity +if [ $? -eq 0 ]; then + echo "Logged in successfully" +else + echo "-e error failed to login to az with managed identity credentials" + exit 1 +fi + +echo "Pushing ${AGENT_IMAGE_FULL_PATH} to ${ACR_NAME}" +az acr import --name $ACR_NAME --registry $CDPX_REGISTRY --source official/${CDPX_REPO_NAME}:${CDPX_TAG} --image $AGENT_IMAGE_FULL_PATH +if [ $? -eq 0 ]; then + echo "Retagged and pushed image successfully" +else + echo "-e error failed to retag and push image to destination ACR" + exit 1 +fi \ No newline at end of file diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/ServiceModels/Public.ServiceModel.json b/deployment/multiarch-agent-deployment/ServiceGroupRoot/ServiceModels/Public.ServiceModel.json new file mode 100644 index 000000000..c3b00340a --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/ServiceModels/Public.ServiceModel.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/serviceModel.json", + "contentVersion": "1.0.0.2", + "ServiceMetadata": { + "ServiceGroup": "ContainerInsightsAgent", + "Environment": "Prod" + }, + "ServiceResourceGroupDefinitions": [ + { + "Name": "CI-Agent-ServiceResourceGroupDefinition", + "ServiceResourceDefinitions": [ + { + "Name": "ShellExtension", + "ComposedOf": { + "Extension": { + "Shell": [ + { + "type": "ShellExtensionType", + "properties": { + "imageName": "adm-ubuntu-1804-l", + "imageVersion": "v18" + } + } + ] + } + } + } + ] + } + ], + "ServiceResourceGroups": [ + { + "AzureResourceGroupName": "ContainerInsights-MultiArch-Agent-Release", + "Location": "eastus2", + "InstanceOf": "CI-Agent-ServiceResourceGroupDefinition", + "AzureSubscriptionId": "30c56c3a-54da-46ea-b004-06eb33432687", + "ScopeTags": [ + { + "Name": "Global" + } + ], + "ServiceResources": [ + { + "Name": "PushLinuxAgent", + "InstanceOf": "ShellExtension", + "RolloutParametersPath": "Parameters\\ContainerInsights.Linux.Parameters.json" + } + ] + } + ] + } \ No newline at end of file diff --git a/deployment/multiarch-agent-deployment/ServiceGroupRoot/buildver.txt b/deployment/multiarch-agent-deployment/ServiceGroupRoot/buildver.txt new file mode 100644 index 000000000..bd2666abb --- /dev/null +++ b/deployment/multiarch-agent-deployment/ServiceGroupRoot/buildver.txt @@ -0,0 +1 @@ +1.0.0.0 \ No newline at end of file diff --git a/kubernetes/linux/Dockerfile b/kubernetes/linux/Dockerfile index 2128d6d6a..bace8d45e 100644 --- a/kubernetes/linux/Dockerfile +++ b/kubernetes/linux/Dockerfile @@ -23,7 +23,7 @@ ENV AGENT_VERSION ${IMAGE_TAG} WORKDIR ${tmpdir} # copy docker provider shell bundle to use the agent image -COPY ./Linux_ULINUX_1.0_x64_64_Release/docker-cimprov-*.*.*-*.x86_64.sh . +COPY ./Linux_ULINUX_1.0_*_64_Release/docker-cimprov-*.*.*-*.*.*.sh . # Note: If you prefer remote destination, uncomment below line and comment above line # wget https://github.com/microsoft/Docker-Provider/releases/download/10.0.0-1/docker-cimprov-10.0.0-1.universal.x86_64.sh diff --git a/kubernetes/linux/Dockerfile.multiarch b/kubernetes/linux/Dockerfile.multiarch new file mode 100644 index 000000000..6ac8c6507 --- /dev/null +++ b/kubernetes/linux/Dockerfile.multiarch @@ -0,0 +1,39 @@ +FROM --platform=$BUILDPLATFORM golang:1.15 AS builder +ARG TARGETOS TARGETARCH +RUN /usr/bin/apt-get update && /usr/bin/apt-get install git g++ make pkg-config libssl-dev libpam0g-dev rpm librpm-dev uuid-dev libkrb5-dev python sudo gcc-aarch64-linux-gnu -y + +COPY build /src/build +COPY source /src/source +RUN cd /src/build/linux && make arch=${TARGETARCH} + + +FROM ubuntu:18.04 AS base_image +ARG TARGETOS TARGETARCH +MAINTAINER OMSContainers@microsoft.com +LABEL vendor=Microsoft\ Corp \ + com.microsoft.product="Azure Monitor for containers" +ENV tmpdir /opt +ENV APPLICATIONINSIGHTS_AUTH NzAwZGM5OGYtYTdhZC00NThkLWI5NWMtMjA3ZjM3NmM3YmRi +ENV MALLOC_ARENA_MAX 2 +ENV HOST_MOUNT_PREFIX /hostfs +ENV HOST_PROC /hostfs/proc +ENV HOST_SYS /hostfs/sys +ENV HOST_ETC /hostfs/etc +ENV HOST_VAR /hostfs/var +ENV AZMON_COLLECT_ENV False +ENV KUBE_CLIENT_BACKOFF_BASE 1 +ENV KUBE_CLIENT_BACKOFF_DURATION 0 +ENV RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR 0.9 +RUN /usr/bin/apt-get update && /usr/bin/apt-get install -y libc-bin wget openssl curl sudo python python-ctypes init-system-helpers net-tools rsyslog cron vim dmidecode apt-transport-https gnupg make && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /src/kubernetes/linux/Linux_ULINUX_1.0_*_64_Release/docker-cimprov-*.*.*-*.*.sh $tmpdir/ +COPY kubernetes/linux/setup.sh kubernetes/linux/main.sh kubernetes/linux/defaultpromenvvariables kubernetes/linux/defaultpromenvvariables-rs kubernetes/linux/defaultpromenvvariables-sidecar kubernetes/linux/mdsd.xml kubernetes/linux/envmdsd kubernetes/linux/logrotate.conf $tmpdir/ + +ARG IMAGE_TAG=ciprod03112022 +ENV AGENT_VERSION ${IMAGE_TAG} + +WORKDIR ${tmpdir} + +RUN chmod 775 $tmpdir/*.sh; sync; $tmpdir/setup.sh ${TARGETARCH} +CMD [ "/opt/main.sh" ] + diff --git a/kubernetes/linux/dockerbuild/build-and-publish-docker-image.sh b/kubernetes/linux/dockerbuild/build-and-publish-docker-image.sh index 267f15f32..580b158c9 100755 --- a/kubernetes/linux/dockerbuild/build-and-publish-docker-image.sh +++ b/kubernetes/linux/dockerbuild/build-and-publish-docker-image.sh @@ -14,6 +14,7 @@ usage() echo echo "Build and publish docker image:" echo "$basename --image " + echo "$basename --image --multiarch" } parse_args() @@ -30,6 +31,7 @@ for arg in "$@"; do shift case "$arg" in "--image") set -- "$@" "-i" ;; + "--multiarch") set -- "$@" "-m" ;; "--"*) usage ;; *) set -- "$@" "$arg" esac @@ -37,7 +39,7 @@ done local OPTIND opt -while getopts 'hi:' opt; do +while getopts 'hi:m' opt; do case "$opt" in h) usage @@ -48,6 +50,11 @@ while getopts 'hi:' opt; do echo "image is $OPTARG" ;; + m) + multi=1 + echo "using multiarch dockerfile" + ;; + ?) usage exit 1 @@ -131,6 +138,13 @@ echo "source code base directory: $baseDir" echo "build directory for docker provider: $buildDir" echo "docker file directory: $dockerFileDir" +if [ "$multi" -eq "1" ]; then + echo "building multiarch" + cd $baseDir + docker buildx build --platform linux/arm64/v8,linux/amd64 -t $image --build-arg IMAGE_TAG=$imageTag -f $linuxDir/Dockerfile.multiarch --push . + exit 0 +fi + # build docker provider shell bundle build_docker_provider diff --git a/kubernetes/linux/main.sh b/kubernetes/linux/main.sh index 4e1b0783c..997f624e2 100644 --- a/kubernetes/linux/main.sh +++ b/kubernetes/linux/main.sh @@ -328,7 +328,7 @@ source ~/.bashrc if [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then #Parse the configmap to set the right environment variables. - /usr/bin/ruby2.6 tomlparser.rb + /usr/bin/ruby2.7 tomlparser.rb cat config_env_var | while read line; do echo $line >> ~/.bashrc @@ -339,7 +339,7 @@ fi #Parse the configmap to set the right environment variables for agent config. #Note > tomlparser-agent-config.rb has to be parsed first before td-agent-bit-conf-customizer.rb for fbit agent settings if [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then - /usr/bin/ruby2.6 tomlparser-agent-config.rb + /usr/bin/ruby2.7 tomlparser-agent-config.rb cat agent_config_env_var | while read line; do #echo $line @@ -348,7 +348,7 @@ if [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then source agent_config_env_var #Parse the configmap to set the right environment variables for network policy manager (npm) integration. - /usr/bin/ruby2.6 tomlparser-npm-config.rb + /usr/bin/ruby2.7 tomlparser-npm-config.rb cat integration_npm_config_env_var | while read line; do #echo $line @@ -359,11 +359,11 @@ fi #Replace the placeholders in td-agent-bit.conf file for fluentbit with custom/default values in daemonset if [ ! -e "/etc/config/kube.conf" ] && [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then - /usr/bin/ruby2.6 td-agent-bit-conf-customizer.rb + /usr/bin/ruby2.7 td-agent-bit-conf-customizer.rb fi #Parse the prometheus configmap to create a file with new custom settings. -/usr/bin/ruby2.6 tomlparser-prom-customconfig.rb +/usr/bin/ruby2.7 tomlparser-prom-customconfig.rb #Setting default environment variables to be used in any case of failure in the above steps if [ ! -e "/etc/config/kube.conf" ]; then @@ -397,7 +397,7 @@ fi if [ ! -e "/etc/config/kube.conf" ]; then if [ "${CONTAINER_TYPE}" == "PrometheusSidecar" ]; then #Parse the agent configmap to create a file with new custom settings. - /usr/bin/ruby2.6 tomlparser-prom-agent-config.rb + /usr/bin/ruby2.7 tomlparser-prom-agent-config.rb #Sourcing config environment variable file if it exists if [ -e "side_car_fbit_config_env_var" ]; then cat side_car_fbit_config_env_var | while read line; do @@ -411,7 +411,7 @@ fi #Parse the configmap to set the right environment variables for MDM metrics configuration for Alerting. if [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then - /usr/bin/ruby2.6 tomlparser-mdm-metrics-config.rb + /usr/bin/ruby2.7 tomlparser-mdm-metrics-config.rb cat config_mdm_metrics_env_var | while read line; do echo $line >> ~/.bashrc @@ -419,7 +419,7 @@ if [ "${CONTAINER_TYPE}" != "PrometheusSidecar" ]; then source config_mdm_metrics_env_var #Parse the configmap to set the right environment variables for metric collection settings - /usr/bin/ruby2.6 tomlparser-metric-collection-config.rb + /usr/bin/ruby2.7 tomlparser-metric-collection-config.rb cat config_metric_collection_env_var | while read line; do echo $line >> ~/.bashrc @@ -430,7 +430,7 @@ fi # OSM scraping to be done in replicaset if sidecar car scraping is disabled and always do the scraping from the sidecar (It will always be either one of the two) if [[ ( ( ! -e "/etc/config/kube.conf" ) && ( "${CONTAINER_TYPE}" == "PrometheusSidecar" ) ) || ( ( -e "/etc/config/kube.conf" ) && ( "${SIDECAR_SCRAPING_ENABLED}" == "false" ) ) ]]; then - /usr/bin/ruby2.6 tomlparser-osm-config.rb + /usr/bin/ruby2.7 tomlparser-osm-config.rb if [ -e "integration_osm_config_env_var" ]; then cat integration_osm_config_env_var | while read line; do @@ -517,7 +517,7 @@ if [ "$CONTAINER_RUNTIME" != "docker" ]; then fi echo "set caps for ruby process to read container env from proc" -sudo setcap cap_sys_ptrace,cap_dac_read_search+ep /usr/bin/ruby2.6 +sudo setcap cap_sys_ptrace,cap_dac_read_search+ep /usr/bin/ruby2.7 echo "export KUBELET_RUNTIME_OPERATIONS_METRIC="$KUBELET_RUNTIME_OPERATIONS_METRIC >> ~/.bashrc echo "export KUBELET_RUNTIME_OPERATIONS_ERRORS_METRIC="$KUBELET_RUNTIME_OPERATIONS_ERRORS_METRIC >> ~/.bashrc diff --git a/kubernetes/linux/setup.sh b/kubernetes/linux/setup.sh index 9d36fec4a..00d5bc0fa 100644 --- a/kubernetes/linux/setup.sh +++ b/kubernetes/linux/setup.sh @@ -1,6 +1,12 @@ TMPDIR="/opt" cd $TMPDIR +if [ -z $1 ]; then + ARCH="amd64" +else + ARCH=$1 +fi + #Download utf-8 encoding capability on the omsagent container. #upgrade apt to latest version apt-get update && apt-get install -y apt && DEBIAN_FRONTEND=noninteractive apt-get install -y locales @@ -9,15 +15,18 @@ sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ dpkg-reconfigure --frontend=noninteractive locales && \ update-locale LANG=en_US.UTF-8 -#install oneagent - Official bits (2/22/2022) -wget https://github.com/microsoft/Docker-Provider/releases/download/1.17.0/azure-mdsd_1.17.0-build.master.354_x86_64.deb - +#install oneagent - Official bits (3/14/2022) +if [ "${ARCH}" != "arm64" ]; then + wget "https://github.com/microsoft/Docker-Provider/releases/download/1.17.0/azure-mdsd_1.17.0-build.master.354_x86_64.deb" -O azure-mdsd.deb +else + wget "https://github.com/microsoft/Docker-Provider/releases/download/1.17.1-arm64-master/azure-mdsd_1.17.1-build.master.366_aarch64.deb" -O azure-mdsd.deb +fi /usr/bin/dpkg -i $TMPDIR/azure-mdsd*.deb cp -f $TMPDIR/mdsd.xml /etc/mdsd.d cp -f $TMPDIR/envmdsd /etc/mdsd.d -#log rotate conf for mdsd and can be extended for other log files as well +# log rotate conf for mdsd and can be extended for other log files as well cp -f $TMPDIR/logrotate.conf /etc/logrotate.d/ci-agent #download inotify tools for watching configmap changes @@ -31,27 +40,27 @@ sudo apt-get install jq=1.5+dfsg-2 -y #used to setcaps for ruby process to read /proc/env sudo apt-get install libcap2-bin -y -wget https://dl.influxdata.com/telegraf/releases/telegraf-1.20.3_linux_amd64.tar.gz -tar -zxvf telegraf-1.20.3_linux_amd64.tar.gz +wget https://dl.influxdata.com/telegraf/releases/telegraf-1.20.3_linux_$ARCH.tar.gz +tar -zxvf telegraf-1.20.3_linux_$ARCH.tar.gz mv /opt/telegraf-1.20.3/usr/bin/telegraf /opt/telegraf chmod 544 /opt/telegraf # Use wildcard version so that it doesnt require to touch this file -/$TMPDIR/docker-cimprov-*.*.*-*.x86_64.sh --install +/$TMPDIR/docker-cimprov-*.*.*-*.*.sh --install #download and install fluent-bit(td-agent-bit) wget -qO - https://packages.fluentbit.io/fluentbit.key | sudo apt-key add - -sudo echo "deb https://packages.fluentbit.io/ubuntu/xenial xenial main" >> /etc/apt/sources.list +sudo echo "deb https://packages.fluentbit.io/ubuntu/bionic bionic main" >> /etc/apt/sources.list sudo apt-get update sudo apt-get install td-agent-bit=1.7.8 -y -# install ruby2.6 +# install ruby2.7 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F5DA5F09C3173AA6 sudo echo "deb http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu bionic main" >> /etc/apt/sources.list sudo apt-get update -sudo apt-get install ruby2.6 ruby2.6-dev gcc make -y +sudo apt-get install ruby2.7 ruby2.7-dev gcc make -y # fluentd v1 gem gem install fluentd -v "1.14.2" --no-document fluentd --setup ./fluent @@ -65,7 +74,7 @@ rm -f $TMPDIR/envmdsd rm -f $TMPDIR/telegraf-*.tar.gz # remove build dependencies -sudo apt-get remove ruby2.6-dev gcc make -y +sudo apt-get remove ruby2.7-dev gcc make -y # Remove settings for cron.daily that conflict with the node's cron.daily. Since both are trying to rotate the same files # in /var/log at the same time, the rotation doesn't happen correctly and then the *.1 file is forever logged to. diff --git a/scripts/build/linux/install-build-pre-requisites.sh b/scripts/build/linux/install-build-pre-requisites.sh index 7959b37e8..b85e54fc4 100644 --- a/scripts/build/linux/install-build-pre-requisites.sh +++ b/scripts/build/linux/install-build-pre-requisites.sh @@ -58,10 +58,26 @@ install_docker() sudo apt-get install docker-ce docker-ce-cli containerd.io -y # Allow your user to access the Docker CLI without needing root access. sudo usermod -aG docker $USER + newgrp docker echo "installing docker completed" fi } +install_docker_buildx() +{ + # install the buildx plugin + sudo curl -O https://github.com/docker/buildx/releases/download/v0.7.1/buildx-v0.7.1.linux-amd64 + sudo mkdir -p $HOME/.docker/cli-plugins + sudo mv buildx-v* $HOME/.docker/cli-plugins + + # install the emulator support + sudo apt-get -y install qemu binfmt-support qemu-user-static + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + docker buildx create --name testbuilder + docker buildx use testbuilder +} + install_python() { echo "installing python ..." @@ -125,6 +141,9 @@ install_build_dependencies # install docker install_docker +# install buildx +install_docker_buildx + # install go install_go_lang diff --git a/source/plugins/go/src/Makefile b/source/plugins/go/src/Makefile index b3b730d79..f9488bc8e 100644 --- a/source/plugins/go/src/Makefile +++ b/source/plugins/go/src/Makefile @@ -1,6 +1,16 @@ BASE_DIR := $(subst /build/linux,,$(PWD)) include $(BASE_DIR)/build/version +ifeq ($(arch),) + PF_ARCH=amd64 +else + PF_ARCH=$(arch) +endif + +ifneq ($(PF_ARCH),amd64) + OPTIONS=CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc GOOS=linux GOARCH=arm64 +endif + fbplugin: @echo "========================= Building out_oms plugin go code =========================" export BUILDVERSION=$(CONTAINER_BUILDVERSION_MAJOR).$(CONTAINER_BUILDVERSION_MINOR).$(CONTAINER_BUILDVERSION_PATCH)-$(CONTAINER_BUILDVERSION_BUILDNR) @@ -12,7 +22,7 @@ fbplugin: @echo "========================= go get =========================" go get @echo "========================= go build =========================" - go build -ldflags "-X 'main.revision=$(BUILDVERSION)' -X 'main.builddate=$(BUILDDATE)'" -buildmode=c-shared -o out_oms.so . + $(OPTIONS) go build -ldflags "-X 'main.revision=$(BUILDVERSION)' -X 'main.builddate=$(BUILDDATE)'" -buildmode=c-shared -o out_oms.so . test: go test -cover -race -coverprofile=coverage.txt -covermode=atomic diff --git a/source/plugins/ruby/in_kube_nodes.rb b/source/plugins/ruby/in_kube_nodes.rb index abbfe94a1..5a52a089b 100644 --- a/source/plugins/ruby/in_kube_nodes.rb +++ b/source/plugins/ruby/in_kube_nodes.rb @@ -560,6 +560,9 @@ def getNodeTelemetryProps(item) properties["OperatingSystem"] = nodeInfo["operatingSystem"] properties["KernelVersion"] = nodeInfo["kernelVersion"] properties["OSImage"] = nodeInfo["osImage"] + if nodeInfo["architecture"] == "arm64" + properties["Architecture"] = nodeInfo["architecture"] + end containerRuntimeVersion = nodeInfo["containerRuntimeVersion"] if containerRuntimeVersion.downcase.start_with?("docker://") properties["DockerVersion"] = containerRuntimeVersion.split("//")[1]