本篇教程主要讲解基于容器服务搭建TeamCity服务,并且完成内部项目的CI流程配置。教程中也分享了一个简单的CI、CD流程,仅作探讨。不过由于篇幅有限,完整的DevOps,我们后续独立探讨。

为了降低容器的使用门槛以及便于大家将容器技术应用于开发和实践,当前教程大部分线上实践结合TKE(腾讯云容器服务)来进行讲解和实践。当本系列内容讲解完成后,笔者将再单独讲解Kubernetes(k8s)。

最后,长沙技术社区第一次线下交流会将在2019年3月10日下午2点开始,有兴趣的朋友可以参与交流。名额有限,详见《长沙.NET技术社区活动通知》。

目录

  • 使用TeamCity来完成内部CI、CD流程1

  • 一个简单的CI、CD流程1

  • 关于TeamCity2

  • 官方镜像4

  • 使用腾讯云容器服务(TKV)搭建和托管TeamCity4

  • 创建TeamCity Server容器服务4

  • 创建Teamcity Agent代理服务7

  • 连接和配置Agent9

  • 创建项目以及配置CI10

使用TeamCity来完成内部CI、CD流程

本篇教程主要讲解基于容器服务搭建TeamCity服务,并且完成内部项目的CI流程配置。至于完整的DevOps,我们后续独立探讨。

一个简单的CI、CD流程

以下分享一个简单的CI、CD流程(仅供参考):

 

注意

本流程需要使用git进行代码版本管理,推荐使用TFS搭建自己的代码版本库。自动部署推荐使用腾讯云镜像触发器实现,此步骤也可以使用脚本实现,如果是普通的.NET代码,推荐编写webdeploy命令脚本来完成自动部署。通知推荐大家使用钉钉机器人。

本流程仅作参考,后续笔者会独立一篇来讲解整个DevOps流程,以及项目(产品)渠道消息集成这块,这里仅作抛砖引玉,同时大家也可以更易于理解,容器技术大大简化CI、CD流程!

 

关于TeamCity

TeamCity是一款成熟的CI服务器,来自JetBrains公司。JetBrains已经在软件开发世界中建立了权威,他们的工具如WebStorm和ReSharper正被全球的开发者所使用。

TeamCity在它的免费版本中提供了所有功能,但仅限于20个配置和3个构建代理。额外的构建代理和构建配置需要购买,你可以在这里找到价格。

TeamCity安装后即可使用,可以在多种不同的平台上工作,并支持各种各样的工具和框架。 能够支持JetBrains和第三方公司开发的公开的插件。尽管是基于Java的解决方案,TeamCity在众多的持续集成工具中提供了最好的.NET支持。TeamCity也有多种企业软件包,可以按所需代理的数量进行扩展。

TeamCity分为专业版和企业版,专业版免费,支持100个构建配置,允许完全访问产品的所有功能,足够小团队小公司来完成自己的CI流程的构建了。

下载地址:

https://www.jetbrains.com/teamcity/download/#section=section-get

TeamCity可以通过执行文件安装,也可以在Docker容器中运行。本篇教程主要讲解通过腾讯云容器服务(TKV)来搭建和托管TeamCity环境。

官方镜像

官方镜像地址:

https://hub.docker.com/r/jetbrains/teamcity-server

如果小伙伴们需要在本地测试,也可以使用以下命令在本地运行:

docker run -it --name teamcity-server-instance  \

-v <path to data directory>:/data/teamcity_server/datadir \

-v <path to logs directory>:/opt/teamcity/logs  \

-p <port on host>:8111 \

jetbrains/teamcity-server

此命令需要映射对应的数据目录和日志目录以及端口。镜像名称为jetbrains/teamcity-server。

在本地运行,我们主要用于学习和测试,接下来我们还是回到主题,继续搭建线上的TeamCity服务。

使用腾讯云容器服务(TKE)搭建和托管TeamCity

创建TeamCity Server容器服务

在TKE创建服务的部分细节在之前的教程中我们讲述过,这里主要讲解一些主要的点。由于TeamCity这边需要使用到数据卷做持久化,那么在TKE中,我们如果实现容器服务的持久化呢?

腾讯云容器服务是基于 Kubernetes 编排系统搭建的,创建服务时可以设置以下类型的数据卷:

· 本地硬盘:将容器所在宿主机的文件目录挂载到容器的指定路径中(对应Kubernetes的HostPath), 也可以不填写源路径(对应Kubernetes的EmptyDir),不填写时将分配主机的临时目录挂载到容器的挂载点,指定源路径的本地硬盘数据卷适用于将数据持久化存储到容器所在宿主机,EmptyDir适用于容器的临时存储。

· 云硬盘:腾讯云基于CBS扩展的Kubernetes的块存储插件。可以指定一块腾讯云的 CBS 云硬盘挂载到容器的某一路径下,容器的迁移,云硬盘会跟随迁移,使用云硬盘数据卷适用于数据的持久化保存,可用于Mysql等有状态服务,设置云硬盘数据卷的服务,实例数量最大为 1。

· NFS盘:可以使用腾讯云的文件存储CFS, 也可使用自建的文件存储NFS, 只需要填写NFS路径,使用NFS数据卷适用于多读多写的持久化存储,适用于大数据分析、媒体处理、内容管理等场景。

· 配置项:将配置项中指定 key 映射到容器中(key作为文件名),使用配置项数据卷主要用于业务配置文件的挂载,可以用于挂载配置文件到指定容器目录。

 

使用数据卷时有以下注意事项:

1.创建数据卷后需要设置容器的挂载点。

2.同一个服务下数据卷的名称和容器设置的挂载点不能重复。

3.本地硬盘数据卷源路径为空时,系统分配临时目录在

/var/lib/kubelet/pods/pod_name/volumes/kubernetes.io~empty-dir.

使用临时的数据卷的生命周期与实例的生命周期保持一致。

4.数据卷挂载需要设置权限,默认设置为读写权限。

了解了这些,接下来的实践我们使用本地硬盘和云硬盘来实现我们云端的数据持久化。

创建TeamCity Server容器服务主要分为以下几个步骤:

1. 创建服务,设置镜像

镜像名称为:jetbrains/teamcity-server,如下图所示(注意是直接输入):

2. 配置数据卷。

数据卷我们这里选择云硬盘,其中“vol”为硬盘命名:

这里我们需要在云硬盘控制台添加好相应的云硬盘:

3. 添加挂载点,以保存数据和日志内容,如下图所示:

其中“vol”为刚创建的数据卷名称,中间部分为容器内的路径,右侧部分为设置该路径的权限。

4. 配置端口映射

TeamCity Server的默认端口为8111,我们可以这么来配置:

如果我们需要将8111映射为80端口,我们可以这么配置:

5. 点击【创建服务】按钮,创建服务

创建完成后,可以在服务列表看到我们所创建的服务:

注意

至此,TeamCity Server服务创建完成。刚才我们在服务访问方式中选择了【提供公网访问】,TKV自动为我们创建了一个负载均衡实例,以提供外网访问。这时,我们使用IP即可访问对应的服务。

如刚创建的:

创建Teamcity Agent代理服务

Server创建好了,我们还需要创建TeamCity Build Agent来为我们构建代码。也就是构建过程还得由专门的构建代理来提供服务。

TeamCity Build Agent官方镜像地址如下:

https://hub.docker.com/r/jetbrains/teamcity-agent/

我们可以通过以下命令在本地跑起来:

docker run -it -e SERVER_URL="<url to TeamCity server>"  \

-v <path to agent config folder>:/data/teamcity_agent/conf  \

jetbrains/teamcity-agent

跑起来之后,我们需要在Server的管理中心来连接和授权。

配置特权级容器

值得注意的是,如果我们使用TeamCity的代理来构建Docker容器,那么我们势必需要使用到主机的Docker守护进程,这时,我们可以使用特权级容器来解决这个问题,如下面命令所示:

docker run -it -e SERVER_URL="<url to TeamCity server>"  \

-v <path to agent config folder>:/data/teamcity_agent/conf \

-v docker_volumes:/var/lib/docker \

--privileged -e DOCKER_IN_DOCKER=start \

jetbrains/teamcity-agent

使用privileged参数,容器内的root才拥有真正的root权限,并且Docker将允许访问主机上的所有设备,甚至允许我们在容器中启动Docker容器。接下来在腾讯云TKV这边,我们也需要使用到特权级容器,以便于我们使用TeamCity来构建Docker容器镜像,以及推送镜像。

TeamCity Agent基础镜像包括

由于在接下来的步骤中需要使用到Agent来构建代码,因此我们需要知道其包含的内容:

· ubuntu:bionic(Linux)

· microsoft / windowsservercore或microsoft / nanoserver(Windows)

· AdoptOpenJDK 8,JDK 64位

· git

· mercurial(除了nanoserver镜像)

· .NET Core SDK(可以构建.NET Core!!)

· MSBuild工具(基于windowsservercore的镜像)

· docker-engine(Linux)

创建Teamcity Agent代理服务

创建TeamCity Agent容器服务主要分为以下几个步骤:

1. 创建服务,设置镜像

镜像名称为:jetbrains/teamcity-agent,如下图所示(注意是直接输入):

2. 配置数据卷。

数据卷我们这里选择使用本地硬盘,主要是为了讲解数据卷的不同类型:

使用本地硬盘有两种形式:

· 指定源路径(HostPath),将容器所在宿主机的文件目录挂载到容器指定的挂载点中,如容器需要访问/etc/hosts则可以使用HostPath映射/etc/hosts等场景。

· 空的源路径(EmptyDir),用于容器的数据的临时存储,如基于磁盘的排序场景等。

也就是我们留空也可以。

3. 添加挂载点,以保存数据,如下图所示:

其中“vol”、“dockervol”为刚创建的数据卷名称,中间部分为容器内的路径,右侧部分为设置该路径的权限。

4. 配置环境变量

如下图所示,我们还需配置以下环境变量:

AGENT_NAME

代理实例名称(授权时会显示)

SERVER_URL

服务端UI

DOCKER_IN_DOCKER

Docker内部启动Docker

5. 配置特权级容器

此选项在TKV容器服务的高级设置中,如图所示:

6. 配置端口映射

这里我们无需提供公网访问,因此选择【仅在集群内访问】即可。端口映射这块,Agent的默认端口为9090。

7. 点击【创建服务】按钮,创建服务

创建完成后,可以在服务列表看到我们所创建的服务:

连接和配置Agent

Server和Agent配置完成后,我们可以访问Server站点,完成初始化工作。然后,我们需要配置好Agent。

打开Agents界面,可以看到我们刚创建的Agent:

这时,我们需要先进行授权,也就是打开【Unauthorized】面板,点击【Authorize】按钮:

授权成功后,我们就可以看见已连接的代理了:

接下来,才可以开始搞事情。

创建项目以及配置CI

项目创建界面如下所示:

推荐大家使用git来管理自己的代码。这里我们可以添加我们的代码仓库地址,如果是私有库,还需要配置账号密码。简单步骤我们这里略过,然后接下来TeamCity会扫描源代码,来提供推荐的构建步骤:

这里我们可以勾选我们需要的步骤,或者自己来创建符合自己需要的步骤。

注意:使用Docker托管的Agent服务镜像并不支持PowellShell。如果选择了不支持的步骤,将无法使用刚才我们创建的Agent执行代码构建。

这里,我们可以添加几个简单的步骤:

步骤1、2使用Docker构建Docker镜像,相关参考界面如下所示:

步骤3则使用CMD命令发送钉钉消息,以通知团队:

通知结果如下图所示:

接下来,我们就可以配置触发器、失败条件判断以及参数等其他配置。整个构建步骤配置起来非常简单,大家也可以结合我之前的CI教程来完善配置,比如添加对镜像推送的步骤等。

完成之后,我们就可以尝试着运行构建,并且查看构建历史:

整个构建详情我们也可以直接查看:

包括构建日志:

在这个过程中,可能大家需要用到一些构建参数、环境变量等等,我们可以打开对应agent的Agent Parameters面板来查看详情:

Docker最全教程之使用TeamCity来完成内部CI、CD流程(十六)的更多相关文章

  1. Docker最全教程之使用Tencent Hub来完成CI(九)

    使用Tencent Hub来完成CI 关于Tencent Hub Tencent Hub是腾讯出品的DevOps服务.主要提供多存储格式的版本管理,支持Docker Image.Binary.Helm ...

  2. Docker最全教程

    摘自雪雁大佬的博客,地址:https://www.cnblogs.com/codelove/default.html 目录: Docker最全教程——从理论到实战(一) Docker最全教程——从理论 ...

  3. Docker最全教程之使用Node.js搭建团队技术文档站(二十三)

    前言 各种编程语言均有其优势和生态,有兴趣的朋友完全可以涉猎多门语言.在平常的工作之中,也可以尝试选择相对适合的编程语言来完成相关的工作. 在团队技术文档站搭建这块,笔者尝试了许多框架,最终还是选择了 ...

  4. Docker最全教程——从理论到实战(七)

    在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解知识点而进行讲解.也就是说,笔者希望能够让大家将理论.知识.思想和指导应用到工作的实际场景和实 ...

  5. Docker最全教程——从理论到实战(五)

    往期内容链接 Docker最全教程——从理论到实战(一) Docker最全教程——从理论到实战(二) Docker最全教程——从理论到实战(三) Docker最全教程——从理论到实战(四) 本篇教程持 ...

  6. Docker最全教程——从理论到实战(八)

    在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解知识点而进行讲解.也就是说,笔者希望能够让大家将理论.知识.思想和指导应用到工作的实际场景和实 ...

  7. Docker最全教程——从理论到实战(六)

    托管到腾讯云容器服务 托管到腾讯云容器服务,我们的公众号“magiccodes”已经发布了相关的录屏教程,大家可以结合本篇教程一起查阅.   自建还是托管? 在开始之前,我们先来讨论一个问题——是自建 ...

  8. Docker最全教程——从理论到实战

    Docker最全教程——从理论到实战(一) Docker最全教程——从理论到实战(二) Docker最全教程——从理论到实战(三) Docker最全教程——从理论到实战(四) Docker最全教程—— ...

  9. Docker最全教程——从理论到实战(十四)

    本篇教程主要讲解基于容器服务搭建TeamCity服务,并且完成内部项目的CI流程配置.教程中也分享了一个简单的CI.CD流程,仅作探讨.不过由于篇幅有限,完整的DevOps,我们后续独立探讨. 为了降 ...

随机推荐

  1. NGINX按天生成日志文件的简易配置

    NGINX按天生成日志文件的简易配置 0x01 最近后端童鞋遇到一个小需求,拆分nginx生成的log文件,最好是按天生成,看着她还有很多bug待改的状态,我说这个简单啊,我来吧.曾经搞node后端的 ...

  2. 智能指针之 shared_ptr

     std::shared_ptr 是通过指针保持对象共享所有权的智能指针.多个 shared_ptr 对象可占有同一对象大概实现了一下,主要实现原理为,共享指针内部持有堆资源 的指针以及引用计数的指针 ...

  3. jmeter接口测试报java.net.SocketException: Socket closed错误。

    如题,jmeter报出java.net.SocketException: Socket closed,我查询了下,服务器是正常的,可以返回数据,基本确定问题出在我这边jmeter.查询原因,看到有人说 ...

  4. apache2.4 虚拟主机配置

    网上教程很多,仅记录我的配置,可供参考 一.修改httpd.conf 打开appserv的安装目录,找到httpd.conf文件,分别去掉下面两行文字前面的#号. #LoadModule vhost_ ...

  5. Spring Cloud Sleuth服务链路追踪(zipkin)(转)

    这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件. 一.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案, ...

  6. java.util.BitSet 详细分析 学习笔记

    1,BitSet类    大小可动态改变, 取值为true或false的位集合.用于表示一组布尔标志.   此类实现了一个按需增长的位向量.位 set 的每个组件都有一个 boolean 值.用非负的 ...

  7. 在VirtualBox中安装BlackArch Linux

    作者:荒原之梦 安装前的准备 下载系统映像:BlackArch Linux官网下载页面 在本文中我使用的是BlackArch Linux的Live ISO,这样可以减少安装时下载系统的时间.Black ...

  8. 剑指Offer常见问题整理

    1 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.(来自牛客网,剑指offer) ...

  9. SpringData ES中一些底层原理的分析

    之前写过一篇SpringData ES 关于字段名和索引中的列名字不一致导致的查询问题,顺便深入学习下Spring Data Elasticsearch. Spring Data Elasticsea ...

  10. Python3 randrange() 函数

    描述 randrange() 方法返回指定递增基数集合中的一个随机数,基数缺省值为1. 语法 以下是 randrange() 方法的语法: import random random.randrange ...