文章导读
- 本文仅代表作者的个人观点;
- 本文的内容仅限于技术探讨,不能作为指导生产环境的素材;
- 本文素材是红帽公司产品技术和手册;
一、CI/CD手下的开源界六大金刚
使用全开源软件,打通CI/CD流程,需要以下六大金刚:
Openshift:PaaS解决方案
Gogs: Go写的本地github
Jenkins/Jenkins Slave Pods
Nexus :工件管理器,能够解决本地缓存构建依赖项。
SonarQube:开源代码分析工具,它可以分析常见编程错误的源代码
Skopeo:镜像复制工具
六大金刚协同工作图:
二、六大金刚第二位:Gogs
Gogs本质上是:用Go编写的开源的GitHub
它的特点是:
- 轻量级
- 轻松部署在OpenShift上
- 使用PostgreSQL / MySQL数据库作为后端
- 使用PVC作为存储库数据
- 最初通过Web界面配置
- 创建/etc/config/gogs/app.ini
- 需要提取并转换为ConfigMap
三、六大金刚第三位:Jenkins
Red Hat OpenShift容器平台(RHOCP)包含:
Jenkins 2 image based on Red Hat Enterprise Linux的镜像
它的特点是
- OAuth enabled
- Can turn off OAuth → admin/password
- Preconfigured with supported plug-in versions
Openshift中可以使用的Jenkins模板:
jenkins-ephemeral
jenkins-persistent
Jenkins预先配置了slave pods
- 在单独的RHOCP pod中执行构建
- 和Jenkins pod在同一个项目中
- 在Jenkins系统配置中配置为Kubernetes pods
- 不会占用Jenkins pod资源
Openshift自带的的slave pod:
- 基本从属pod用于构建自定义从属pod
- Node.js的
- Maven的
- ASP.net
- 限制/配额强制执行
构建自己的自定义Jenkins slave pod
- 基于basic slave pod image,完全自定义设置
- Maven slave pod:增强Maven构建过程
- Node.js或ASP.net从属pod
自定义slave pod流程:
1.使用Docker构建新的容器映像
2.新容器映像上载到openshift容器注册表
3.使用Jenkins注册docker image,使用label(jenkins中指定slave pod镜像时的label)与pipeline(node后面的内容)步骤相关联
四、六大金刚第四位:Nexus
Nexus是存储库工件管理器,它能够解决本地缓存构建依赖项。
它可以基于以下两种方式:
- Maven
- NPM
通常,我们在openshift集群中设置一个nexus,以便做maven构建依赖的缓存。
它可以实现:
- 快速加速Maven构建,将Nexus作为Maven代理存储库:
- 可以充当容器注册表
我们可以配置,settings.xml,将地址指向nexus的地址:
Maven使用$ HOME / .m2中的settings.xml进行pom.xml之外的配置:
Maven构建在$ HOME / .m2中查找settings.xml
五、六大金刚第五位:SonarQube
SonarQube开源代码分析工具,它可以分析常见编程错误的源代码。
可以通过Maven或Jenkins插件调用
Add to pom.xml:
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
从Maven调用SonarQube:
mvn sonar:sonar -s ./nexus_settings.xml \
-Dsonar.host.url=http://sonarqube-xyz-sonarqube.apps-na39.openshift.opentlc.com
六、六大金刚第六位:Skopeo
skopeo是命令行实用程序,对容器映像和映像存储库执行各种操作。
它不需要运行Docker守护程序来执行操作
我们使用skopeo只要从各种存储机制复制图像
示例:
- 可以将图像从一个注册表复制到另一个注册表而无需特权用户
- 检查远程图像的属性,包括图层,而不将图像拉到主机
- 从图像存储库中删除图像
- 当存储库需要时,skopeo可以传递适当的凭据和证书进行身份验证
七、实验展示:环境准备
将为持续集成和持续部署(CI / CD)的实践奠定基础。我们在以后的实验中设置构建复杂管道所需的所有工具。 构建过程集成了Gogs,Nexus,SonarQube和S2I构建。
实验目标
- 使用持久存储设置Nexus 3并配置Nexus以缓存Red Hat和其他构建工件。
- 设置具有持久存储的SonarQube和PostgreSQL作为后端。
- 设置具有持久存储的Gogs和PostgreSQL作为后端。
- 使用持久存储设置Jenkins。
- 执行本地工作站构建,以测试是否已正确设置和配置所有工具。
步骤1:设置Nexus
Sonatype提供了一个标记为sonatype / nexus3的Nexus 3映像:DockerHub中的最新版本。
使用重新创建部署策略而不是滚动来设置Nexus。
Nexus需要大量内存。 将内存请求设置为1Gi,将内存限制设置为2Gi。
Nexus 3 image在/ nexus-data处定义了VOLUME。
部署Nexus容器映像并创建到Nexus服务的路由。 由于对部署配置进行了一些更改:
oc new-app sonatype/nexus3:latest
oc expose svc nexus3
oc rollout pause dc nexus3
将部署策略从Rolling更改为Recreate,并设置内存请求和限制。
oc patch dc nexus3 --patch='{ "spec": { "strategy": { "type": "Recreate" }}}'
oc set resources dc nexus3 --limits=memory=2Gi --requests=memory=1Gi
创建持久卷声明(PVC)并将其挂载到/ nexus-data。
为Nexus设置探针:
重新触发dc:
oc rollout resume dc nexus3
nexus3部署成功:
部署Nexus后,使用提供的脚本设置Nexus存储库。 使用Nexus 3默认用户ID(admin)和密码(admin123)。
执行脚本,完成如下工作:
- 一些Maven代理存储库用于缓存Red Hat和JBoss依赖项。
- 一个maven-all-public组存储库,包含所有必需工件的代理存储库。
- 用于缓存Node.JS构建工件的NPM代理存储库。
- 私有Docker注册表。
- 释放管道生成的WAR文件的存储库。
- Nexus中的Docker注册表在端口5000上侦听.OpenShift不知道这个额外的端点,因此需要创建一个公开Nexus Docker注册表以供使用的其他路由。
- 创建名为nexus-registry的服务,该服务从部署配置nexus3公开端口5000。
- 创建名为nexus-registry的OpenShift路由,该路由使用边缘终止进行TLS加密并公开端口5000。
步骤2:设置SonarQube
首先为SonarQube部署持久的PostgreSQL数据库。
部署模板时,请为POSTGRESQL_USER,POSTGRESQL_PASSWORD,POSTGRESQL_DATABASE和VOLUME_CAPACITY参数选择合理的值。
确保数据库成功部署并启动:
部署DockerHub中提供的SonarQube映像(wkulhanek / sonarqube:6.7.4)。
该图像需要环境中的SONARQUBE_JDBC_USERNAME,SONARQUBE_JDBC_PASSWORD和SONARQUBE_JDBC_URL。
SONARQUBE_JDBC_URL的正确设置是SONARQUBE_JDBC_URL = jdbc:postgresql:// postgresql / <dbname>其中“<dbname>”是我们在设置PostgreSQL时选择的名称。
暂停已创建的SonarQube部署配置的推出,以便可以对部署配置进行一些更改。
创建一个PVC并将其挂载在/ opt / sonarqube / data。
SonarQube是一个繁重的应用程序。 建议使用以下参数:
内存请求:1.5Gi
内存限制:3Gi
CPU请求:1个CPU
CPU限制:2个CPU
设置部署策略。
由于SonarQube使用Elasticsearch,因此需要重新创建部署策略而不是默认的Rolling部署策略。
为了确保服务正常运行,增加探针:
最后,恢复部署SonarQube dc以立即进行部署。
一旦SonarQube完全启动,请通过暴露的路由登录。 默认用户ID为admin
步骤3:设置Gogs
Gogs是一个开源的GitHub克隆,可以部署在本地基础架构中。 它需要具有持久存储的PostgreSQL或MySQL数据库以及存储其自身数据的持久卷。
Gogs的独特之处在于它必须在部署后进行配置。 必须配置数据库连接以及其他设置。
Gogs将配置写入本地容器上的文件。 由于容器是短暂的,因此每次重新部署运行此Gogs容器的pod时,Gogs容器都会丢失此配置。 为了防止这种情况,需要将配置文件保存在持久存储中,ConfigMap是一个很好的解决方案。
使用持久存储部署PostgreSQL数据库服务器。
OpenShift中有一个postgresql-persistent模板。
确保在部署模板时添加PostgreSQL用户ID,密码和数据库名称。
为gogs部署prostgres数据库:
部署Gogs服务器。
为Gog添加持久存储并将其附加到/data。
将服务公开为路由并检索生成的路由。
在Web浏览器中,安装gogs
参数配置如下:
安装成功以后,注册用户,创建库:
从Gogs窗格中检索配置文件并将其存储在$ HOME目录中。
配置文件在容器中的位置是
/opt/gogs/custom/conf/app.ini
.
使用Gogs配置文件创建ConfigMap。
更新Gogs部署配置以将ConfigMap作为卷安装在/ opt / gogs / custom / conf中。
等到重新部署完成,然后导航回Gogs主页
注册新用户 - 第一个注册用户成为Gogs的管理员。
以您刚注册的用户身份登录Gogs。
登录成功:
将openshift-tasks源代码安装到Gogs中
登录Gogs并创建一个名为CICDLabs的组织。
在CICDLabs组织下,创建一个名为openshift-tasks的存储库。
不要将其设为私有存储库。
在客户端VM上,从GitHub克隆源代码并将其推送到Gogs:
确保使用您的凭据替换<gogs_user>和<gogs_password>。
为本地构建设置nexus_settings.xml,确保<url>指向您的特定Nexus URL:
提交并将更新的设置文件推送到Gogs:
git commit -m "Updated Settings" nexus_settings.xml nexus_openshift_settings.xml
git push gogs master
步骤4:设置Jenkins
设置具有2 GB内存和持久卷声明为4 GB的持久性Jenkins实例。
编辑Jenkins从属pod配置以允许Maven从属pod在构建JEE应用程序时消耗2Gi内存。
创建自定义Jenkins Slave Pod
库存Jenkins Maven slave pod没有安装skopeo。 但是,您需要skopeo才能将构建的容器映像移动到另一个注册表中。 这意味着您需要构建自定义从属pod。 您只需扩展现有的从属pod并将skopeo安装到该pod中。 然后,您需要将此容器图像推送到OpenShift容器注册表中,以使其可用于OpenShift。 因为您自己构建此映像,所以您可以使用当前的Jenkins项目(xyz-jenkins)作为容器映像的主页。
您的堡垒主机已安装Docker。 但是因为您的群集中没有真正的证书,所以Docker注册表是一个不安全的注册表。 这意味着您需要配置本地Docker守护程序以允许连接到OpenShift Container Registry。
启用和配置系统服务以及构建Docker容器需要root权限。 因此,以下部分需要在客户端VM上以root用户身份运行。
vi /etc/containers/registries.conf
在您的主目录中,创建一个jenkins-slave-appdev子目录并将其更改为:
在jenkins-slave-appdev目录中,创建一个Dockerfile。
使用docker.io/openshift/jenkins-slave-maven-centos7:v3.9作为基本映像。
教室集群没有正确的订阅,因此您无法基于RHEL构建任何图像 - 但您可以使用上游的CentOS映像。
此基本映像使用1001用户作为用户来运行从属pod。
您需要以root用户身份安装skopeo。 确保在构建过程中执行任何操作之前切换到root用户,并在完成后切换回1001。
安装skopeo。
构建容器。
构建容器时,请确保使用指向Docker注册表的路径和Jenkins项目的名称对其进行标记。
由于您正在将容器推入OpenShift Container Registry,因此您需要选择一个您获得授权的项目 - 最容易选择的是Jenkins项目。
您还需要在标记中使用当前版本号。
容器名称必须类似于jenkins-slave-maven-appdev。
当然,您可以使用任何其他名称 - 只需确保您在整个实验室中保持一致。
docker build . -t docker-registry-default.apps.0845.openshift.opentlc.com/xyz-jenkins80/jenkins-slave-maven-appdev:v3.9
自定义Slave Pod发布到OpenShift Container Registry
如何处理此步骤有两种选择。
使用Docker命令使用OpenShift用户ID和相关令牌作为密码登录OpenShift Container Registry,然后按下标记的图像。
docker push docker-registry-default.apps.0845.openshift.opentlc.com/xyz-jenkins80/jenkins-slave-maven-appdev:v3.9
当您在OpenShift容器注册表中提供自定义的Maven slave pod时,需要告诉Jenkins在何处找到它以及何时使用它。
您可以使用现有的Maven从属图像作为模板,并从现有图像复制大多数字段。
在Jenkins中选择Manage Jenkins,然后单击Configure System,最后向下滚动到Cloud部分。 单击Add Pod Template并选择Kubernetes Pod Template将另一个pod模板添加到Jenkins。
确保如下配置
单击屏幕底部的“保存”。
测试自定义Slave Pod
使用简单的pipeline,我们可以测试slave pod是否正常工作并安装了skopeo。
创建一个类型为Pipeline的新Jenkins job并使用此测试pileline:
确保请求的标签与slave pod定义标记的标签相匹配。
控制台输出如下所示(单击Build Number,然后单击Console Output):
可以看到slave pod启动:
八、实验展示:本地构建
为了验证所有构建工具是否都已正确设置,最好使用OpenShift安装中的Nexus和SonarQube从客户端运行测试。
首先,您可以构建openshift-tasks应用程序:
确保仔细检查构建的输出,以验证您的Maven依赖项来自Nexus而不是公共Internet存储库。
运行单元测试:确保仔细检查构建的输出,以验证您的Maven依赖项来自Nexus而不是公共Internet存储库。
运行Maven部署测试
mvn -s ./nexus_settings.xml deploy -DskipTests=true \
-DaltDeploymentRepository=nexus::default::http://$(oc get route nexus3 -n xyz-nexus80 --template='{{ .spec.host }}')/repository/releases
运行Nexus Docker注册表测试
skopeo copy --dest-tls-verify=false --dest-creds=admin:admin123 docker-daemon:docker-registry-default.apps.0845.openshift.opentlc.com/xyz-jenkins80/jenkins-slave-maven-appdev:v3.9 docker://$(oc get route nexus-registry -n xyz-nexus80 --template='{{ .spec.host }}')/xyz-jenkins80/jenkins-slave-maven-appdev:v3.9
通过浏览器查看:
运行代码分析测试
mvn sonar:sonar -s ./nexus_settings.xml -Dsonar.host.url=http://$(oc get route sonarqube -n xyz-sonarqube80 --template='{{ .spec.host }}')
登录浏览器进行查看: