TFS持续集成容器化讨论

在TFS中工具中如何通过容器化来精简我们的持续集成过程,以及相关的实现方式

0
2923

简介

容器化已经深入到了当前软件研发中的很多过程中,它使我们的开发部署更加精简与高效。这里小编想探讨一下在TFS中工具中如何通过容器化来精简我们的持续集成过程,以及相关的实现方式。

 

作者:薄涛
LEANSOFT咨询服务总监,认证 Scrum Master,曾为多个行业的100多家客户实施过微软Team Foundation Server,包括:中国农业银行,兴业银行,中关村银行,华为,上海通用,上海汇众,百威英博,斯伦贝谢,世纪互联,金士顿(台湾)等。

借助Docker可以帮助我们快速实现持续集成的标准化。基于TFS当前版本的生成机制,我们可以实现下面两种持续集成的容器化管理。

  1. 持续集成过程容器化:使用Docker运行应用的构建、测试与发布。
  2. 生成代理容器化:使用容器运行TFS代理,然后在容器中运行持续集成。

持续集成过程容器化

在当前的TFS生成运行机制下,小编比较推荐这种方式,因为我们可以在现有条件下最大限度的将持续过程模板化,所有的生成过程全部在Dockerfile或者Docker-compose.yaml中定义,这样依赖什么样的生成环境,构建与测试的过程可与全部由开发人员自行控制,其实也是变相的实现了Jenkins Pipeline的部分功能。这种实现方式大家可以在我们公众号之前的文章《使用TFS玩转Docker自动化部署》一文中查看详细内容。

生成代理容器化

种种方式较之上一种的唯一区别就是将代理放到容器中运行。微软官方提供了镜像https://hub.docker.com/r/microsoft/vsts-agent/ 。微软提供了很多镜像版本给我们使用,我们可以根据自己的需要可以获取不同的镜像版本运行代理。

这里举例说明镜像如何根据需求选取不同的镜像,如:ubuntu-16.04-tfs-2018-u2-docker-17.12.0-ce-standard

ubuntu-16.04指的是基础镜像使用的是ubuntu系统的16.04版本;

tfs-2018-u2指的是此镜像适用于tfs2018 update 2,其实这里最主要的区别在于镜像中安装的TFS代理版本,你可以通过修改Dockerfile文件来配置镜像中的代理版本,下面我们会详细的讲如何自定义生成代理镜像。注意:如果标签中不包含tfs,镜像中是没有安装VSTS代理的。

docker-17.12.0-ce指的是在镜像中安装的docker版本,你可以在类似ubuntu-16.04-docker-17.12.0-ce-standard标签的Dockerfile中修改docker版本,在镜像中安装自己需要的Docker版本。

standard是用来区分基础镜像中安装的依赖的,没有standard的镜像版本中是不安装任何依赖的,需要我们自己修改Dockerfile安装需要的依赖,包含standard的镜像版本中预制安装了很多的依赖,如:基础命令行工具(curl,ftp等等),JDK,Java生成工具,Node.js等依赖,这个镜像有4GB大小。

自定义生成代理镜像

我们基于标签ubuntu-16.04-tfs-2018-u2-docker-17.12.0-ce-standardubuntu-16.04-docker-17.12.0-ce-standard的Dockerfile生成我们需要的镜像,首先在github上获取所有VSTS代理镜像文件,运行下面的命令:

git clone https://github.com/Microsoft/vsts-agent-docker.git

git repo中的目录组织结构和标签是对应的,我们根据标签找到ubuntu-16.04-tfs-2018-u2-docker-17.12.0-ce-standard的Dockerfile

此镜像依赖于ubuntu-16.04-docker-17.12.0-ce-standard镜像,可以在此镜像的Dockerfile中修改Docker版本,ubuntu-16.04-docker-17.12.0-ce-standard镜像依赖于ubuntu-16.04-standard镜像,可以在此镜像的Dockerfile中修改需要安装的依赖。 这里我们不修改基础依赖镜像,只修改VSTS代理版本。

修改后我们在本地使用Docker build命令生成新的docker镜像

#打开Dockerfile所在目录
cd ~/vsts-agent-docker/ubuntu/16.04/tfs/2018-u2/docker/17.12.0-ce/standard
#生成容器镜像
docker build -t vsts-agent:ubuntu-16.04-tfs-2018-u2-140-docker-17.12.0-ce-standard .

启动代理,并对代理进行配置:

docker run \
 -e TFS_URL=<tfs的服务器url> \
 -e VSTS_ACCOUNT=<TFS生成运行账户> \
 -e VSTS_TOKEN=<在 TFS | 个人设置 | 安全 中生成的Token> \
 -e VSTS_AGENT='$(hostname)-agent' \
 -e VSTS_POOL=<代理池名称> \
 -e VSTS_WORK='/var/vsts/$VSTS_AGENT' \
 -v /var/vsts:/var/vsts \
 -it vsts-agent:ubuntu-16.04-tfs-2018-u2-140-docker-17.12.0-ce-standard

运行后可以看到代理正在执行,并且在TFS中代理已经注册

但是这里大家会发现一个问题,在这个镜像中我们只能使用PAT方式注册代理,而PAT要求TFS服务器必须为HTTPS形式,但是因为很多人的TFS只部署在公司内部,因此没有配置HTTPS,那么我就需要修改agent的启动配置脚本,以支持Negotiate的方式连接TFS。

在与Dockerfile同级目录中还有一个start.sh文件,我们需要修改此文件。

首先,将对VSTS TOKEN的验证注释掉:

# if [ -z "$VSTS_TOKEN_FILE" ]; then
#   if [ -z "$VSTS_TOKEN" ]; then
#     echo 1>&2 error: missing VSTS_TOKEN environment variable
#     exit 1
#   fi
#   VSTS_TOKEN_FILE=/vsts/.token
#   echo -n $VSTS_TOKEN > "$VSTS_TOKEN_FILE"
# fi
# unset VSTS_TOKEN

然后修改代理启动配置

./bin/Agent.Listener configure --unattended \
--agent "${VSTS_AGENT:-$(hostname)}" \
--url "$TFS_URL" \
--auth Negotiate \
--username "$VSTS_User" \
--password "$VSTS_PWD" \
--pool "${VSTS_POOL:-Default}" \
--work "${VSTS_WORK:-_work}" \
--replace & wait $!

启动代理,并对代理进行配置:

docker run \
 -e TFS_URL=<tfs的服务器url> \
 -e VSTS_User=<TFS生成运行账户> \ 
 -e VSTS_PWD=<TFS生成运行账户密码> \
 -e VSTS_AGENT='$(hostname)-agent' \
 -e VSTS_POOL=<代理池名称> \
 -e VSTS_WORK='/var/vsts/$VSTS_AGENT' \
 -v /var/vsts:/var/vsts \
 -it vsts-agent:ubuntu-16.04-tfs-2018-u2-140-docker-17.12.0-ce-standard-nego

注意:输入VSTS_User参数时不要加入域名,比如你的TFS账户为leansoft\botao,这里只写botao就好了,要不然会报授权的错误。

小结

当选用容器化生成代理进行管理时,由于容器自身的特性会导致当容器销毁后TFS的代理记录不会自动删除的问题,这个需要我们手动处理,或者自己写批处理脚本根据容器的健康状况维护代理。

当然我们也希望在不久的将来TFS可以实现当有生成请求时,自动激活并配置代理,并且在代理上的生成执行完毕后自动注销代理,这样我们就可以直接将代理容器托管到容器编排平台,进一步提高生成环境资源的利用率并减少对代理的维护操作。