CICD Jenkins与Docker容器,Kubernetes和Gitlab

时间:2019-10-07 11:37:01

标签: docker jenkins kubernetes gitlab devops

我有一个工作流,其中

1)团队A和团队B将应用中的更改推送到服务器A上的私有gitlab(在docker容器中运行)。 2)他们的应用程序应包含Dockerfile或docker-compose.yml 3)Gitlab应该触发jenkins构建(jenkins在服务器A上的docker容器中运行)并执行诸如test之类的常规构建操作 4)Jenkins应该构建一个新的docker映像并将其部署。

问题: 如果团队A需要像maven和npm这样的程序包来做Web应用程序,但是团队B需要像c ++这样的其他程序包,我该如何解决这个问题?

因为我认为让我的jenkins容器拥有所有这些软件包(mvn,npm,yarn,c ++等)然后执行jenkins构建是不正确的。

我当时以为A队应该得到一个装有需要安装软件包的容器。对于B队也是如此。

我想利用Docker,Kubernetes,Jenkins和Gitlab。 (尽可能多的容器技术)

请为我的工作流程提供建议。谢谢

2 个答案:

答案 0 :(得分:1)

我想分享一个与开发人员的观点不同的观点,这种观点与“以操作为中心”的问题有关。

对于开发人员来说,Jenkins还是可以触发应用程序构建的工具。是的,当然,构建的工件也可以是docker映像,但这并不是开发人员真正关心的。您已将其称为“测试之类的常规构建”,但是开发人员围绕此“常规构建”拥有整个生态系统。

例如,您提到的mvn具有出色的依赖性解析功能。它可以单独解决依赖关系。大致相同的假设适用于其他构建工具。在这个答案中,我会坚持使用maven。

因此,您不需要自己维护依赖项,但作为Jenkins维护者,您应该具备实际构建产品的技术能力(正在运行maven的产品将依次解析/下载所有依赖项,然后运行测试,产生测试结果,甚至可以创建docker映像,或者甚至可以将映像部署到某些映像存储库中;))。

因此,使用某些构建技术的开发人员可以维护自己的脚本(对于maven来说是声明性的,对于C ++而言是make的文件)应该能够运行自己的工具。

现在,此图片与容器化并不矛盾:

jenkins映像实际上可以包含maven / make / npm少数几个用于运行构建的工具。实际的脚本可以成为应用程序源代码库的一部分(由git维护)。

因此,当Jenkins收到有关构建的通知时-应该检出源代码,运行一些脚本(例如mvn package),显示测试结果,然后作为一个单独的步骤或从maven创建一个图像。您的应用程序,并根据您的实际devops需求将其上传到某个存储库或提供给kubernetes集群。

请注意,在mvn package期间,maven会将所有依赖项(第3方软件包)下载到jenkins工作区中,使用Java编译器编译您显然还需要在Jenkins机器上使用的所有内容。

答案 1 :(得分:0)

哇,这是一个很大的挑战,有很多方法可以解决这一挑战。 您可以采用以下两种方法:

使用不同类型的詹金斯奴隶来解决

从长远来看,您应该考虑在奴隶上运行Jenkins工作负载。 这不仅是您的用例所希望的,而且在更高的工作负载上可以更好地扩展。 因为在最坏的情况下,更密集的工作负载可能会杀死您的Jenkins主服务器。 请参阅https://wiki.jenkins.io/display/JENKINS/Distributed+builds以供参考。 在Jenkins中定义从站时(例如使用用于AWS集成的ec2插件),您可以针对不同的工作负载使用不同的从站。这意味着您需要为每个特定目的准备一个从属设备(或从属映像,在AWS中为AMI)。一种用于Java,一种用于节点,您可以为其命名。

然后,通过检查Restrict where this project can be run并输入您的从属标签,可以在您的作业中使用这些已定义的从属。

enter image description here

通过在Docker环境中完成所有操作来解决该问题

在您的情况下,最简单的解决方案是仅使用Docker基础结构来构建任何类型的Docker映像,然后将其推送到私有Docker Registry(所有大型云提供商都提供此类Container Registry服务),然后从以下位置下载部署时间。这样可以避免您每次更改新技术堆栈时的麻烦。

我真的不知道您对Docker或其他容器化技术有多熟悉,所以我为您简要介绍解决方案。

  1. 以所需的基础映像为起点创建一个Dockerfile。只是谷歌他们或寻找他们在Dockerhub。这是nodeJS的示例:
MAINTAINER devops@yourcompany.biz

ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install --silent

#i recommend using a .dockerignore file to not copy unnecessary stuff in your image
COPY . .

CMD [ "npm", "start"]
  1. 调整图像并为您的CI / CD管道创建一个Jenkinsfile。在那里,您应该像这样构建并推送docker映像:
stage('build docker image') {
            ...
            steps {
                script {
                    docker.build('your/registry/your-image', '--build-arg NODE_ENV=production .')
                    docker.withRegistry('https://yourregistryurl.com', 'credentials token to access registry') {
                        docker.image('your/registry/your-image').push(env.BRANCH_NAME + '-latest')
                    }
                }
            }
        }
  1. 通过在部署脚本中下载并运行先前部署的映像来进行部署(在我的情况下是通过Ansible完成的)。

如果您尝试更详细地定义问题,则会得到更好的答案。