CI管道-Github+ACR

这是一个来自于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/bash

echo "Defining variables..."
export RESOURCE_GROUP_NAME=mslearn-gh-pipelines-$RANDOM
export AKS_NAME=contoso-video
export ACR_NAME=ContosoContainerRegistry$RANDOM

echo "Searching for resource group..."
az group create -n $RESOURCE_GROUP_NAME -l eastus

echo "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_B2s

echo "Obtaining credentials..."
az aks get-credentials -n $AKS_NAME -g $RESOURCE_GROUP_NAME

echo "Creating ACR..."
az acr create -n $ACR_NAME -g $RESOURCE_GROUP_NAME --sku basic
az acr update -n $ACR_NAME --admin-enabled true

export 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_NAME

export 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.yaml

echo "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 Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_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 on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # 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 script
        run: echo Hello, world!

      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.

配置文件分为三部分:

  • 名字
# This is a basic workflow to help you get started with Actions

name: CI
  • 触发器,以’on’标准
# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    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 on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # 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 script
        run: echo Hello, world!

      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          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 staging

on:
  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@42d299face0c5c43a0487c477f595ac9cf22f1a7
  uses: docker/login-action@v1.12.0
  with:
    # Server address of Docker registry. If not set then will default to Docker Hub
    registry: # optional
    # Username used to log against the Docker registry
    username: # optional
    # Password or personal access token used to log against the Docker registry
    password: # 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 job
    logout: # optional, default is true

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

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

项名称用于操作
usernamedocker/login${{ secrets.ACR_LOGIN }}
passworddocker/login${{ secrets.ACR_PASSWORD }}
注册表docker/login${{ secrets.ACR_NAME }}
repositorydocker/build-and-pushcontoso-website
标记docker/build-and-pushlatst
上下文docker/build-and-push.
pushdocker/build-and-pushtrue

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

  1. 生成并推送镜像
    在上面提到的操作文档中可以查到Build and push的示例:
      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: 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 Buildx
  uses: docker/setup-buildx-action@v1

最后的yml文件:

name: Build and push the latest build to staging

on:
  push:
    branches: [ main ]

jobs:
  build_push_image:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Docker Login
        uses: docker/login-action@v1.12.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Build and push staging images
        uses: docker/build-push-action@v2
        with:
          context: .
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest
          push: 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 production

on:
  push:
    tags:
      - 'v*'

生成并推送映像

  1. 创建将收集必要版本信息的新步骤。 为此,将使用 ::set-output 内部命令。 在签出操作下面添加以下行:
- name: Fetch latest version
  id: fetch_version
  run: echo ::set-output name=TAG::${GITHUB_REF#refs/tags/}
  1. 修改push的label
      - name: Build and push production images
        uses: docker/build-push-action@v2
        with:
          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 production

on:
  push:
    tags:
      - 'v*'

jobs:
  build_push_image:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2

      - name: Fetch latest version
        id: fetch_version
        run: echo ::set-output name=TAG::${GITHUB_REF#refs/tags/}

      - name: Docker Login
        uses: docker/login-action@v1.12.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Build and push production images
        uses: docker/build-push-action@v2
        with:
          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中可以看到两个版本
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值