这是一个来自于Azure的实验,实验资料:Azure Kubernetes 服务部署管道和 GitHub Actions

本实验涉及CI部分

CICD

持续集成 (CI)

CI 要求团队经常在代码中实现和集成最小更改。 实现此方法意味需要不断测试、编译、部署,然后在生产环境中再次测试。

最重要的 CI 原则之一是尽可能频繁地将所有最新更改合并回主分支。 不断合并更改有助于避免出现“集成地狱”和合并日,当许多开发人员在一天内一次性合并其更改时,常常会发生这种情况。

CI 旨在避免因代码更改而引起的生产问题,即在问题对研发人员或客户造成实际损害之前检测到这些问题。

CI 管道

CI 管道是我们为检测到新的代码更改时所运行的进程赋予的统称。 每当代码更改触发 CI 运行时,将执行所有管道步骤。 如果其中一个步骤出现错误,则管道将停止执行。

事件会触发管道。 软件开发过程中会触发大量事件。 CI 提供程序需要支持所有相关事件。 触发事件时,将触发此特定事件的所有侦听器。 进程的第一个阶段将启动。

在大多数情况下,该过程从克隆或下载源代码开始。 然后,触发下一步,依此类推。

工作流可以包含逻辑跳转,以便在满足某些条件时不执行阶段,但管道会继续执行。

持续交付 (CD)

CD 从 CI 结束的地方开始。 CD 会自动执行到所选基础结构环境的交付过程。 可以使用 CD 快速、持续地向客户发布新更改。

使用 CD 时,可以提前决定是每天、每周、每月还是视业务需要择日来部署更改。

本实验CICD管道设计

本实验假设应用Contoso ,其会生成一个应用网站。

  • CI阶段会生成两个工作管道,分别会生成带有latest和版本(如v.0.0.1)标签的镜像,并将两种镜像存储在镜像注册表中。

  • CD阶段,在成功向主分支进行带标签的推送后,会在 AKS 中发布一个网站。 此设计可以检查投入生产环境的每个部署的版本。 将容器镜像部署好后,可以使用标签进行路由。

  • 在每次成功推送到主分支(无论推送是否带标签)时在过渡环境中测试网站。

现在来设计此管道。

CI管道设计

Github Actions

Github Actions是本实验在Ci阶段使用的主要工具。GitHub Actions 通过自动化工作流无缝集成 GitHub 中的所有托管代码,工作流可以执行多个任务,并将代码集成到多个环境中(本实验环境为Azure镜像注册表)。

  • GitHub Actions 支持所有 GitHub 事件。 每个步骤都定义为一个操作,该操作可以是 JavaScript 代码,也可以是 Docker 容器。
  • Actions 是管道的最重要部分。 即阶段性的构建基块,且易于创建。

设计要点

  • 原始环境MicrosoftDocs/mslearn-aks-deployment-pipeline-github-actions,fork到github个人账户。使用Azure CLI或Cloud Shell克隆。
  • ACR和AKS的初始化使用克隆文件夹下init.sh实现
  • 使用Github Actions创建两个工作流。一个为lasted版本,一个为v*版本触发。两个工作流生成的镜像Push到ACR镜像库。

本阶段设计的管道流程图:

如上图所示:两个不同的事件会触发管道

  • 向主分支进行带标签的推送
  • 向主分支进行不带标签的推送

CD管道设计

对于部署步骤,是将网站部署到正确位置。

设计要点

  • 如果带标签的提交触发了管道,将网站部署到 AKS 群集的 production 命名空间中的生产环境

  • 如果带标记的提交没有触发管道,将其推送到同一群集的 staging 命名空间

  • 使用Helm为生成应用工具

本阶段设计的管道流程图:

LAB

初始化环境

  1. Fork原始内容
  2. 克隆文件夹到本地,使用Cloud shell或Azure CLI
[root@Alma ~]# git clone https://github.com/etaon/mslearn-aks-deployment-pipeline-github-actions
Cloning into 'mslearn-aks-deployment-pipeline-github-actions'...
remote: Enumerating objects: 146, done.
remote: Total 146 (delta 0), reused 0 (delta 0), pack-reused 146
Receiving objects: 100% (146/146), 225.46 KiB | 965.00 KiB/s, done.
Resolving deltas: 100% (59/59), done.

查看内容:

[root@Alma ~]# cd mslearn-aks-deployment-pipeline-github-actions/
[root@Alma mslearn-aks-deployment-pipeline-github-actions]# ll
total 48
-rw-r--r--. 1 root root   444 Jan 17 10:39 CODE_OF_CONDUCT.md
-rw-r--r--. 1 root root   574 Jan 17 10:39 Dockerfile
-rwxr-xr-x. 1 root root  1687 Jan 17 10:39 init.sh
drwxr-xr-x. 2 root root    69 Jan 17 10:39 kubernetes
-rw-r--r--. 1 root root 18653 Jan 17 10:39 LICENSE
-rw-r--r--. 1 root root  1141 Jan 17 10:39 LICENSE-CODE
-rw-r--r--. 1 root root  7686 Jan 17 10:39 README.md
-rw-r--r--. 1 root root  2780 Jan 17 10:39 SECURITY.md
drwxr-xr-x. 7 root root   101 Jan 17 10:39 src
  1. 使用init.sh生成环境,其内容如下
#!/bin/bashecho "Defining variables..."
export RESOURCE_GROUP_NAME=mslearn-gh-pipelines-$RANDOM
export AKS_NAME=contoso-video
export ACR_NAME=ContosoContainerRegistry$RANDOMecho "Searching for resource group..."
az group create -n $RESOURCE_GROUP_NAME -l eastusecho "Creating cluster..."
az aks create \--resource-group $RESOURCE_GROUP_NAME \--name $AKS_NAME \--node-count 1 \--enable-addons http_application_routing \--dns-name-prefix $AKS_NAME \--enable-managed-identity \--generate-ssh-keys \--node-vm-size Standard_B2secho "Obtaining credentials..."
az aks get-credentials -n $AKS_NAME -g $RESOURCE_GROUP_NAMEecho "Creating ACR..."
az acr create -n $ACR_NAME -g $RESOURCE_GROUP_NAME --sku basic
az acr update -n $ACR_NAME --admin-enabled trueexport ACR_USERNAME=$(az acr credential show -n $ACR_NAME --query "username" -o tsv)
export ACR_PASSWORD=$(az acr credential show -n $ACR_NAME --query "passwords[0].value" -o tsv)az aks update \--name $AKS_NAME \--resource-group $RESOURCE_GROUP_NAME \--attach-acr $ACR_NAMEexport DNS_NAME=$(az network dns zone list -o json --query "[?contains(resourceGroup,'$RESOURCE_GROUP_NAME')].name" -o tsv)sed -i '' 's+!IMAGE!+'"$ACR_NAME"'/contoso-website+g' kubernetes/deployment.yaml
sed -i '' 's+!DNS!+'"$DNS_NAME"'+g' kubernetes/ingress.yamlecho "Installation concluded, copy these values and store them, you'll use them later in this exercise:"
echo "-> Resource Group Name: $RESOURCE_GROUP_NAME"
echo "-> ACR Name: $ACR_NAME"
echo "-> ACR Login Username: $ACR_USERNAME"
echo "-> ACR Password: $ACR_PASSWORD"
echo "-> AKS Cluster Name: $ACR_NAME"
echo "-> AKS DNS Zone Name: $DNS_NAME"

可以看出本脚本主要生成一个AKS Cluster和一个ACR仓库。

[root@Alma mslearn-aks-deployment-pipeline-github-actions]# ./init.sh
Defining variables...
Searching for resource group...
{"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourceGroups/mslearn-gh-pipelines-6498","location": "eastus","managedBy": null,"name": "mslearn-gh-pipelines-6498","properties": {"provisioningState": "Succeeded"},"tags": null,"type": "Microsoft.Resources/resourceGroups"
}
Creating cluster...
{"aadProfile": null,"addonProfiles": {"httpApplicationRouting": {"config": {"HTTPApplicationRoutingZoneName": "9c4fe3790bba4b1eadd1.eastus.aksapp.io"},"enabled": true,"identity": {"clientId": "78b08f9a-00dd-4111-8d5f-56ba045ac2d8","objectId": "a5b7f775-f724-4c94-aead-28595e5e821b","resourceId": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.ManagedIdentity/userAssignedIdentities/httpapplicationrouting-contoso-video"}}},"agentPoolProfiles": [{"availabilityZones": null,"count": 1,"enableAutoScaling": false,"enableEncryptionAtHost": false,"enableFips": false,"enableNodePublicIp": false,"enableUltraSsd": false,"gpuInstanceProfile": null,"kubeletConfig": null,"kubeletDiskType": "OS","linuxOsConfig": null,"maxCount": null,"maxPods": 110,"minCount": null,"mode": "System","name": "nodepool1","nodeImageVersion": "AKSUbuntu-1804gen2containerd-2022.01.07","nodeLabels": null,"nodePublicIpPrefixId": null,"nodeTaints": null,"orchestratorVersion": "1.21.7","osDiskSizeGb": 128,"osDiskType": "Managed","osSku": "Ubuntu","osType": "Linux","podSubnetId": null,"powerState": {"code": "Running"},"provisioningState": "Succeeded","proximityPlacementGroupId": null,"scaleDownMode": null,"scaleSetEvictionPolicy": null,"scaleSetPriority": null,"spotMaxPrice": null,"tags": null,"type": "VirtualMachineScaleSets","upgradeSettings": null,"vmSize": "Standard_B2s","vnetSubnetId": null}],"apiServerAccessProfile": null,"autoScalerProfile": null,"autoUpgradeProfile": null,"azurePortalFqdn": "contoso-video-b9c207fb.portal.hcp.eastus.azmk8s.io","disableLocalAccounts": false,"diskEncryptionSetId": null,"dnsPrefix": "contoso-video","enablePodSecurityPolicy": null,"enableRbac": true,"extendedLocation": null,"fqdn": "contoso-video-b9c207fb.hcp.eastus.azmk8s.io","fqdnSubdomain": null,"httpProxyConfig": null,"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/mslearn-gh-pipelines-6498/providers/Microsoft.ContainerService/managedClusters/contoso-video","identity": {"principalId": "2d7d6a16-0029-4650-a940-e06444a45528","tenantId": "7446b7c5-bb59-4186-a8df-513c195bc49f","type": "SystemAssigned","userAssignedIdentities": null},"identityProfile": {"kubeletidentity": {"clientId": "bce75f9f-3c0a-47a4-b286-817aa71606c7","objectId": "9e9f8eac-2e13-4124-8471-3ae4aa22c0e6","resourceId": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.ManagedIdentity/userAssignedIdentities/contoso-video-agentpool"}},"kubernetesVersion": "1.21.7","linuxProfile": {"adminUsername": "azureuser","ssh": {"publicKeys": [{"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTn5WASHIgIKuIeEgGSdkaxZ8DntqG+zUkjMPiZMxtRH2/dZaL230SbRG+FZ3FrsvnQp40d7TSCGdADIufsS9hkNkR0egzIsPGqzhcjyeYOAOSBD8atImbAxb6aFntk1uS1hVpn2C2p5DE0//FsWdp+KDTVAcdHgkrYMPECTfQh/lmURlddaLf3ZNju6xUc/sOFDAPZmVXr17pkuAYRjAr7MGchh6Rpbkg665ZOdY4lAJWDZONJ1u1DsyGQO18qdLDU7ZreOSgHe0pgLbVtKnUTAhGicjQqRGvwfKUQdyV223PjBqo57o/iNpPej2NR2Euhbcst25BE8KjzZ6l9y8n"}]}},"location": "eastus","maxAgentPools": 100,"name": "contoso-video","networkProfile": {"dnsServiceIp": "10.0.0.10","dockerBridgeCidr": "172.17.0.1/16","loadBalancerProfile": {"allocatedOutboundPorts": null,"effectiveOutboundIPs": [{"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourceGroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.Network/publicIPAddresses/8b24dcb0-2bac-46c7-bcb6-27908632326c","resourceGroup": "MC_mslearn-gh-pipelines-6498_contoso-video_eastus"}],"idleTimeoutInMinutes": null,"managedOutboundIPs": {"count": 1},"outboundIPs": null,"outboundIpPrefixes": null},"loadBalancerSku": "Standard","natGatewayProfile": null,"networkMode": null,"networkPlugin": "kubenet","networkPolicy": null,"outboundType": "loadBalancer","podCidr": "10.244.0.0/16","serviceCidr": "10.0.0.0/16"},"nodeResourceGroup": "MC_mslearn-gh-pipelines-6498_contoso-video_eastus","podIdentityProfile": null,"powerState": {"code": "Running"},"privateFqdn": null,"privateLinkResources": null,"provisioningState": "Succeeded","resourceGroup": "mslearn-gh-pipelines-6498","securityProfile": null,"servicePrincipalProfile": {"clientId": "msi","secret": null},"sku": {"name": "Basic","tier": "Free"},"tags": null,"type": "Microsoft.ContainerService/ManagedClusters","windowsProfile": null
}
Obtaining credentials...
Merged "contoso-video" as current context in /root/.kube/config
Creating ACR...
{"adminUserEnabled": false,"anonymousPullEnabled": false,"creationDate": "2022-01-17T03:12:55.182289+00:00","dataEndpointEnabled": false,"dataEndpointHostNames": [],"encryption": {"keyVaultProperties": null,"status": "disabled"},"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourceGroups/mslearn-gh-pipelines-6498/providers/Microsoft.ContainerRegistry/registries/ContosoContainerRegistry5380","identity": null,"location": "eastus","loginServer": "contosocontainerregistry5380.azurecr.io","name": "ContosoContainerRegistry5380","networkRuleBypassOptions": "AzureServices","networkRuleSet": null,"policies": {"exportPolicy": {"status": "enabled"},"quarantinePolicy": {"status": "disabled"},"retentionPolicy": {"days": 7,"lastUpdatedTime": "2022-01-17T03:12:56.840110+00:00","status": "disabled"},"trustPolicy": {"status": "disabled","type": "Notary"}},"privateEndpointConnections": [],"provisioningState": "Succeeded","publicNetworkAccess": "Enabled","resourceGroup": "mslearn-gh-pipelines-6498","sku": {"name": "Basic","tier": "Basic"},"status": null,"systemData": {"createdAt": "2022-01-17T03:12:55.182289+00:00","createdBy": "izhao.yiyi@hotmail.com","createdByType": "User","lastModifiedAt": "2022-01-17T03:12:55.182289+00:00","lastModifiedBy": "izhao.yiyi@hotmail.com","lastModifiedByType": "User"},"tags": {},"type": "Microsoft.ContainerRegistry/registries","zoneRedundancy": "Disabled"
}
{"adminUserEnabled": true,"anonymousPullEnabled": false,"creationDate": "2022-01-17T03:12:55.182289+00:00","dataEndpointEnabled": false,"dataEndpointHostNames": [],"encryption": {"keyVaultProperties": null,"status": "disabled"},"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourceGroups/mslearn-gh-pipelines-6498/providers/Microsoft.ContainerRegistry/registries/ContosoContainerRegistry5380","identity": null,"location": "eastus","loginServer": "contosocontainerregistry5380.azurecr.io","name": "ContosoContainerRegistry5380","networkRuleBypassOptions": "AzureServices","networkRuleSet": null,"policies": {"exportPolicy": {"status": "enabled"},"quarantinePolicy": {"status": "disabled"},"retentionPolicy": {"days": 7,"lastUpdatedTime": "2022-01-17T03:12:56.840110+00:00","status": "disabled"},"trustPolicy": {"status": "disabled","type": "Notary"}},"privateEndpointConnections": [],"provisioningState": "Succeeded","publicNetworkAccess": "Enabled","resourceGroup": "mslearn-gh-pipelines-6498","sku": {"name": "Basic","tier": "Basic"},"status": null,"systemData": {"createdAt": "2022-01-17T03:12:55.182289+00:00","createdBy": "izhao.yiyi@hotmail.com","createdByType": "User","lastModifiedAt": "2022-01-17T03:13:13.400167+00:00","lastModifiedBy": "izhao.yiyi@hotmail.com","lastModifiedByType": "User"},"tags": {},"type": "Microsoft.ContainerRegistry/registries","zoneRedundancy": "Disabled"
}
AAD role propagation done[############################################]  100.0000%{"aadProfile": null,"addonProfiles": {"httpApplicationRouting": {"config": {"HTTPApplicationRoutingZoneName": "9c4fe3790bba4b1eadd1.eastus.aksapp.io"},"enabled": true,"identity": {"clientId": "78b08f9a-00dd-4111-8d5f-56ba045ac2d8","objectId": "a5b7f775-f724-4c94-aead-28595e5e821b","resourceId": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.ManagedIdentity/userAssignedIdentities/httpapplicationrouting-contoso-video"}}},"agentPoolProfiles": [{"availabilityZones": null,"count": 1,"enableAutoScaling": false,"enableEncryptionAtHost": false,"enableFips": false,"enableNodePublicIp": false,"enableUltraSsd": false,"gpuInstanceProfile": null,"kubeletConfig": null,"kubeletDiskType": "OS","linuxOsConfig": null,"maxCount": null,"maxPods": 110,"minCount": null,"mode": "System","name": "nodepool1","nodeImageVersion": "AKSUbuntu-1804gen2containerd-2022.01.07","nodeLabels": null,"nodePublicIpPrefixId": null,"nodeTaints": null,"orchestratorVersion": "1.21.7","osDiskSizeGb": 128,"osDiskType": "Managed","osSku": "Ubuntu","osType": "Linux","podSubnetId": null,"powerState": {"code": "Running"},"provisioningState": "Succeeded","proximityPlacementGroupId": null,"scaleDownMode": null,"scaleSetEvictionPolicy": null,"scaleSetPriority": null,"spotMaxPrice": null,"tags": null,"type": "VirtualMachineScaleSets","upgradeSettings": null,"vmSize": "Standard_B2s","vnetSubnetId": null}],"apiServerAccessProfile": null,"autoScalerProfile": null,"autoUpgradeProfile": null,"azurePortalFqdn": "contoso-video-b9c207fb.portal.hcp.eastus.azmk8s.io","disableLocalAccounts": false,"diskEncryptionSetId": null,"dnsPrefix": "contoso-video","enablePodSecurityPolicy": null,"enableRbac": true,"extendedLocation": null,"fqdn": "contoso-video-b9c207fb.hcp.eastus.azmk8s.io","fqdnSubdomain": null,"httpProxyConfig": null,"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/mslearn-gh-pipelines-6498/providers/Microsoft.ContainerService/managedClusters/contoso-video","identity": {"principalId": "2d7d6a16-0029-4650-a940-e06444a45528","tenantId": "7446b7c5-bb59-4186-a8df-513c195bc49f","type": "SystemAssigned","userAssignedIdentities": null},"identityProfile": {"kubeletidentity": {"clientId": "bce75f9f-3c0a-47a4-b286-817aa71606c7","objectId": "9e9f8eac-2e13-4124-8471-3ae4aa22c0e6","resourceId": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourcegroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.ManagedIdentity/userAssignedIdentities/contoso-video-agentpool"}},"kubernetesVersion": "1.21.7","linuxProfile": {"adminUsername": "azureuser","ssh": {"publicKeys": [{"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTn5WASHIgIKuIeEgGSdkaxZ8DntqG+zUkjMPiZMxtRH2/dZaL230SbRG+FZ3FrsvnQp40d7TSCGdADIufsS9hkNkR0egzIsPGqzhcjyeYOAOSBD8atImbAxb6aFntk1uS1hVpn2C2p5DE0//FsWdp+KDTVAcdHgkrYMPECTfQh/lmURlddaLf3ZNju6xUc/sOFDAPZmVXr17pkuAYRjAr7MGchh6Rpbkg665ZOdY4lAJWDZONJ1u1DsyGQO18qdLDU7ZreOSgHe0pgLbVtKnUTAhGicjQqRGvwfKUQdyV223PjBqo57o/iNpPej2NR2Euhbcst25BE8KjzZ6l9y8n"}]}},"location": "eastus","maxAgentPools": 100,"name": "contoso-video","networkProfile": {"dnsServiceIp": "10.0.0.10","dockerBridgeCidr": "172.17.0.1/16","loadBalancerProfile": {"allocatedOutboundPorts": null,"effectiveOutboundIPs": [{"id": "/subscriptions/14adb214-7b29-422a-ac8a-df2af1e51201/resourceGroups/MC_mslearn-gh-pipelines-6498_contoso-video_eastus/providers/Microsoft.Network/publicIPAddresses/8b24dcb0-2bac-46c7-bcb6-27908632326c","resourceGroup": "MC_mslearn-gh-pipelines-6498_contoso-video_eastus"}],"idleTimeoutInMinutes": null,"managedOutboundIPs": {"count": 1},"outboundIPs": null,"outboundIpPrefixes": null},"loadBalancerSku": "Standard","natGatewayProfile": null,"networkMode": null,"networkPlugin": "kubenet","networkPolicy": null,"outboundType": "loadBalancer","podCidr": "10.244.0.0/16","serviceCidr": "10.0.0.0/16"},"nodeResourceGroup": "MC_mslearn-gh-pipelines-6498_contoso-video_eastus","podIdentityProfile": null,"powerState": {"code": "Running"},"privateFqdn": null,"privateLinkResources": null,"provisioningState": "Succeeded","resourceGroup": "mslearn-gh-pipelines-6498","securityProfile": null,"servicePrincipalProfile": {"clientId": "msi","secret": null},"sku": {"name": "Basic","tier": "Free"},"tags": null,"type": "Microsoft.ContainerService/ManagedClusters","windowsProfile": null
}
sed: can't read s+!IMAGE!+ContosoContainerRegistry5380/contoso-website+g: No such file or directory
sed: can't read s+!DNS!+9c4fe3790bba4b1eadd1.eastus.aksapp.io+g: No such file or directory
Installation concluded, copy these values and store them, you'll use them later in this exercise:
-> Resource Group Name: mslearn-gh-pipelines-6498
-> ACR Name: ContosoContainerRegistry5380
-> ACR Login Username: ContosoContainerRegistry5380
-> ACR Password: Kuyj6H3dvx3h90nj5P851onpoM7aMMX+
-> AKS Cluster Name: ContosoContainerRegistry5380
-> AKS DNS Zone Name: 9c4fe3790bba4b1eadd1.eastus.aksapp.io

最后生成的ASK、ACR等的参数:

-> Resource Group Name: mslearn-gh-pipelines-6498
-> ACR Name: ContosoContainerRegistry5380
-> ACR Login Username: ContosoContainerRegistry5380
-> ACR Password: Kuyj6H3dvx3h90nj5P851onpoM7aMMX+
-> AKS Cluster Name: ContosoContainerRegistry5380
-> AKS DNS Zone Name: 9c4fe3790bba4b1eadd1.eastus.aksapp.io

从控制台也可以看到:

CI:生成管道(latest)

步骤为:

  • 生成操作工作流
  • 创建触发器
  • 生成并推送映像
  • 设置secret
  • 推送映像

生成操作工作流

选择Actions下的set up a workflow yourself

管道是存储库中的 .github/workflows 目录中的一个文件。 GitHub 提供了生成大多数管道所需的预生成组件。

默认会生成一个main.yml模板来定义管道,如以下示例所示:

# This is a basic workflow to help you get started with Actionsname: CI# Controls when the workflow will run
on:# Triggers the workflow on push or pull request events but only for the main branchpush:branches: [ main ]pull_request:branches: [ main ]# Allows you to run this workflow manually from the Actions tabworkflow_dispatch:# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:# This workflow contains a single job called "build"build:# The type of runner that the job will run onruns-on: ubuntu-latest# Steps represent a sequence of tasks that will be executed as part of the jobsteps:# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it- uses: actions/checkout@v2# Runs a single command using the runners shell- name: Run a one-line scriptrun: echo Hello, world!# Runs a set of commands using the runners shell- name: Run a multi-line scriptrun: |echo Add other actions to build,echo test, and deploy your project.

配置文件分为三部分:

  • 名字
# This is a basic workflow to help you get started with Actionsname: CI
  • 触发器,以’on’标准
# Controls when the workflow will run
on:# Triggers the workflow on push or pull request events but only for the main branchpush:branches: [ main ]pull_request:branches: [ main ]
  • 工作流的具体行动
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:# This workflow contains a single job called "build"build:# The type of runner that the job will run onruns-on: ubuntu-latest# Steps represent a sequence of tasks that will be executed as part of the jobsteps:# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it- uses: actions/checkout@v2# Runs a single command using the runners shell- name: Run a one-line scriptrun: echo Hello, world!# Runs a set of commands using the runners shell- name: Run a multi-line scriptrun: |echo Add other actions to build,echo test, and deploy your project.

创建触发器

修改yml名称并更改默认触发器

  1. “main.yml”重命名为“build-staging.yml”
  2. 该名称:Build and push the latest build to staging
  3. 修改触发器
name: Build and push the latest build to stagingon:push:branches: [ main ]

生成并推送映像

  1. 将 build 项重命名为 build_push_image。
  2. 将该版本修复为 ubuntu-20.04
  3. 在steps首先确保已具有一个使用 checkout 操作的步骤。 此操作会将存储库克隆到作业环境中(默认已存在)
  # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it- uses: actions/checkout@v2
  1. 为了登录镜像存储卡,在右侧Marketplace输入Docker login:

    选择Docker Login并复制配置:
- name: Docker Login# You may pin to the exact commit or the version.# uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7uses: docker/login-action@v1.12.0with:# Server address of Docker registry. If not set then will default to Docker Hubregistry: # optional# Username used to log against the Docker registryusername: # optional# Password or personal access token used to log against the Docker registrypassword: # optional# Specifies whether the given registry is ECR (auto, true or false)ecr: # optional, default is auto# Log out from the Docker registry at the end of a joblogout: # optional, default is true

注意缩进:name 项应与上一个 uses 项对齐。

使用的参数用到了前面环境准备时的参数项:

项名称 用于操作
username docker/login ${{ secrets.ACR_LOGIN }}
password docker/login ${{ secrets.ACR_PASSWORD }}
注册表 docker/login ${{ secrets.ACR_NAME }}
repository docker/build-and-push contoso-website
标记 docker/build-and-push latst
上下文 docker/build-and-push .
push docker/build-and-push true

有关详细信息,请参阅 GitHub 生成-推送-操作文档

  1. 生成并推送镜像
    在上面提到的操作文档中可以查到Build and push的示例:
      - name: Build and pushuses: docker/build-push-action@v2with:context: .push: truetags: user/app:latest

dockerfile文件放在操作的‘.’目录下:

FROM nginx:1.18
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get update -y && apt-get install -y git curl nodejs && curl -sL https://github.com/gohugoio/hugo/releases/download/v0.72.0/hugo_extended_0.72.0_Linux-64bit.tar.gz | tar -xz hugo && mv hugo /usr/bin && npm i -g postcss-cli autoprefixer postcss
RUN git clone https://github.com/MicrosoftDocs/mslearn-aks-deployment-pipeline-github-actions /contoso-website
WORKDIR /contoso-website/src
RUN git submodule update --init themes/introduction
RUN hugo && mv public/* /usr/share/nginx/html
EXPOSE 80
  1. 还将在签出操作和登录操作之间添加另一个操作,以设置生成引擎供 Docker 使用。 此操作称为 docker/setup-buildx-action,使用 v1。
- name: Set up Buildxuses: docker/setup-buildx-action@v1

最后的yml文件:

name: Build and push the latest build to stagingon:push:branches: [ main ]jobs:build_push_image:runs-on: ubuntu-20.04steps:- uses: actions/checkout@v2- name: Set up Buildxuses: docker/setup-buildx-action@v1- name: Docker Loginuses: docker/login-action@v1.12.0with:registry: ${{ secrets.ACR_NAME }}username: ${{ secrets.ACR_LOGIN }}password: ${{ secrets.ACR_PASSWORD }}- name: Build and push staging imagesuses: docker/build-push-action@v2with:context: .tags: ${{secrets.ACR_NAME}}/contoso-website:latestpush: true

Commit new file:

可以看到在.github/workflow中已经生产了文件

而在Actions里面发现工作流失败:

这是因为在工作流中定义的参数还没有,这需要采用secret的方式导入。

设置secret

setting–>Secret–>New repository secret

名称:

      registry: ${{ secrets.ACR_NAME }}username: ${{ secrets.ACR_LOGIN }}password: ${{ secrets.ACR_PASSWORD }}

值:

-> ACR Name: `ContosoContainerRegistry5380`#注意完整的ACR:contosocontainerregistry5380.azurecr.io
-> ACR Login Username: `ContosoContainerRegistry5380`
-> ACR Password: `Kuyj6H3dvx3h90nj5P851onpoM7aMMX+`

生产结果:

推送镜像

到Actions中再次提交

成功!
从Azure控制台也可以看到:

CI:生成管道(v*)

再生成使用带标签的工作流,建立新的yml文件:build-production.yml,并将name改成
name: Build and push the tagged build to production

触发器

name: Build and push the tagged build to productionon:push:tags:- 'v*'

生成并推送映像

  1. 创建将收集必要版本信息的新步骤。 为此,将使用 ::set-output 内部命令。 在签出操作下面添加以下行:
- name: Fetch latest versionid: fetch_versionrun: echo ::set-output name=TAG::${GITHUB_REF#refs/tags/}
  1. 修改push的label
      - name: Build and push production imagesuses: docker/build-push-action@v2with:context: .tags: ${{secrets.ACR_NAME}}/contoso-website:latest,${{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}push: true

整体的yml:

name: Build and push the latest build to productionon:push:tags:- 'v*'jobs:build_push_image:runs-on: ubuntu-20.04steps:- uses: actions/checkout@v2- name: Fetch latest versionid: fetch_versionrun: echo ::set-output name=TAG::${GITHUB_REF#refs/tags/}- name: Docker Loginuses: docker/login-action@v1.12.0with:registry: ${{ secrets.ACR_NAME }}username: ${{ secrets.ACR_LOGIN }}password: ${{ secrets.ACR_PASSWORD }}- name: Build and push production imagesuses: docker/build-push-action@v2with:context: .tags: ${{secrets.ACR_NAME}}/contoso-website:latest,${{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}push: true


执行成功以后,由于没有push新的v*的label,并不会生成新的images:

3. 在azure shell中提交tag(pull的文件夹更新到最新):

izhao_yiyi@Azure:~/mslearn-aks-deployment-pipeline-github-actions$ git tag -a v0.0.1 -m'First tag'
izhao_yiyi@Azure:~/mslearn-aks-deployment-pipeline-github-actions$ git push --tags
Username for 'https://github.com': etaon
Password for 'https://etaon@github.com':
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 170 bytes | 170.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/etaon/mslearn-aks-deployment-pipeline-github-actions* [new tag]         v0.0.1 -> v0.0.1

完成以后:

ACR中可以看到两个版本

CI管道-Github+ACR相关推荐

  1. travis ci_如何使用Travis CI和GitHub进行Web开发工作流程

    travis ci by Vijayabharathi Balasubramanian 通过Vijayabharathi Balasubramanian 如何使用Travis CI和GitHub进行W ...

  2. 如何在 GitLab CI 管道中构建 Docker 映像

    CI 管道的一个常见用例是构建用于部署应用程序的 Docker 映像.GitLab CI 是一个很好的选择,因为它支持集成的拉代理服务,这意味着更快的管道,以及用于存储构建图像的内置注册表. 在本指南 ...

  3. 赛普拉斯天线_赛普拉斯在gitlab ci管道中设置了首次验收测试

    赛普拉斯天线 Late evening calls, reverted releases, lost revenue, and eventually fear of touching anything ...

  4. ci github 通知_初探CI,Github调戏Action手记——自动构建并发布

    前言 最近在做脚本的说明文档时使用了vuepress这个东西 前端实在是菜,只能随便写写了 正常写完md文件之后推送至github做版本控制 而前端页面的生成则是在本地,部署也是在本地手工进行 一套下 ...

  5. 使用Jenkins,GitHub和Docker的最先进的持续集成和部署管道

    搭建舞台 在过去的两年中,我一直在从事Node.js项目. 我们使用GitHub进行源管理,使用Jenkins进行持续集成. 我们还有一个基于Docker和Terraform的部署工具 . 在此期间, ...

  6. github持续集成的设置_如何使用GitHub Actions和Puppeteer建立持续集成管道

    github持续集成的设置 Lately I've added continuous integration to my blog using Puppeteer for end to end tes ...

  7. 被投毒的管道:研究员探索CI环境中的攻击方法

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 专栏·供应链安全 数字化时代,软件无处不在.软件如同社会中的"虚拟人",已经成为支撑社会正常运转的最基本元素之一,软件的安全 ...

  8. 使用GitHub Actions通过CI提高代码质量

    不论是开发.暂存还是生产环境,无时无刻都有代码不间断地被推送到 Git 上. 我们总是想要确保我们投入大量时间设计和编写的代码是具备可读性与安全性的,并且没有漏洞,能够平稳地运行. 使用自动化可以节省 ...

  9. GitHub Actions 漏洞可导致攻击者投毒开发管道

     聚焦源代码安全,网罗国内外最新资讯! 专栏·供应链安全 数字化时代,软件无处不在.软件如同社会中的"虚拟人",已经成为支撑社会正常运转的最基本元素之一,软件的安全性问题也正在成为 ...

  10. Flutter GitHub Travis CI 搭建

    通过 Travis CI 连接 GitHub 上的 Flutter 项目, 实现持续集成: 代码扫描, 测试, 打包发布 release. Install Android SDK os: linuxl ...

最新文章

  1. QPS、TPS、RT、并发数、吞吐量理解和性能优化深入思考
  2. 编程能力差!90%输在这点上!谷歌AI专家:其实都是瞎努力!
  3. C# winform开发:Graphics、pictureBox同时画多个矩形
  4. [Medical Image Processing] 1. Introduction
  5. 面试官 | 什么是递归算法?它有什么用?
  6. MooTools教程(5):事件处理
  7. java 获取本机的ip和mac_java获取本机ip和mac地址
  8. SpringBoot 2.1.5(12)--- Spring Boot 特性上
  9. batchplot3.5.9如何使用_VirtualBox中安装的Windows XP如何使用USB3.0
  10. 多年心路历程见证从技术小白到收获BAT等大厂研发offer,分享一些经验和感悟...
  11. gson 不忽略空_仅在不为null或不为空的情况下,Gson序列化字段
  12. java mq5.15,ActiveMQ 5.15.x Release安装和配置--Linux篇
  13. ListView分组实现方案(一)
  14. Java Programming Review 02
  15. 赛事+内容IP齐发力,汽车之家打破Z世代次元壁
  16. 简单快速的视频上传分享网站,可做外链
  17. Jmeter取样器设置
  18. Label Smoothing 标签平滑 (Label smooth regularization, LSR)
  19. VSTO,PPT插件,C#,文本框TextFrame对象和TextFrame2对象在文本居中上的区别
  20. visual studio 2008微软教程

热门文章

  1. c语言写股票交易软件,写股票软件
  2. python中字典的定义和操作
  3. NSUOJ2888最小唯一表示前缀(偷懒的xzj)
  4. 构词法——现代单词记忆十大规律
  5. 计算机安装xp蓝屏怎么办,联想笔记本装xp系统蓝屏解决方法
  6. java中赛场统分的情况
  7. matlab 如何将.m文件所在的路径设置为当前活动目录(当前文件夹),以及保存到matlab搜索路径
  8. 如何在浏览器中禁用和启用Cookie?
  9. Autodesk CAD帮助文档 DXF 图层使用
  10. elastic mapping not_analyzed 简单理解 + analysis-ik分词器安装