内容
活动
关注

基于Docker容器的,Jenkins、GitLab构建持续集成CI

简介: 一、场景: 开发者将代码提交(push)到GitLab后,GitLab通过Hook通知jenkins,jenkins自动从GitLab中获取项目最新的源码进行集成和发布。 二、准备: 基于Docker,创建一个私有GitLab的容器,创建一个jenkins的容器 三、步骤 1、构建Jenkins容器 Jenkins容器安装Jenkins的rpm包,Jenkins依赖 JDK,所以需要在Jenkins的容器中安装配置jdk,本人使用jdk1.8,同时需要Jenkins的容器调用maven的打包命令,所以也需要配置安装maven,本人使用maven 3.3.9。

** 开发者将代码提交(push)到GitLab后,GitLab通过Hook通知jenkins,jenkins自动从GitLab中获取项目最新的源码进行集成和发布。

基于Docker,创建一个私有GitLab的容器,创建一个jenkins的容器** 

1. 构建私有的GitLab容器

https://about.gitlab.com/installation/#centos-7,直接安装gitlab,不借助docker

通过docker-compose的方式安装gitlab,docker-compose这个命令需要单独安装,docker-compose会对指定目录下的docker-compose.yml文件进行执行,这个文件会一次性启动所编辑的镜像,及所要用到的参数,官方提供的yml文件内容如下:

#Install docker-compose sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version 
version: '2' services: redis: restart: always image: sameersbn/redis:latest command: - --loglevel warning volumes: - /srv/docker/gitlab/redis:/var/lib/redis:Z #文件的挂载点 postgresql: restart: always image: sameersbn/postgresql:9.6-2 volumes: - /srv/docker/gitlab/postgresql:/var/lib/postgresql:Z #文件的挂载点 environment: - DB_USER=gitlab - DB_PASS=password - DB_NAME=gitlabhq_production - DB_EXTENSION=pg_trgm gitlab: restart: always image: sameersbn/gitlab:9.1.4 depends_on: - redis - postgresql ports: - "10080:80" - "10022:22" volumes: - /srv/docker/gitlab/gitlab:/home/git/data:Z #文件的挂载点 environment: - DEBUG=false - DB_ADAPTER=postgresql - DB_HOST=postgresql - DB_PORT=5432 - DB_USER=gitlab - DB_PASS=password - DB_NAME=gitlabhq_production - REDIS_HOST=redis - REDIS_PORT=6379 - TZ=Asia/Kolkata - GITLAB_TIMEZONE=Kolkata - GITLAB_HTTPS=false - SSL_SELF_SIGNED=false - GITLAB_HOST=localhost - GITLAB_PORT=10080 - GITLAB_SSH_PORT=10022 - GITLAB_RELATIVE_URL_ROOT= - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_ROOT_PASSWORD= - GITLAB_ROOT_EMAIL= - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true - GITLAB_NOTIFY_PUSHER=false - GITLAB_EMAIL=notifications@example.com - GITLAB_EMAIL_REPLY_TO=noreply@example.com - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com - GITLAB_BACKUP_SCHEDULE=daily - GITLAB_BACKUP_TIME=01:00 - SMTP_ENABLED=false - SMTP_DOMAIN=www.example.com - SMTP_HOST=smtp.gmail.com - SMTP_PORT=587 - SMTP_USER=mailer@example.com - SMTP_PASS=password - SMTP_STARTTLS=true - SMTP_AUTHENTICATION=login - IMAP_ENABLED=false - IMAP_HOST=imap.gmail.com - IMAP_PORT=993 - IMAP_USER=mailer@example.com - IMAP_PASS=password - IMAP_SSL=true - IMAP_STARTTLS=false - OAUTH_ENABLED=false - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER= - OAUTH_ALLOW_SSO= - OAUTH_BLOCK_AUTO_CREATED_USERS=true - OAUTH_AUTO_LINK_LDAP_USER=false - OAUTH_AUTO_LINK_SAML_USER=false - OAUTH_EXTERNAL_PROVIDERS= - OAUTH_CAS3_LABEL=cas3 - OAUTH_CAS3_SERVER= - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false - OAUTH_CAS3_LOGIN_URL=/cas/login - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate - OAUTH_CAS3_LOGOUT_URL=/cas/logout - OAUTH_GOOGLE_API_KEY= - OAUTH_GOOGLE_APP_SECRET= - OAUTH_GOOGLE_RESTRICT_DOMAIN= - OAUTH_FACEBOOK_API_KEY= - OAUTH_FACEBOOK_APP_SECRET= - OAUTH_TWITTER_API_KEY= - OAUTH_TWITTER_APP_SECRET= - OAUTH_GITHUB_API_KEY= - OAUTH_GITHUB_APP_SECRET= - OAUTH_GITHUB_URL= - OAUTH_GITHUB_VERIFY_SSL= - OAUTH_GITLAB_API_KEY= - OAUTH_GITLAB_APP_SECRET= - OAUTH_BITBUCKET_API_KEY= - OAUTH_BITBUCKET_APP_SECRET= - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL= - OAUTH_SAML_IDP_CERT_FINGERPRINT= - OAUTH_SAML_IDP_SSO_TARGET_URL= - OAUTH_SAML_ISSUER= - OAUTH_SAML_LABEL="Our SAML Provider" - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient - OAUTH_SAML_GROUPS_ATTRIBUTE= - OAUTH_SAML_EXTERNAL_GROUPS= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME= - OAUTH_CROWD_SERVER_URL= - OAUTH_CROWD_APP_NAME= - OAUTH_CROWD_APP_PASSWORD= - OAUTH_AUTH0_CLIENT_ID= - OAUTH_AUTH0_CLIENT_SECRET= - OAUTH_AUTH0_DOMAIN= - OAUTH_AZURE_API_KEY= - OAUTH_AZURE_API_SECRET= - OAUTH_AZURE_TENANT_ID=

在docker-compose.yml文件所在目录下,执行docker-compose up命令(docker-compose命令需要安装),如果之前没有下载过GitLab的镜像会自动下载,如果下载过就直接启动已有的容器。

这里会在docker创建一个新的网桥,gitlab所需要的gitlab容器和redis容器及postgresql容器都在这个网桥指定的网段内,可以通过docker network ls查看.

网桥的名称通常为你yml文件所在目录名称的小写加上下划线default,例如mygitlab_default。这个很有用,因为如果你想要容器内部互联,就需要指定所要连接的容器在一个网段内,例如jenkins容器如果想内部连接gitlab容器,就得都在mygitlab_default这个网桥提供的网段内,Docker默认会为容器指定在docker0这个网段内的一个ip,通常会是172.17.. 我的gitlab默认在172.18,所以需要在接下来创建jenkins容器并启动时,指定到18这个网段内,当然你想通过宿主机的ip和端口也是可以的

执行完成之后,gitlab容器的80端口绑定在了宿主机的10080端口,同时gitlab容器的22端口(ssh)绑定在宿主机10022端口。可以通过访问localhost:10080来访问私有仓库

2. 构建Jenkins容器

Jenkins容器安装Jenkins的rpm包,Jenkins依赖 JDK,所以需要在Jenkins的容器中安装配置jdk,本人使用jdk1.8,同时需要Jenkins的容器调用maven的打包命令,所以也需要配置安装maven,本人使用maven 3.3.9。

a.通过Dockerfile构建一个jenkins容器,基于centos7的镜像。

 这里不推荐将一个基础镜像一次性打包成完整的应用镜像,建议构建三层镜像模型。 所谓三层镜像就是,基础镜像,中间件镜像,应用镜像。例如我要构建一个Jenkins 的镜像,打包一个基于Centos7 和一些常用工具的镜像就是基础镜像,例如叫Centos7-base。然后这里Jenkins依赖Java和Maven,所以在基于Centos7-base的基础上安装配置java及maven后,再打包的镜像为中间件镜像,例如叫Centos7-jdk8-mvn3,这层中间件的镜像我们为来的复用会很高,以后只要有基于java1.8和maven3的,就可以直接使用这个镜像进行构建。最后我们再在Centos7-jdk8-mvn3的基础上安装配置jenkins,最后打包运用在生产环境。 

b.构建基础镜像,整合jdk及mvn。配置PATH ,安装所需要的工具,Dockerfile如下:

#base on centos 7 image FROM daocloud.io/centos:7 MAINTAINER hoewon LABEL JDK \ 1.8 COPY jdk1.8 /usr/local/jdk1.8/ \ maven /usr/local/maven/ RUN yum install -y openssh-server openssh-clients git RUN yum install -y iproute net-tools ENV JAVA_HOME /usr/local/jdk1.8 ENV PATH $JAVA_HOME/bin:$PATH EXPOSE 8080 ENTRYPOINT /bin/bash
将要复制进镜像里的jdk和maven文件放到与Dockerfile相同的目录下 

执行命令打包镜像

#最后 . 是当前目录的意思,不可省略,或自定义Dockerfile所在目录 docker build -t repo/name:tag . #成功后查看本地镜像 docker images 

c.通过基础镜像安装jenkins,也是通过Dockerfile

#A jenkins 2.7.4 on centos 7 image #基于刚才做好的基础镜像 FROM 127.0.0.1:5000/env/centos7-jdk8-mvn:1.3 MAINTAINER hoewon LABEL JDK1.8 \ Jenkins-2.7.4 #复制jenkins rpm至镜像 COPY jenkins.rpm /usr/local/ #创建jenkins用户,并更改密码 RUN useradd jenkins && echo "jenkins password" > passwd jenkins --stdin #安装jenkins RUN rpm -ivh /usr/local/jenkins.rpm #更改jenkins安装文件的所有者 RUN rpm -ql jenkins | xargs chown -R jenkins:jenkins #创建jenkins日志文件 RUN touch /usr/lib/jenkins/jenkins-logs #更改日志文件所有者 RUN chown jenkins:jenkins /usr/lib/jenkins/jenkins-logs #曝光8080端口 EXPOSE 8080 #启动容器时使用jenkins用户 USER jenkins #定义用户空间为工作空间 WORKDIR /home/jenkins #启动容器时启动jenkins ENTRYPOINT java -jar /usr/lib/jenkins/jenkins.war &> /usr/lib/jenkins/jenkins-logs

d.运行jenkins容器,这里需要将container的网络设置跟GtiLab同网络的环境下,同时我们希望jenkins容器在用maven打包之后,在调用docker惊醒封装镜像,然后推送镜像至私有的镜像仓库,所以我们把宿主机的/usr/bin/docker 和/run/docker.sock 和所依赖的共享库文件,在启动容器时一并挂载至容器内部。

# --net 指定docker的网桥 docker run -idt --net mygitlab_default --name jenkins_c -p 8888:8080 -v /usr/lib64/libltdl.so.7:/usr/lib64/libltdl.so.7 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker 127.0.0.1:5000/myjenkins:1.0 /bin/bash

e.容器启动后,8080端口被绑定到了宿主机的8888端口,访问localhost:8888来访问jenkins
首次登录jenkins会需要输入jenkins的超级管理员密码,这个密码在jenkins第一次启动的日志中,可以进入jenkins容器,查看运行日志,也可以根据页面提示,直接去jenkins的家目录下一个.jenkins/secrets/init…..的文件内查看密码。登录后注册一个用户,并在系统管理-管理插件下,安装GitLab的插件。第一次运行jenkins会让你选择安装插件,选择第一个推荐的安装后,在管理插件的可选插件tab下搜索Gitlab Plugin 和Gitlab Hook Plugin插件进行安装,然后重启jenkins

3.构建私有的Docker 镜像仓库
拉取一个docker 的镜像仓库镜像,并运行该容器,容器运行后会绑定宿主机5000端口,我个人用的是daocloud.io提供的镜像,这个镜像仓库需要注册。

docker run \ -e SETTINGS_FLAVOR=s3 \ -e AWS_BUCKET=acme-docker \ -e STORAGE_PATH=/registry \ -e AWS_KEY=AKIAHSHB43HS3J92MXZ \ -e AWS_SECRET=xdDowwlK7TJajV1Y7EoOZrmuPEJlHYcNP2k4j49T \ -e SEARCH_BACKEND=sqlalchemy \ -p 5000:5000 \ daocloud.io/registry

运行成功后,可以访问http://localhost:5000/v2/_catalog 来查看本地仓库信息

4.构建持续集成环境
万事具备,下面我们开始利用gitlab,jenkins,来构建持续集成环境。

a.在gitlab中创建一个项目,项目类为public,创建后会有如下提示,这些提示用来告诉你如何通过客户端下载项目,并提交项目

#Command line instructions #Git global setup git config --global user.name "jenkins" git config --global user.email "15561581025@163.com" #Create a new repository git clone ssh://git@localhost:10022/jenkins/demo.git cd demo touch README.md git add README.md git commit -m "add README" git push -u origin master #Existing folder cd existing_folder git init git remote add origin ssh://git@localhost:10022/jenkins/demo.git git add . git commit git push -u origin master #Existing Git repository cd existing_repo git remote add origin ssh://git@localhost:10022/jenkins/demo.git git push -u origin --all git push -u origin --tags

b.进入jenkins容器,然后通过git客户端,拉取项目。在拉取之前,需要用使用ssh-keygen来生成当前jenkins用户在jenkins容器的公钥密钥,ssh-keygen需要安装openssh。

ssh-keygen – t rsa

可以一路回车,默认生成在jenkins用户的家目录下的一个.ssh的文件夹,将.ssh/id_rsa.pub的内容全部复制

c.登录gitlab,右上角下拉列表下选择setting,然后在主页面有一个SSH Keys的tab页,将你刚才复制的公钥内容添加至Key这个文本框,然后点击Add key。这个步骤的意思是,如果你想让jenkins通过ssh协议从gitlab拉取项目,需要认证,配置的公钥就是允许jenkins容器的jenkins用户所运行的jenkins从gitlab通过ssh协议拉取项目(有点别扭,但是需要注意的是jenkins这个容器主机和jenkins用户,jenkins程序是jenkins用户启动的)。
(这里有一个没有解决的问题,就是关于拉取private类型的项目,需要做的ssh认证,需要公钥密钥匹配,但是没有实现,所以暂时项目都是public。如果public的项目的话,可以通过http协议进行拉取,但是需不需要配置ssh的公钥,我也没试过,因该是不需要把。)

在配置好key之后,我们回到jenkins容器,当前用户为jenkins。我们想通过git客户端拉取项目的第二个准备工作,需要配置git的全局配置。

git config --global user.name=”yourName”

我的gitlab 和jenkins的用户都是jenkins,这里应该填写的是git用户名

git config –global user.email=”your email”

这两个配置完成后,我们可以就可以拉取项目到本地了,以我自己demo为例

git clone ssh://git@localhost:10022/jenkins/eurka.git

d.现在拉取到当前目录的eurka是个空项目,我们把我们要上传的项目源码和Dockerfile(用来jenkins调用docker打包镜像用的)添加至这个目录,然后git add ,git commit ,git push 命令将本地文件添加提交并推送整合至gitlab这个项目的某个分支下,默认是master

e.提交完成后,我们开始配置jenkins,以jenkins用户登录jenkins,新建,选择 --构建一个自由风格的软件项目然后确定

f.然后进入到这个项目的配置下,在源码管理选择Git,然后在Repository URL下,填入项目的ssh地址,注意这里不可一世用localhost,你可以填写主机的ip加上10022端口,也可以配置gitlab容器的ip地址加上22端口,我这里配置的是我的容器地址,例如ssh://git@172.18.0.4:22/jenkins/eurka.git,这里不要写10022端口!!!!因为是public项目,所以不需要添加认证
g.在构建触发器下,选择Build wher a chage is pushed to GitLab……….将后面的地址复制,然后在gitlab这个项目的Setting下的Integrations下,勾选Push Event,找到Add webhook,并填写刚才复制的路径,我这里写的依然是容器ip,http://172.18.0.5:8080/project/eurka,没有使用localhost:8888这个url,保存

h.回到jenkins的设置,在构建中下Execute shell下,编写shell脚本,这里就是gitlab被push后,通过webhook的方式让jenkins自动从gitlab下拉取项目之后,要执行的代码
默认拉取之后,会在这个项目的路径下,如果不确定自己当前的工作目录,可以通过echo $WORKDIR来查看当前位置,例如我的项目叫eurka,这个项目下我上传了一个maven项目,所以我如果想要对这个maven项目打包,我得进入这个项目目录,然后对这个项目下的pom文件进行操作,贴出我的shell:

#先打印当前位置 pwd #进入到我的maven项目 cd spring-cloud-02-service #maven打包 mvn clean compile package -Dmaven.test.skip=true #回到上一级,因为上一级有Dockerfile文件 cd ../ #这里我先移除掉了我之前的镜像,然后再重新构建一个镜像,如果当前有#这个镜像运行的容器,需要先停止容器,移除容器,最后移除镜像 docker rmi 127.0.0.1:5000/auto/eurka:1.0 . || docker build -t 127.0.0.1:5000/auto/eurka:1.0 . #将打包的镜像推送到本地的docker仓库 docker push 127.0.0.1:5000/auto/eurka:1.0 #查看本地是否打包成功 docker images #最后可以执行docker run -itd –name container_name -p xxxx:xxxx repo/im#g:tag /bin/bash让jenkins调用宿主机的docker,运行刚才打包好的镜像,不#出意外,应该在我们指定的端口上可以访问这个项目了。

最初我们在run jenkins容器的时候,将宿主机的docker文件挂载进了容器内部,这个操作很重要,但我也很迷糊,但可以肯定的是,jenkins容器所运行的docker及操作是针对宿主机的docker的

后续的持续集成,要基于kubernetes,kubernetes会自动的找其节点自动拉取刚push的镜像,并自动部署。未完待续

相关实践学习
通过ACR快速部署网站应用
本次实验任务是在云上基于ECS部署Docker环境,制作网站镜像并上传至ACR镜像仓库,通过容器镜像运行网站应用,网站运行在Docker容器中、网站业务数据存储在Mariadb数据库中、网站文件数据存储在服务器ECS云盘中,通过公网地址进行访问。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
9月前
|
人工智能 Kubernetes jenkins
容器化AI模型的持续集成与持续交付(CI/CD):自动化模型更新与部署
在前几篇文章中,我们探讨了容器化AI模型的部署、监控、弹性伸缩及安全防护。为加速模型迭代以适应新数据和业务需求,需实现容器化AI模型的持续集成与持续交付(CI/CD)。CI/CD通过自动化构建、测试和部署流程,提高模型更新速度和质量,降低部署风险,增强团队协作。使用Jenkins和Kubernetes可构建高效CI/CD流水线,自动化模型开发和部署,确保环境一致性并提升整体效率。
|
4月前
|
Cloud Native 中间件 调度
云原生信息提取系统:容器化流程与CI/CD集成实践
本文介绍如何通过工程化手段解决数据提取任务中的稳定性与部署难题。结合 Scrapy、Docker、代理中间件与 CI/CD 工具,构建可自动运行、持续迭代的云原生信息提取系统,实现结构化数据采集与标准化交付。
154 1
云原生信息提取系统:容器化流程与CI/CD集成实践
|
7月前
|
jenkins Java Linux
Jenkins环境的部署及任务构建
以上就是Jenkins环境的部署及任务构建的全部内容。希望可以帮助你轻松上手Jenkins,让你的CI/CD之旅更加顺畅!
476 68
|
6月前
|
jenkins 持续交付 开发工具
利用Dockerfile自主构建Jenkins镜像
希望这个过程能善用你的野马般想象,把自己置身于和计算机的卓尔不凡的对话中,让编程的过程充满趣味。
220 36
|
5月前
|
Ubuntu jenkins 机器人
在Jenkins上配置触发Ubuntu环境的图形用户界面(GUI)构建任务。
以上,这趟融合了技术与艺术的Jenkins配置之旅就告一段落了。记住,技术应当像艺术一样有趣和生动,这样才能激发出最大的创新和效率。
145 2
|
8月前
|
安全 持续交付 云计算
课时5:阿里云容器服务:最原生的集成Docker和云服务
阿里云容器服务以服务化形式构建容器基础设施,大幅提升开发效率,简化应用部署流程。通过Docker容器和DevOps工具(如Jenkins),实现自动化部署与迭代,优化企业内部复杂部署问题。该服务支持GPU调度、混合云架构无缝迁移,并与阿里云产品体系无缝集成,提供安全防护、网络负载均衡等多重功能支持。凭借微服务架构,帮助企业突破业务瓶颈,提高资源利用率,轻松应对海量流量。
278 0
课时5:阿里云容器服务:最原生的集成Docker和云服务
|
4月前
|
存储 安全 Linux
Linux服务器上安装配置GitLab的步骤。
按照以上步骤,一个基础的GitLab服务应该运行并可以使用。记得定期检查GitLab官方文档,因为GitLab的安装和配置步骤可能随着新版本而变化。
342 0
|
Shell Docker 容器
GitlabCI学习笔记之一:安装Gitlab和GitLabRunner
GitlabCI学习笔记之一:安装Gitlab和GitLabRunner
|
Devops 持续交付 开发工具
入职必会-开发环境搭建54-GitLab下载和安装
GitLab 是一个基于 web 的 Git 仓库管理工具,提供了代码托管、版本控制、协作开发、持续集成等功能,是一个综合的 DevOps 平台。用户可以使用 GitLab 托管他们的代码仓库,并利用其丰富的功能来管理和协作开发项目。 以下是 GitLab 的一些主要特点和功能。
287 0
入职必会-开发环境搭建54-GitLab下载和安装
|
Docker 容器
Docker安装Gitlab和Gitlab-Runner并实现项目CICD
Docker安装Gitlab和Gitlab-Runner并实现项目CICD

推荐镜像

查看更多
下一篇