您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

如何使用 Jenkins、GitHub 和 Docker 在 Azure 中的 Linux VM 上创建开发基础结构How to create a development infrastructure on a Linux VM in Azure with Jenkins, GitHub, and Docker

要将应用程序开发的生成和测试阶段自动化,可以使用持续集成和部署 (CI/CD) 管道。To automate the build and test phase of application development, you can use a continuous integration and deployment (CI/CD) pipeline. 本教程介绍如何在 Azure VM 上创建 CI/CD 管道,包括如何:In this tutorial, you create a CI/CD pipeline on an Azure VM including how to:

  • 创建 Jenkins VMCreate a Jenkins VM
  • 安装并配置 JenkinsInstall and configure Jenkins
  • 创建 GitHub 与 Jenkins 之间的 Webhook 集成Create webhook integration between GitHub and Jenkins
  • 通过 GitHub 提交创建并触发 Jenkins 生成作业Create and trigger Jenkins build jobs from GitHub commits
  • 创建应用的 Docker 映像Create a Docker image for your app
  • 验证 GitHub 提交是否生成新的 Docker 映像并更新正在运行的应用Verify GitHub commits build new Docker image and updates running app

启动 Azure Cloud ShellLaunch Azure Cloud Shell

Azure Cloud Shell 是免费的交互式 shell,可以使用它运行本文中的步骤。The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. 它预安装有常用 Azure 工具并将其配置与帐户一起使用。It has common Azure tools preinstalled and configured to use with your account. 请直接单击“复制”对代码进行复制,将其粘贴到 Cloud Shell 中,然后按 Enter 来运行它。Just click the Copy to copy the code, paste it into the Cloud Shell, and then press enter to run it. 可以通过两种方式来启动 Cloud Shell:There are two ways to launch the Cloud Shell:

单击代码块右上角的“试用”。Click Try It in the upper right corner of a code block. 本文中的 Cloud Shell
单击 Azure 门户右上角菜单上的“Cloud Shell”按钮。Click the Cloud Shell button on the menu in the upper right of the Azure portal. 门户中的 Cloud Shell

如果选择在本地安装并使用 CLI,本教程要求运行 Azure CLI 2.0.4 或更高版本。If you choose to install and use the CLI locally, this tutorial requires that you are running the Azure CLI version 2.0.4 or later. 运行 az --version 即可查找版本。Run az --version to find the version. 如果需要进行安装或升级,请参阅安装 Azure CLI 2.0If you need to install or upgrade, see Install Azure CLI 2.0.

创建 Jenkins 实例Create Jenkins instance

在有关如何在首次启动时自定义 Linux 虚拟机的上一个教程中,已了解如何使用 cloud-init 自动执行 VM 自定义。In a previous tutorial on How to customize a Linux virtual machine on first boot, you learned how to automate VM customization with cloud-init. 本教程使用 cloud-init 文件在 VM 上安装 Jenkins 和 Docker。This tutorial uses a cloud-init file to install Jenkins and Docker on a VM. Jenkins 是一种常用的开放源代码自动化服务器,它与 Azure 无缝集成以支持持续集成 (CI) 和持续交付 (CD)。Jenkins is a popular open source automation server that integrates seamlessly with Azure to enable continuous integration (CI) and continuous delivery (CD). 有关如何使用 Jenkins 的更多教程,请参阅Azure 中心中的 JenkinsFor more tutorials on how to use Jenkins, see the Jenkins in Azure hub.

在当前 shell 中,创建名为“cloud-init.txt”的文件并粘贴下面的配置。In your current shell, create a file named cloud-init.txt and paste the following configuration. 例如,在不处于本地计算机上的 Cloud Shell 中创建文件。For example, create the file in the Cloud Shell not on your local machine. 输入 sensible-editor cloud-init-jenkins.txt 以创建文件并查看可用编辑器的列表。Enter sensible-editor cloud-init-jenkins.txt to create the file and see a list of available editors. 请确保已正确复制整个 cloud-init 文件,尤其是第一行:Make sure that the whole cloud-init file is copied correctly, especially the first line:

#cloud-config
package_upgrade: true
write_files:
  - path: /etc/systemd/system/docker.service.d/docker.conf
    content: |
      [Service]
        ExecStart=
        ExecStart=/usr/bin/dockerd
  - path: /etc/docker/daemon.json
    content: |
      {
        "hosts": ["fd://","tcp://127.0.0.1:2375"]
      }
runcmd:
  - wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add -
  - sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
  - apt-get update && apt-get install jenkins -y
  - curl -sSL https://get.docker.com/ | sh
  - usermod -aG docker azureuser
  - usermod -aG docker jenkins
  - service jenkins restart

使用 az group create 创建资源组,才能创建 VM。Before you can create a VM, create a resource group with az group create. 以下示例在 eastus 位置创建名为 myResourceGroupJenkins 的资源组。The following example creates a resource group named myResourceGroupJenkins in the eastus location:

az group create --name myResourceGroupJenkins --location eastus

现使用 az vm create 创建 VM。Now create a VM with az vm create. 使用 --custom-data 参数传递到 cloud-init 配置文件中。Use the --custom-data parameter to pass in your cloud-init config file. 如果已将 cloud-init-jenkins.txt 文件保存在现有工作目录的外部,请提供该文件的完整路径。Provide the full path to cloud-init-jenkins.txt if you saved the file outside of your present working directory.

az vm create --resource-group myResourceGroupJenkins \
    --name myVM \
    --image UbuntuLTS \
    --admin-username azureuser \
    --generate-ssh-keys \
    --custom-data cloud-init-jenkins.txt

创建并配置 VM 需要几分钟的时间。It takes a few minutes for the VM to be created and configured.

若要允许 Web 流量抵达 VM,请使用 az vm open-port 为 Jenkins 流量打开端口 8080,并为用于运行示例应用的 Node.js 应用打开端口 1337To allow web traffic to reach your VM, use az vm open-port to open port 8080 for Jenkins traffic and port 1337 for the Node.js app that is used to run a sample app:

az vm open-port --resource-group myResourceGroupJenkins --name myVM --port 8080 --priority 1001
az vm open-port --resource-group myResourceGroupJenkins --name myVM --port 1337 --priority 1002

配置 JenkinsConfigure Jenkins

若要访问 Jenkins 实例,请获取 VM 的公共 IP 地址:To access your Jenkins instance, obtain the public IP address of your VM:

az vm show --resource-group myResourceGroupJenkins --name myVM -d --query [publicIps] --o tsv

出于安全考虑,需要输入 VM 上某个文本文件中存储的初始管理员密码来启动 Jenkins 安装。For security purposes, you need to enter the initial admin password that is stored in a text file on your VM to start the Jenkins install. 使用上一步骤中获取的公共 IP 地址通过 SSH 连接到 VM:Use the public IP address obtained in the previous step to SSH to your VM:

ssh azureuser@<publicIps>

查看并复制 Jenkins 安装程序的 initialAdminPasswordView the initialAdminPassword for your Jenkins install and copy it:

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

如果文件尚不可用,请再等待几分钟,以便 cloud-init 完成 Jenkins 和 Docker 安装。If the file isn't available yet, wait a couple more minutes for cloud-init to complete the Jenkins and Docker install.

现在,请打开 Web 浏览器并转到 http://<publicIps>:8080Now open a web browser and go to http://<publicIps>:8080. 按如下所示完成初始 Jenkins 安装:Complete the initial Jenkins setup as follows:

  • 输入在上一步骤从 VM 获取的 initialAdminPasswordEnter the initialAdminPassword obtained from the VM in the previous step.
  • 选择“选择要安装的插件”Choose Select plugins to install
  • 在顶部文本框中搜索 GitHub,选择“GitHub 插件”,然后选择“安装”Search for GitHub in the text box across the top, select the GitHub plugin, then select Install
  • 若要创建 Jenkins 用户帐户,请根据需要填写表单。To create a Jenkins user account, fill out the form as desired. 从安全角度讲,应该创建这第一个 Jenkins 用户,而不要继续使用默认管理员帐户。From a security perspective, you should create this first Jenkins user rather than continuing as the default admin account.
  • 完成后,选择“开始使用 Jenkins”When finished, select Start using Jenkins

创建 GitHub WebhookCreate GitHub webhook

若要配置与 GitHub 的集成,请从 Azure 示例存储库中打开 Node.js Hello World 示例应用To configure the integration with GitHub, open the Node.js Hello World sample app from the Azure samples repo. 若要将存储库分叉到自己的 GitHub 帐户,请选择右上角的“分叉”按钮。To fork the repo to your own GitHub account, select the Fork button in the top right-hand corner.

在创建的分叉中创建 Webhook:Create a webhook inside the fork you created:

  • 选择“设置”,然后在左侧选择“集成和服务”。Select Settings, then select Integrations & services on the left-hand side.
  • 选择“添加服务”,并在筛选框中输入 Jenkins。Choose Add service, then enter Jenkins in filter box.
  • 选择“Jenkins (GitHub 插件)”Select Jenkins (GitHub plugin)
  • 对于“Jenkins 挂钩 URL”,请输入 http://<publicIps>:8080/github-webhook/For the Jenkins hook URL, enter http://<publicIps>:8080/github-webhook/. 请确保包含尾部的 /Make sure you include the trailing /
  • 选择“添加服务”Select Add service

将 GitHub Webhook 添加到分叉的存储库

创建 Jenkins 作业Create Jenkins job

若要让 Jenkins 对 GitHub 中的事件(例如提交代码)做出响应,请创建 Jenkins 作业。To have Jenkins respond to an event in GitHub such as committing code, create a Jenkins job.

在 Jenkins 网站中的主页上,选择“创建新作业”:In your Jenkins website, select Create new jobs from the home page:

  • 输入 HelloWorld 作为作业名称。Enter HelloWorld as job name. 选择“自由风格项目”,然后选择“确定”。Choose Freestyle project, then select OK.
  • 在“常规”部分下面,选择“GitHub”项目并输入分叉的存储库的 URL,例如 https://github.com/iainfoulds/nodejs-docs-hello-worldUnder the General section, select GitHub project and enter your forked repo URL, such as https://github.com/iainfoulds/nodejs-docs-hello-world
  • 在“源代码管理”部分下面,选择“Git”并输入分叉的存储库 .git 的 URL,例如 https://github.com/iainfoulds/nodejs-docs-hello-world.gitUnder the Source code management section, select Git, enter your forked repo .git URL, such as https://github.com/iainfoulds/nodejs-docs-hello-world.git
  • 在“生成触发器”部分下面,选择“用于 GITscm 轮询的 GitHub 挂钩触发器”。Under the Build Triggers section, select GitHub hook trigger for GITscm polling.
  • 在“生成”部分下面,选择“添加生成步骤”。Under the Build section, choose Add build step. 选择“执行 shell”,并在命令窗口中输入 echo "Testing"Select Execute shell, then enter echo "Testing" in to command window.
  • 选择作业窗口底部的“保存”。Select Save at the bottom of the jobs window.

测试 GitHub 集成Test GitHub integration

若要测试 GitHub 与 Jenkins 的集成,请提交分叉中的更改。To test the GitHub integration with Jenkins, commit a change in your fork.

返回到 GitHub Web UI,选择分叉的存储库,然后选择“index.js”文件。Back in GitHub web UI, select your forked repo, and then select the index.js file. 选择铅笔图标编辑该文件,使第 6 行的内容如下:Select the pencil icon to edit this file so line 6 reads:

response.end("Hello World!");

若要提交更改,请选择底部的“提交更改”按钮。To commit your changes, select the Commit changes button at the bottom.

在 Jenkins 中,作业页左下角的“生成历史记录”部分下面启动了一个新的生成。In Jenkins, a new build starts under the Build history section of the bottom left-hand corner of your job page. 选择生成号链接,并选择左侧的“控制台输出”。Choose the build number link and select Console output on the left-hand size. 从 GitHub 提取代码以及生成操作将消息 Testing 输出到控制台时,可以查看 Jenkins 执行的步骤。You can view the steps Jenkins takes as your code is pulled from GitHub and the build action outputs the message Testing to the console. 每次在 GitHub 中提交内容时,Webhook 以此方式访问 Jenkins 并触发新的生成。Each time a commit is made in GitHub, the webhook reaches out to Jenkins and trigger a new build in this way.

定义 Docker 生成映像Define Docker build image

为了查看基于 GitHub 提交内容运行的 Node.js 应用,让我们生成一个 Docker 映像用于运行该应用。To see the Node.js app running based on your GitHub commits, lets build a Docker image to run the app. 该映像是从定义如何配置运行应用的容器的 Dockerfile 生成的。The image is built from a Dockerfile that defines how to configure the container that runs the app.

通过 SSH 连接到 VM 后,请切换到根据上一步骤创建的作业命名的 Jenkins 工作区目录。From the SSH connection to your VM, change to the Jenkins workspace directory named after the job you created in a previous step. 在本示例中,该目录名为 HelloWorldIn our example, that was named HelloWorld.

cd /var/lib/jenkins/workspace/HelloWorld

在此工作区目录中创建包含 sudo sensible-editor Dockerfile 的文件并粘贴以下内容。Create a file with in this workspace directory with sudo sensible-editor Dockerfile and paste the following contents. 请确保已正确复制整个 Dockerfile,尤其是第一行:Make sure that the whole Dockerfile is copied correctly, especially the first line:

FROM node:alpine

EXPOSE 1337

WORKDIR /var/www
COPY package.json /var/www/
RUN npm install
COPY index.js /var/www/

此 Dockerfile 使用基本 Node.js 映像(该映像使用 Alpine Linux),公开运行 Hello World 应用的端口 1337,复制应用文件并初始化应用。This Dockerfile uses the base Node.js image using Alpine Linux, exposes port 1337 that the Hello World app runs on, then copies the app files and initializes it.

创建 Jenkins 生成规则Create Jenkins build rules

在上一步骤中,已创建一个可将消息输出到控制台的基本 Jenkins 生成规则。In a previous step, you created a basic Jenkins build rule that output a message to the console. 让我们创建生成步骤以使用 Dockerfile 并运行应用。Lets create the build step to use our Dockerfile and run the app.

返回到 Jenkins 实例,选择上一步骤创建的作业。Back in your Jenkins instance, select the job you created in a previous step. 选择左侧的“配置”,并向下滚动到“生成”部分:Select Configure on the left-hand side and scroll down to the Build section:

  • 删除现有的 echo "Test" 生成步骤。Remove your existing echo "Test" build step. 选择现有生成步骤框右上角的红叉。Select the red cross on the top right-hand corner of the existing build step box.
  • 选择“添加生成步骤”,然后选择“执行 shell”Choose Add build step, then select Execute shell
  • 在“命令”框中输入以下 Docker 命令,然后选择“保存”:In the Command box, enter the following Docker commands, then select Save:

    docker build --tag helloworld:$BUILD_NUMBER .
    docker stop helloworld && docker rm helloworld
    docker run --name helloworld -p 1337:1337 helloworld:$BUILD_NUMBER node /var/www/index.js &
    

Docker 生成步骤将创建一个映像,并使用 Jenkins 生成编号对其进行标记,以便可以维护映像的历史记录。The Docker build steps create an image and tag it with the Jenkins build number so you can maintain a history of images. 运行应用的任何现有容器会停止,随后被删除。Any existing containers running the app are stopped and then removed. 然后,将使用该映像启动新的容器,并基于 GitHub 中的最新提交内容运行 Node.js 应用。A new container is then started using the image and runs your Node.js app based on the latest commits in GitHub.

测试管道Test your pipeline

若要查看整个管道的工作状况,请再次在分叉的 GitHub 存储库中编辑 index.js 文件,并选择“提交更改”。To see the whole pipeline in action, edit the index.js file in your forked GitHub repo again and select Commit change. 会基于 GitHub 的 Webhook 在 Jenkins 中启动新作业。A new job starts in Jenkins based on the webhook for GitHub. 创建 Docker 映像并在新容器中启动应用需要几秒钟时间。It takes a few seconds to create the Docker image and start your app in a new container.

如果需要,请再次获取 VM 的公共 IP 地址:If needed, obtain the public IP address of your VM again:

az vm show --resource-group myResourceGroupJenkins --name myVM -d --query [publicIps] --o tsv

打开 Web 浏览器并输入 http://<publicIps>:1337Open a web browser and enter http://<publicIps>:1337. 将显示 Node.js 应用,其中反映了 GitHub 分叉中的最新提交内容,如下所示:Your Node.js app is displayed and reflects the latest commits in your GitHub fork as follows:

运行 Node.js 应用

现在,请再次在 GitHub 中编辑 index.js,并提交更改。Now make another edit to the index.js file in GitHub and commit the change. 等待几秒钟让作业在 Jenkins 中完成,并刷新 Web 浏览器查看新容器中运行的应用的更新版本,如下所示:Wait a few seconds for the job to complete in Jenkins, then refresh your web browser to see the updated version of your app running in a new container as follows:

在 GitHub 中再次提交更改后运行 Node.js 应用

后续步骤Next steps

在本教程中,已将 GitHub 配置为每次提交代码后运行 Jenkins 生成作业,然后部署了一个 Docker 容器用于测试应用。In this tutorial, you configured GitHub to run a Jenkins build job on each code commit and then deploy a Docker container to test your app. 你已了解如何:You learned how to:

  • 创建 Jenkins VMCreate a Jenkins VM
  • 安装并配置 JenkinsInstall and configure Jenkins
  • 创建 GitHub 与 Jenkins 之间的 Webhook 集成Create webhook integration between GitHub and Jenkins
  • 通过 GitHub 提交创建并触发 Jenkins 生成作业Create and trigger Jenkins build jobs from GitHub commits
  • 创建应用的 Docker 映像Create a Docker image for your app
  • 验证 GitHub 提交是否生成新的 Docker 映像并更新正在运行的应用Verify GitHub commits build new Docker image and updates running app

转到下一教程,详细了解如何将 Jenkins 与 Visual Studio Team Services 集成。Advance to the next tutorial to learn more about how to integrate Jenkins with Visual Studio Team Services.