教程:使用 Jenkins 从 GitHub 部署到 Azure Kubernetes 服务

重要

许多 Azure 服务都有 Jenkins 插件。其中一些插件将从 2024 年 2 月 29 日开始不受支持。 当前推荐通过 Azure CLI 将 Jenkins 与 Azure 服务集成。 有关详细信息,请参阅适用于 Azure 的 Jenkins 插件一文。

本教程通过设置 Jenkins 中的持续集成 (CI) 和持续部署 (CD),将 GitHub 中的一个示例应用部署到 Azure 容器服务 (AKS) 群集。

在本教程中,你将完成以下任务:

  • 将示例 Azure 投票应用部署到 AKS 群集。
  • 创建一个基本 Jenkins 项目。
  • 设置可供 Jenkins 与 ACR 交互的凭据。
  • 创建用于自动执行生成操作的 Jenkins 生成作业和 GitHub Webhook。
  • 测试 CI/CD 管道,基于 GitHub 代码提交来更新 AKS 中的应用程序。

先决条件

若要完成本教程,需要准备好以下各项:

准备应用程序

在本文中,将使用一个示例 Azure 投票应用程序,其中包含 Web 接口和用作临时数据存储的 Redis。

集成 Jenkins 和 AKS 以执行自动部署前,请先手动准备 Azure 投票应用程序,并将它部署到 AKS 群集。 通过手动部署,可帮助你了解应用程序的实际效果。

注意

示例 Azure 投票应用程序使用计划在 Linux 节点上运行的 Linux pod。 本文中概述的流程还适用于计划在 Windows Server 节点上运行的 Windows Server pod。

为示例应用程序的以下 GitHub 存储库创建分支:https://github.com/Azure-Samples/azure-voting-app-redis。 若要将存储库分叉到自己的 GitHub 帐户,请选择右上角的“分叉”按钮

将此分支克隆到开发系统。 克隆此存储库时,请务必使用分支 URL:

git clone https://github.com/<your-github-account>/azure-voting-app-redis.git

更改为已克隆分支的目录:

cd azure-voting-app-redis

若要创建示例应用程序所需的容器映像,请结合使用 docker-compose.yaml 文件和 docker-compose

docker-compose up -d

此时,系统拉取所需的基础映像,并生成应用程序容器。 然后,可运行 docker images 命令,以查看创建的映像。 已下载或创建三个映像。 azure-vote-front 映像包含应用程序,并以 nginx-flask 映像为依据。 redis 映像用于启动 Redis 实例:

$ docker images

REPOSITORY                   TAG        IMAGE ID            CREATED             SIZE
azure-vote-front             latest     9cc914e25834        40 seconds ago      694MB
redis                        latest     a1b99da73d05        7 days ago          106MB
tiangolo/uwsgi-nginx-flask   flask      788ca94b2313        9 months ago        694MB

登录到 Azure 容器注册表。

az acr login -n <acrLoginServer>

<acrLoginServer> 替换为 ACR 登录服务器。

运行 docker tag 命令,以便使用 ACR 登录服务器名称和版本号 v1 来标记映像。 使用在上一步中获取的你自己的 <acrLoginServer> 名称:

docker tag azure-vote-front <acrLoginServer>/azure-vote-front:v1

最后,将 azure-vote-front 映像推送到 ACR 注册表。 同样,将 <acrLoginServer> 替换为你自己的 ACR 注册表的登录服务器名称(如 myacrregistry.azurecr.io):

docker push <acrLoginServer>/azure-vote-front:v1

将示例应用程序部署到 AKS

若要将示例应用程序部署到 AKS 群集,可使用 Azure 投票存储库根目录中的 Kubernetes 清单文件。 使用 vi 等编辑器打开 azure-vote-all-in-one-redis.yaml 清单文件。 将 microsoft 替换为 ACR 登录服务器名称。 此值位于清单文件的第 60 行:

containers:
- name: azure-vote-front
  image: azuredocs/azure-vote-front

接下来,运行 kubectl apply 命令,将应用程序部署到 AKS 群集:

kubectl apply -f azure-vote-all-in-one-redis.yaml

此时,系统创建 Kubernetes 负载均衡器服务,向 Internet 公开应用程序。 此过程可能需要几分钟。 若要监视负载均衡器部署进度,请将 kubectl get service 命令和 --watch 参数配合使用。

$ kubectl get service azure-vote-front --watch

EXTERNAL-IP 地址从“挂起”变为 IP 地址以后,请使用 Control + C 停止 kubectl 监视进程。

NAME               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE

若要查看应用程序的实际效果,请打开 Web 浏览器,以转到服务的外部 IP 地址。 此时,Azure 投票应用程序显示,如下面的示例所示:

AKS 中运行的 Azure 示例投票应用程序

配置 Jenkins 控制器

应用以下更改,以从 Jenkins 控制器启用 AKS 部署:

打开端口 80 入站。

az vm open-port \
--resource-group <Resource_Group_name> \
--name <Jenkins_Controller_VM>  \
--port 80 --priority 1020

<Resource_Group_name><Jenkins_Controller_VM> 替换为相应的值。

通过 SSH 连接到 Jenkins 控制器

ssh azureuser@<PublicIPAddres>

<PublicIPAddress> 替换为 Jenkins 控制器的 IP 地址。

安装并登录到 AzCLI

curl -L https://aka.ms/InstallAzureCli | bash
az login

注意

若要手动安装 AzCLI,请按照这些说明进行操作。

安装 Docker

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common -y;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -;
sudo apt-key fingerprint 0EBFCD88;
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable";
sudo apt-get update;
sudo apt-get install docker-ce -y;

安装 Kubectl 并连接到 AKS

sudo az aks install-cli
sudo az aks get-credentials --resource-group <Resource_Group> --name <AKS_Name>

<Resource_Group><AKS_Name> 替换为相应的值。

配置访问权限

sudo usermod -aG docker jenkins;
sudo usermod -aG docker azureuser;
sudo touch /var/lib/jenkins/jenkins.install.InstallUtil.lastExecVersion;
sudo service jenkins restart;
sudo cp ~/.kube/config /var/lib/jenkins/.kube/
sudo chmod 777 /var/lib/jenkins/
sudo chmod 777 /var/lib/jenkins/config

创建 Jenkins 环境变量

Jenkins 环境变量用于保留 ACR 登录服务器名称。 此变量在 Jenkins 生成作业运行期间进行引用。 若要创建此环境变量,请完成以下步骤:

  • 在 Jenkins 门户的左侧,依次选择“管理 Jenkins”>“配置系统”

  • 在“全局属性”下,选择“环境变量”。 添加包含名称 ACR_LOGINSERVER 和 ACR 登录服务器值的变量。

    Jenkins 环境变量

  • 完成后,在页面底部选择“保存”

创建 ACR 的 Jenkins 凭据

在 CI/CD 流程期间,Jenkins 根据应用程序更新生成新容器映像,然后需要将这些映像推送到 ACR 注册表。

必须指定 ACR 的凭据,Jenkins 才能将更新后的容器映像推送到 ACR。

为 Jenkins 的服务主体配置对 ACR 注册表的“参与者”权限,以区分角色和权限。

创建供 Jenkins 使用 ACR 的服务主体

首先,运行 az ad sp create-for-rbac 命令创建服务主体:

az ad sp create-for-rbac

此命令会生成类似于以下示例的输出:

{
  "appId": "<app-ID>",
  "displayName": "azure-cli-2018-09-28-22-19-34",
  "name": "http://azure-cli-2018-09-28-22-19-34",
  "password": "<password>",
  "tenant": "<tenant-ID>"
}

记下 appIdpassword。 在后续步骤中,需要用到这些值在 Jenkins 中配置凭据资源。

运行 az acr show 命令以获取 ACR 注册表的资源 ID,并将它存储为变量。

ACR_ID=$(az acr show --resource-group <Resource_Group> --name <acrLoginServer> --query "id" --output tsv)

<Resource_Group><acrLoginServer> 替换为相应的值。

创建角色分配,以向服务主体分配对 ACR 注册表的“参与者”权限。

az role assignment create --assignee <appID> --role Contributor --scope $ACR_ID

<appId> 替换为在用于创建服务主体的早期命令输出中提供的值。

在 Jenkins 中创建 ACR 服务主体的凭据资源

借助在 Azure 中创建的角色分配,现在将 ACR 凭据存储在 Jenkins 凭据对象中。 在运行 Jenkins 生成作业期间会引用这些凭据。

返回到 Jenkins 门户的左侧,依次选择“管理 Jenkins”>“管理凭据”>“Jenkins 存储”>“全局凭据(无限制)”>“添加凭据”

确保凭据类型为“带密码的用户名”,并输入以下项:

  • 用户名 - 为采用 ACR 注册表身份验证而创建的服务主体的 appId
  • 密码 - 为采用 ACR 注册表身份验证而创建的服务主体的 password
  • ID - 凭据标识符,如 acr-credentials

完成后,凭据表单如下面的示例所示:

创建包含服务主体信息的 Jenkins 凭据对象

选择“确定”,并返回到 Jenkins 门户。

创建 Jenkins 项目

在 Jenkins 门户主页的左侧,选择“新建项”

  1. 输入“azure-vote”作为作业名称。 依次选择“自由风格项目”和“确定”

  2. 在“常规”部分下面,选择“GitHub 项目”并输入已创建分支存储库的 URL,例如 https://github.com/<your-github-account>/azure-voting-app-redis

  3. 源代码管理部分下,选择 Git,输入分支存储库 .git URL,例如 https://github.com/<your-github-account>/azure-voting-app-redis.git

  4. 在“生成触发器”部分下面,选择“用于 GITscm 轮询的 GitHub 挂钩触发器”

  5. 在“生成环境”下,选择“使用机密文本或文件”

  6. 在“绑定”下,依次选择“添加”>“用户名和密码(已分隔)”

    • 在“用户名变量”中输入 ACR_ID,并在“密码变量”中输入 ACR_PASSWORD

      Jenkins 绑定

  7. 选择添加类型为“执行 shell”的“生成步骤”,并使用以下文本。 此脚本将生成新的容器映像,并将其推送到 ACR 注册表。

    # Build new image and push to ACR.
    WEB_IMAGE_NAME="${ACR_LOGINSERVER}/azure-vote-front:kube${BUILD_NUMBER}"
    docker build -t $WEB_IMAGE_NAME ./azure-vote
    docker login ${ACR_LOGINSERVER} -u ${ACR_ID} -p ${ACR_PASSWORD}
    docker push $WEB_IMAGE_NAME
    
  8. 添加另一个“执行 shell”类型的“生成步骤”并使用以下文本。 此脚本使用 ACR 中的新容器映像来更新 AKS 中的应用程序部署。

    # Update kubernetes deployment with new image.
    WEB_IMAGE_NAME="${ACR_LOGINSERVER}/azure-vote-front:kube${BUILD_NUMBER}"
    kubectl set image deployment/azure-vote-front azure-vote-front=$WEB_IMAGE_NAME
    
  9. 完成后,单击“保存”。

测试 Jenkins 生成

先手动测试 Jenkins 生成,再根据 GitHub 提交来自动执行作业。

此生成会验证是否已正确配置作业。 它将确认适当的 Kubernetes 身份验证文件是否已就位,以及 ACR 身份验证能否正常运行。

在项目的左侧菜单中,选择“立即生成”

Jenkins 测试生成

第一个生成需要的时间较长,因为 Docker 映像层会被下拉到 Jenkins 服务器。

这些生成将执行以下任务:

  1. 克隆 GitHub 存储库
  2. 生成新的容器映像
  3. 将容器映像推送到 ACR 注册表
  4. 更新 AKS 部署所使用的映像

由于未对应用程序代码进行任何更改,因此 Web UI 没有变化。

生成作业完成后,选择生成历史记录下的“生成 1”。 选择“控制台输出”,并查看生成流程的输出。 最后一行应指示生成成功。

创建 GitHub Webhook

成功完成手动生成后,立即将 GitHub 集成到 Jenkins 生成。 每次有时间代码提交到 GitHub 时,均会使用 Webhook 运行 Jenkins 生成作业。

若要创建 GitHub Webhook,请完成以下步骤:

  1. 在 Web 浏览器中,转到 GitHub 分支存储库。

  2. 选择“设置”,然后在左侧选择“Webhook”。

  3. 选择“添加 Webhook”。 对于“有效负载 URL”,输入“http://<publicIp:8080>/github-webhook/”,其中 <publicIp> 是 Jenkins 服务器的 IP 地址。 请务必包含尾随的 /。 保留内容类型的其他默认值,并触发“推送”事件。

  4. 选择“添加 Webhook”。

    为 Jenkins 创建 GitHub Webhook

测试整个 CI/CD 管道

现在可测试整个 CI/CD 管道。 当你将代码提交推送到 GitHub 后,系统会执行以下步骤:

  1. GitHub Webhook 通知 Jenkins。
  2. Jenkins 启动生成作业,并从 GitHub 拉取最新代码提交。
  3. Docker 生成通过更新后的代码启动,新容器映像标记有最新生成号。
  4. 新容器映像推送到 Azure 容器注册表。
  5. 在 Azure Kubernetes 服务上运行的应用程序将使用 Azure 容器注册表中的最新映像进行更新。

在开发计算机上,使用代码编辑器打开克隆的应用程序。 在 /azure-vote/azure-vote 目录下,打开 config_file.cfg 文件。 将此文件中的投票值更新为,除 cats 和 dogs 以外的值,如下面的示例所示:

# UI Configurations
TITLE = 'Azure Voting App'
VOTE1VALUE = 'Blue'
VOTE2VALUE = 'Purple'
SHOWHOST = 'false'

更新后,保存此文件并提交更改,同时将更改推送到 GitHub 存储库的分支。 GitHub Webhook 触发新的 Jenkins 生成作业。 在 Jenkins Web 仪表板中,监视生成流程。 只需几秒钟,即可拉取最新代码,创建和推送更新后的映像,并部署 AKS 中更新后的应用程序。

生成完成后,立即刷新示例 Azure 投票应用程序的 Web 浏览器。 此时,更改显示,如下面的示例所示:

AKS 中由 Jenkins 生成作业更新的示例 Azure 投票应用程序

后续步骤